Salome HOME
DataArrayDouble::getIdsNotInRange, DataArrayInt::getIdsNotInRange
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::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 char *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]).c_str());
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).c_str());
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 char *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  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
427  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
428  * the number of component in the result array is same as that of each of given arrays.
429  * Info on components is copied from the first of the given arrays. Number of components
430  * in the given arrays must be  the same.
431  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
432  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
433  *          The caller is to delete this result array using decrRef() as it is no more
434  *          needed.
435  *  \throw If all arrays within \a arrs are NULL.
436  *  \throw If all not null arrays in \a arrs have not the same type.
437  *  \throw If getNumberOfComponents() of arrays within \a arrs.
438  */
439 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
440 {
441   std::vector<const DataArray *> arr2;
442   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
443     if(*it)
444       arr2.push_back(*it);
445   if(arr2.empty())
446     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
447   std::vector<const DataArrayDouble *> arrd;
448   std::vector<const DataArrayInt *> arri;
449   std::vector<const DataArrayChar *> arrc;
450   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
451     {
452       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
453       if(a)
454         { arrd.push_back(a); continue; }
455       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
456       if(b)
457         { arri.push_back(b); continue; }
458       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
459       if(c)
460         { arrc.push_back(c); continue; }
461       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
462     }
463   if(arr2.size()==arrd.size())
464     return DataArrayDouble::Aggregate(arrd);
465   if(arr2.size()==arri.size())
466     return DataArrayInt::Aggregate(arri);
467   if(arr2.size()==arrc.size())
468     return DataArrayChar::Aggregate(arrc);
469   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
470 }
471
472 /*!
473  * Sets information on a component specified by an index.
474  * To know more on format of this information
475  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
476  *  \warning Don't pass NULL as \a info!
477  *  \param [in] i - the index (zero based) of the component of interest.
478  *  \param [in] info - the string containing the information.
479  *  \throw If \a i is not a valid component index.
480  */
481 void DataArray::setInfoOnComponent(int i, const char *info)
482 {
483   if(i<(int)_info_on_compo.size() && i>=0)
484     _info_on_compo[i]=info;
485   else
486     {
487       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();
488       throw INTERP_KERNEL::Exception(oss.str().c_str());
489     }
490 }
491
492 /*!
493  * Sets information on all components. This method can change number of components
494  * at certain conditions; if the conditions are not respected, an exception is thrown.
495  * The number of components can be changed in \a this only if \a this is not allocated.
496  * The condition of number of components must not be changed.
497  *
498  * To know more on format of the component information see
499  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
500  *  \param [in] info - a vector of component infos.
501  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
502  */
503 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
504 {
505   if(getNumberOfComponents()!=(int)info.size())
506     {
507       if(!isAllocated())
508         _info_on_compo=info;
509       else
510         {
511           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 !";
512           throw INTERP_KERNEL::Exception(oss.str().c_str());
513         }
514     }
515   else
516     _info_on_compo=info;
517 }
518
519 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const
520 {
521   if(getNumberOfTuples()!=nbOfTuples)
522     {
523       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
524       throw INTERP_KERNEL::Exception(oss.str().c_str());
525     }
526 }
527
528 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const
529 {
530   if(getNumberOfComponents()!=nbOfCompo)
531     {
532       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
533       throw INTERP_KERNEL::Exception(oss.str().c_str());
534     }
535 }
536
537 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const
538 {
539   if(getNbOfElems()!=nbOfElems)
540     {
541       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
542       throw INTERP_KERNEL::Exception(oss.str().c_str());
543     }
544 }
545
546 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const
547 {
548    if(getNumberOfTuples()!=other.getNumberOfTuples())
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553   if(getNumberOfComponents()!=other.getNumberOfComponents())
554     {
555       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
556       throw INTERP_KERNEL::Exception(oss.str().c_str());
557     }
558 }
559
560 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const
561 {
562   checkNbOfTuples(nbOfTuples,msg);
563   checkNbOfComps(nbOfCompo,msg);
564 }
565
566 /*!
567  * Simply this method checks that \b value is in [0,\b ref).
568  */
569 void DataArray::CheckValueInRange(int ref, int value, const char *msg)
570 {
571   if(value<0 || value>=ref)
572     {
573       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
574       throw INTERP_KERNEL::Exception(oss.str().c_str());
575     }
576 }
577
578 /*!
579  * This method checks that [\b start, \b end) is compliant with ref length \b value.
580  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
581  */
582 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg)
583 {
584   if(start<0 || start>=value)
585     {
586       if(value!=start || end!=start)
587         {
588           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
589           throw INTERP_KERNEL::Exception(oss.str().c_str());
590         }
591     }
592   if(end<0 || end>value)
593     {
594       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
595       throw INTERP_KERNEL::Exception(oss.str().c_str());
596     }
597 }
598
599 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg)
600 {
601   if(value<0 || value>ref)
602     {
603       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
604       throw INTERP_KERNEL::Exception(oss.str().c_str());
605     }
606 }
607
608 /*!
609  * 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, 
610  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
611  *
612  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
613  *
614  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
615  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
616  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
617  * \param [in] sliceId - the slice id considered
618  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
619  * \param [out] startSlice - the start of the slice considered
620  * \param [out] stopSlice - the stop of the slice consided
621  * 
622  * \throw If \a step == 0
623  * \throw If \a nbOfSlices not > 0
624  * \throw If \a sliceId not in [0,nbOfSlices)
625  */
626 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
627 {
628   if(nbOfSlices<=0)
629     {
630       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633   if(sliceId<0 || sliceId>=nbOfSlices)
634     {
635       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
636       throw INTERP_KERNEL::Exception(oss.str().c_str());
637     }
638   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
639   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
640   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
641   if(sliceId<nbOfSlices-1)
642     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
643   else
644     stopSlice=stop;
645 }
646
647 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg)
648 {
649   if(end<begin)
650     {
651       std::ostringstream oss; oss << msg << " : end before begin !";
652       throw INTERP_KERNEL::Exception(oss.str().c_str());
653     }
654   if(end==begin)
655     return 0;
656   if(step<=0)
657     {
658       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
659       throw INTERP_KERNEL::Exception(oss.str().c_str());
660     }
661   return (end-1-begin)/step+1;
662 }
663
664 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg)
665 {
666   if(step==0)
667     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
668   if(end<begin && step>0)
669     {
670       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   if(begin<end && step<0)
674     {
675       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
676       throw INTERP_KERNEL::Exception(oss.str().c_str());
677     }
678   if(begin!=end)
679     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
680   else
681     return 0;
682 }
683
684 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
685 {
686   if(step!=0)
687     {
688       if(step>0)
689         {
690           if(begin<=value && value<end)
691             {
692               if((value-begin)%step==0)
693                 return (value-begin)/step;
694               else
695                 return -1;
696             }
697           else
698             return -1;
699         }
700       else
701         {
702           if(begin>=value && value>end)
703             {
704               if((begin-value)%(-step)==0)
705                 return (begin-value)/(-step);
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712     }
713   else
714     return -1;
715 }
716
717 /*!
718  * Returns a new instance of DataArrayDouble. The caller is to delete this array
719  * using decrRef() as it is no more needed. 
720  */
721 DataArrayDouble *DataArrayDouble::New()
722 {
723   return new DataArrayDouble;
724 }
725
726 /*!
727  * Checks if raw data is allocated. Read more on the raw data
728  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
729  *  \return bool - \a true if the raw data is allocated, \a false else.
730  */
731 bool DataArrayDouble::isAllocated() const
732 {
733   return getConstPointer()!=0;
734 }
735
736 /*!
737  * Checks if raw data is allocated and throws an exception if it is not the case.
738  *  \throw If the raw data is not allocated.
739  */
740 void DataArrayDouble::checkAllocated() const
741 {
742   if(!isAllocated())
743     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
744 }
745
746 /*!
747  * This method desallocated \a this without modification of informations relative to the components.
748  * After call of this method, DataArrayDouble::isAllocated will return false.
749  * If \a this is already not allocated, \a this is let unchanged.
750  */
751 void DataArrayDouble::desallocate()
752 {
753   _mem.destroy();
754 }
755
756 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
757 {
758   std::size_t sz(_mem.getNbOfElemAllocated());
759   sz*=sizeof(double);
760   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
761 }
762
763 /*!
764  * Returns the only one value in \a this, if and only if number of elements
765  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
766  *  \return double - the sole value stored in \a this array.
767  *  \throw If at least one of conditions stated above is not fulfilled.
768  */
769 double DataArrayDouble::doubleValue() const
770 {
771   if(isAllocated())
772     {
773       if(getNbOfElems()==1)
774         {
775           return *getConstPointer();
776         }
777       else
778         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
779     }
780   else
781     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
782 }
783
784 /*!
785  * Checks the number of tuples.
786  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
787  *  \throw If \a this is not allocated.
788  */
789 bool DataArrayDouble::empty() const
790 {
791   checkAllocated();
792   return getNumberOfTuples()==0;
793 }
794
795 /*!
796  * Returns a full copy of \a this. For more info on copying data arrays see
797  * \ref MEDCouplingArrayBasicsCopyDeep.
798  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
799  *          delete this array using decrRef() as it is no more needed. 
800  */
801 DataArrayDouble *DataArrayDouble::deepCpy() const
802 {
803   return new DataArrayDouble(*this);
804 }
805
806 /*!
807  * Returns either a \a deep or \a shallow copy of this array. For more info see
808  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
809  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
810  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
811  *          == \a true) or \a this instance (if \a dCpy == \a false).
812  */
813 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
814 {
815   if(dCpy)
816     return deepCpy();
817   else
818     {
819       incrRef();
820       return const_cast<DataArrayDouble *>(this);
821     }
822 }
823
824 /*!
825  * Copies all the data from another DataArrayDouble. For more info see
826  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
827  *  \param [in] other - another instance of DataArrayDouble to copy data from.
828  *  \throw If the \a other is not allocated.
829  */
830 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
831 {
832   other.checkAllocated();
833   int nbOfTuples=other.getNumberOfTuples();
834   int nbOfComp=other.getNumberOfComponents();
835   allocIfNecessary(nbOfTuples,nbOfComp);
836   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
837   double *pt=getPointer();
838   const double *ptI=other.getConstPointer();
839   for(std::size_t i=0;i<nbOfElems;i++)
840     pt[i]=ptI[i];
841   copyStringInfoFrom(other);
842 }
843
844 /*!
845  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
846  * 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.
847  * If \a this has not already been allocated, number of components is set to one.
848  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
849  * 
850  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
851  */
852 void DataArrayDouble::reserve(std::size_t nbOfElems)
853 {
854   int nbCompo=getNumberOfComponents();
855   if(nbCompo==1)
856     {
857       _mem.reserve(nbOfElems);
858     }
859   else if(nbCompo==0)
860     {
861       _mem.reserve(nbOfElems);
862       _info_on_compo.resize(1);
863     }
864   else
865     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
866 }
867
868 /*!
869  * 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
870  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
871  *
872  * \param [in] val the value to be added in \a this
873  * \throw If \a this has already been allocated with number of components different from one.
874  * \sa DataArrayDouble::pushBackValsSilent
875  */
876 void DataArrayDouble::pushBackSilent(double val)
877 {
878   int nbCompo=getNumberOfComponents();
879   if(nbCompo==1)
880     _mem.pushBack(val);
881   else if(nbCompo==0)
882     {
883       _info_on_compo.resize(1);
884       _mem.pushBack(val);
885     }
886   else
887     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
888 }
889
890 /*!
891  * 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
892  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
893  *
894  *  \param [in] valsBg - an array of values to push at the end of \this.
895  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
896  *              the last value of \a valsBg is \a valsEnd[ -1 ].
897  * \throw If \a this has already been allocated with number of components different from one.
898  * \sa DataArrayDouble::pushBackSilent
899  */
900 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
901 {
902   int nbCompo=getNumberOfComponents();
903   if(nbCompo==1)
904     _mem.insertAtTheEnd(valsBg,valsEnd);
905   else if(nbCompo==0)
906     {
907       _info_on_compo.resize(1);
908       _mem.insertAtTheEnd(valsBg,valsEnd);
909     }
910   else
911     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
912 }
913
914 /*!
915  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
916  * \throw If \a this is already empty.
917  * \throw If \a this has number of components different from one.
918  */
919 double DataArrayDouble::popBackSilent()
920 {
921   if(getNumberOfComponents()==1)
922     return _mem.popBack();
923   else
924     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
925 }
926
927 /*!
928  * 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.
929  *
930  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
931  */
932 void DataArrayDouble::pack() const
933 {
934   _mem.pack();
935 }
936
937 /*!
938  * Allocates the raw data in memory. If exactly same memory as needed already
939  * allocated, it is not re-allocated.
940  *  \param [in] nbOfTuple - number of tuples of data to allocate.
941  *  \param [in] nbOfCompo - number of components of data to allocate.
942  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
943  */
944 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
945 {
946   if(isAllocated())
947     {
948       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
949         alloc(nbOfTuple,nbOfCompo);
950     }
951   else
952     alloc(nbOfTuple,nbOfCompo);
953 }
954
955 /*!
956  * Allocates the raw data in memory. If the memory was already allocated, then it is
957  * freed and re-allocated. See an example of this method use
958  * \ref MEDCouplingArraySteps1WC "here".
959  *  \param [in] nbOfTuple - number of tuples of data to allocate.
960  *  \param [in] nbOfCompo - number of components of data to allocate.
961  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
962  */
963 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
964 {
965   if(nbOfTuple<0 || nbOfCompo<0)
966     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
967   _info_on_compo.resize(nbOfCompo);
968   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
969   declareAsNew();
970 }
971
972 /*!
973  * Assign zero to all values in \a this array. To know more on filling arrays see
974  * \ref MEDCouplingArrayFill.
975  * \throw If \a this is not allocated.
976  */
977 void DataArrayDouble::fillWithZero()
978 {
979   checkAllocated();
980   _mem.fillWithValue(0.);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign \a val to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  *  \param [in] val - the value to fill with.
988  *  \throw If \a this is not allocated.
989  */
990 void DataArrayDouble::fillWithValue(double val)
991 {
992   checkAllocated();
993   _mem.fillWithValue(val);
994   declareAsNew();
995 }
996
997 /*!
998  * Set all values in \a this array so that the i-th element equals to \a init + i
999  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1000  *  \param [in] init - value to assign to the first element of array.
1001  *  \throw If \a this->getNumberOfComponents() != 1
1002  *  \throw If \a this is not allocated.
1003  */
1004 void DataArrayDouble::iota(double init)
1005 {
1006   checkAllocated();
1007   if(getNumberOfComponents()!=1)
1008     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1009   double *ptr=getPointer();
1010   int ntuples=getNumberOfTuples();
1011   for(int i=0;i<ntuples;i++)
1012     ptr[i]=init+double(i);
1013   declareAsNew();
1014 }
1015
1016 /*!
1017  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1018  *  \param [in] val - value to check equality of array values to.
1019  *  \param [in] eps - precision to check the equality.
1020  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1021  *                 \a false else.
1022  *  \throw If \a this->getNumberOfComponents() != 1
1023  *  \throw If \a this is not allocated.
1024  */
1025 bool DataArrayDouble::isUniform(double val, double eps) const
1026 {
1027   checkAllocated();
1028   if(getNumberOfComponents()!=1)
1029     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1030   int nbOfTuples=getNumberOfTuples();
1031   const double *w=getConstPointer();
1032   const double *end2=w+nbOfTuples;
1033   const double vmin=val-eps;
1034   const double vmax=val+eps;
1035   for(;w!=end2;w++)
1036     if(*w<vmin || *w>vmax)
1037       return false;
1038   return true;
1039 }
1040
1041 /*!
1042  * Sorts values of the array.
1043  *  \param [in] asc - \a true means ascending order, \a false, descending.
1044  *  \throw If \a this is not allocated.
1045  *  \throw If \a this->getNumberOfComponents() != 1.
1046  */
1047 void DataArrayDouble::sort(bool asc)
1048 {
1049   checkAllocated();
1050   if(getNumberOfComponents()!=1)
1051     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1052   _mem.sort(asc);
1053   declareAsNew();
1054 }
1055
1056 /*!
1057  * Reverse the array values.
1058  *  \throw If \a this->getNumberOfComponents() < 1.
1059  *  \throw If \a this is not allocated.
1060  */
1061 void DataArrayDouble::reverse()
1062 {
1063   checkAllocated();
1064   _mem.reverse(getNumberOfComponents());
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1070  * with at least absolute difference value of |\a eps| at each step.
1071  * If not an exception is thrown.
1072  *  \param [in] increasing - if \a true, the array values should be increasing.
1073  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1074  *                    the values are considered different.
1075  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1076  *         increasing arg.
1077  *  \throw If \a this->getNumberOfComponents() != 1.
1078  *  \throw If \a this is not allocated.
1079  */
1080 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1081 {
1082   if(!isMonotonic(increasing,eps))
1083     {
1084       if (increasing)
1085         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1086       else
1087         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1088     }
1089 }
1090
1091 /*!
1092  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1093  * with at least absolute difference value of |\a eps| at each step.
1094  *  \param [in] increasing - if \a true, array values should be increasing.
1095  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1096  *                    the values are considered different.
1097  *  \return bool - \a true if values change in accordance with \a increasing arg.
1098  *  \throw If \a this->getNumberOfComponents() != 1.
1099  *  \throw If \a this is not allocated.
1100  */
1101 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1102 {
1103   checkAllocated();
1104   if(getNumberOfComponents()!=1)
1105     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1106   int nbOfElements=getNumberOfTuples();
1107   const double *ptr=getConstPointer();
1108   if(nbOfElements==0)
1109     return true;
1110   double ref=ptr[0];
1111   double absEps=fabs(eps);
1112   if(increasing)
1113     {
1114       for(int i=1;i<nbOfElements;i++)
1115         {
1116           if(ptr[i]<(ref+absEps))
1117             return false;
1118           ref=ptr[i];
1119         }
1120       return true;
1121     }
1122   else
1123     {
1124       for(int i=1;i<nbOfElements;i++)
1125         {
1126           if(ptr[i]>(ref-absEps))
1127             return false;
1128           ref=ptr[i];
1129         }
1130       return true;
1131     }
1132 }
1133
1134 /*!
1135  * Returns a textual and human readable representation of \a this instance of
1136  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1137  *  \return std::string - text describing \a this DataArrayDouble.
1138  */
1139 std::string DataArrayDouble::repr() const
1140 {
1141   std::ostringstream ret;
1142   reprStream(ret);
1143   return ret.str();
1144 }
1145
1146 std::string DataArrayDouble::reprZip() const
1147 {
1148   std::ostringstream ret;
1149   reprZipStream(ret);
1150   return ret.str();
1151 }
1152
1153 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile, DataArrayByte *byteArr) const
1154 {
1155   static const char SPACE[4]={' ',' ',' ',' '};
1156   checkAllocated();
1157   std::string idt(indent,' ');
1158   ofs.precision(17);
1159   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1160   if(byteArr)
1161     {
1162       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1163       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1164       float *pt(tmp);
1165       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1166       for(const double *src=begin();src!=end();src++,pt++)
1167         *pt=float(*src);
1168       const char *data(reinterpret_cast<const char *>((float *)tmp));
1169       std::size_t sz(getNbOfElems()*sizeof(float));
1170       byteArr->insertAtTheEnd(data,data+sz);
1171       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1172     }
1173   else
1174     {
1175       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1176       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1177     }
1178   ofs << std::endl << idt << "</DataArray>\n";
1179 }
1180
1181 void DataArrayDouble::reprStream(std::ostream& stream) const
1182 {
1183   stream << "Name of double array : \"" << _name << "\"\n";
1184   reprWithoutNameStream(stream);
1185 }
1186
1187 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1188 {
1189   stream << "Name of double array : \"" << _name << "\"\n";
1190   reprZipWithoutNameStream(stream);
1191 }
1192
1193 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1194 {
1195   DataArray::reprWithoutNameStream(stream);
1196   stream.precision(17);
1197   _mem.repr(getNumberOfComponents(),stream);
1198 }
1199
1200 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1201 {
1202   DataArray::reprWithoutNameStream(stream);
1203   stream.precision(17);
1204   _mem.reprZip(getNumberOfComponents(),stream);
1205 }
1206
1207 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const
1208 {
1209   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1210   const double *data=getConstPointer();
1211   stream.precision(17);
1212   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1213   if(nbTuples*nbComp>=1)
1214     {
1215       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1216       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1217       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1218       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1219     }
1220   else
1221     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1222   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1223 }
1224
1225 /*!
1226  * Method that gives a quick overvien of \a this for python.
1227  */
1228 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1229 {
1230   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1231   stream << "DataArrayDouble C++ instance at " << this << ". ";
1232   if(isAllocated())
1233     {
1234       int nbOfCompo=(int)_info_on_compo.size();
1235       if(nbOfCompo>=1)
1236         {
1237           int nbOfTuples=getNumberOfTuples();
1238           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1239           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1240         }
1241       else
1242         stream << "Number of components : 0.";
1243     }
1244   else
1245     stream << "*** No data allocated ****";
1246 }
1247
1248 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1249 {
1250   const double *data=begin();
1251   int nbOfTuples=getNumberOfTuples();
1252   int nbOfCompo=(int)_info_on_compo.size();
1253   std::ostringstream oss2; oss2 << "[";
1254   oss2.precision(17);
1255   std::string oss2Str(oss2.str());
1256   bool isFinished=true;
1257   for(int i=0;i<nbOfTuples && isFinished;i++)
1258     {
1259       if(nbOfCompo>1)
1260         {
1261           oss2 << "(";
1262           for(int j=0;j<nbOfCompo;j++,data++)
1263             {
1264               oss2 << *data;
1265               if(j!=nbOfCompo-1) oss2 << ", ";
1266             }
1267           oss2 << ")";
1268         }
1269       else
1270         oss2 << *data++;
1271       if(i!=nbOfTuples-1) oss2 << ", ";
1272       std::string oss3Str(oss2.str());
1273       if(oss3Str.length()<maxNbOfByteInRepr)
1274         oss2Str=oss3Str;
1275       else
1276         isFinished=false;
1277     }
1278   stream << oss2Str;
1279   if(!isFinished)
1280     stream << "... ";
1281   stream << "]";
1282 }
1283
1284 /*!
1285  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1286  * mismatch is given.
1287  * 
1288  * \param [in] other the instance to be compared with \a this
1289  * \param [in] prec the precision to compare numeric data of the arrays.
1290  * \param [out] reason In case of inequality returns the reason.
1291  * \sa DataArrayDouble::isEqual
1292  */
1293 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1294 {
1295   if(!areInfoEqualsIfNotWhy(other,reason))
1296     return false;
1297   return _mem.isEqual(other._mem,prec,reason);
1298 }
1299
1300 /*!
1301  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1302  * \ref MEDCouplingArrayBasicsCompare.
1303  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1304  *  \param [in] prec - precision value to compare numeric data of the arrays.
1305  *  \return bool - \a true if the two arrays are equal, \a false else.
1306  */
1307 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1308 {
1309   std::string tmp;
1310   return isEqualIfNotWhy(other,prec,tmp);
1311 }
1312
1313 /*!
1314  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1315  * \ref MEDCouplingArrayBasicsCompare.
1316  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1317  *  \param [in] prec - precision value to compare numeric data of the arrays.
1318  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1319  */
1320 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1321 {
1322   std::string tmp;
1323   return _mem.isEqual(other._mem,prec,tmp);
1324 }
1325
1326 /*!
1327  * Changes number of tuples in the array. If the new number of tuples is smaller
1328  * than the current number the array is truncated, otherwise the array is extended.
1329  *  \param [in] nbOfTuples - new number of tuples. 
1330  *  \throw If \a this is not allocated.
1331  *  \throw If \a nbOfTuples is negative.
1332  */
1333 void DataArrayDouble::reAlloc(int nbOfTuples)
1334 {
1335   if(nbOfTuples<0)
1336     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1337   checkAllocated();
1338   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1339   declareAsNew();
1340 }
1341
1342 /*!
1343  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1344  * array to the new one.
1345  *  \return DataArrayInt * - the new instance of DataArrayInt.
1346  */
1347 DataArrayInt *DataArrayDouble::convertToIntArr() const
1348 {
1349   DataArrayInt *ret=DataArrayInt::New();
1350   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1351   std::size_t nbOfVals=getNbOfElems();
1352   int *dest=ret->getPointer();
1353   // to make Visual C++ happy : instead of std::copy(src,src+nbOfVals,dest);
1354   for(const double *src=begin();src!=end();src++,dest++)
1355     *dest=(int)*src;
1356   ret->copyStringInfoFrom(*this);
1357   return ret;
1358 }
1359
1360 /*!
1361  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1362  * arranged in memory. If \a this array holds 2 components of 3 values:
1363  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1364  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1365  *  \warning Do not confuse this method with transpose()!
1366  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1367  *          is to delete using decrRef() as it is no more needed.
1368  *  \throw If \a this is not allocated.
1369  */
1370 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1371 {
1372   if(_mem.isNull())
1373     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1374   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1375   DataArrayDouble *ret=DataArrayDouble::New();
1376   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1377   return ret;
1378 }
1379
1380 /*!
1381  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1382  * arranged in memory. If \a this array holds 2 components of 3 values:
1383  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1384  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1385  *  \warning Do not confuse this method with transpose()!
1386  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1387  *          is to delete using decrRef() as it is no more needed.
1388  *  \throw If \a this is not allocated.
1389  */
1390 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1391 {
1392   if(_mem.isNull())
1393     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1394   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1395   DataArrayDouble *ret=DataArrayDouble::New();
1396   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1397   return ret;
1398 }
1399
1400 /*!
1401  * Permutes values of \a this array as required by \a old2New array. The values are
1402  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1403  * the same as in \this one.
1404  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1405  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1406  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1407  *     giving a new position for i-th old value.
1408  */
1409 void DataArrayDouble::renumberInPlace(const int *old2New)
1410 {
1411   checkAllocated();
1412   int nbTuples=getNumberOfTuples();
1413   int nbOfCompo=getNumberOfComponents();
1414   double *tmp=new double[nbTuples*nbOfCompo];
1415   const double *iptr=getConstPointer();
1416   for(int i=0;i<nbTuples;i++)
1417     {
1418       int v=old2New[i];
1419       if(v>=0 && v<nbTuples)
1420         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1421       else
1422         {
1423           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1424           throw INTERP_KERNEL::Exception(oss.str().c_str());
1425         }
1426     }
1427   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1428   delete [] tmp;
1429   declareAsNew();
1430 }
1431
1432 /*!
1433  * Permutes values of \a this array as required by \a new2Old array. The values are
1434  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1435  * the same as in \this one.
1436  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1437  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1438  *     giving a previous position of i-th new value.
1439  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1440  *          is to delete using decrRef() as it is no more needed.
1441  */
1442 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1443 {
1444   checkAllocated();
1445   int nbTuples=getNumberOfTuples();
1446   int nbOfCompo=getNumberOfComponents();
1447   double *tmp=new double[nbTuples*nbOfCompo];
1448   const double *iptr=getConstPointer();
1449   for(int i=0;i<nbTuples;i++)
1450     {
1451       int v=new2Old[i];
1452       if(v>=0 && v<nbTuples)
1453         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1454       else
1455         {
1456           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1457           throw INTERP_KERNEL::Exception(oss.str().c_str());
1458         }
1459     }
1460   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1461   delete [] tmp;
1462   declareAsNew();
1463 }
1464
1465 /*!
1466  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1467  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1468  * Number of tuples in the result array remains the same as in \this one.
1469  * If a permutation reduction is needed, renumberAndReduce() should be used.
1470  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1471  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1472  *          giving a new position for i-th old value.
1473  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1474  *          is to delete using decrRef() as it is no more needed.
1475  *  \throw If \a this is not allocated.
1476  */
1477 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1478 {
1479   checkAllocated();
1480   int nbTuples=getNumberOfTuples();
1481   int nbOfCompo=getNumberOfComponents();
1482   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1483   ret->alloc(nbTuples,nbOfCompo);
1484   ret->copyStringInfoFrom(*this);
1485   const double *iptr=getConstPointer();
1486   double *optr=ret->getPointer();
1487   for(int i=0;i<nbTuples;i++)
1488     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1489   ret->copyStringInfoFrom(*this);
1490   return ret.retn();
1491 }
1492
1493 /*!
1494  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1495  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1496  * tuples in the result array remains the same as in \this one.
1497  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1498  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1499  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1500  *     giving a previous position of i-th new value.
1501  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1502  *          is to delete using decrRef() as it is no more needed.
1503  */
1504 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1505 {
1506   checkAllocated();
1507   int nbTuples=getNumberOfTuples();
1508   int nbOfCompo=getNumberOfComponents();
1509   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1510   ret->alloc(nbTuples,nbOfCompo);
1511   ret->copyStringInfoFrom(*this);
1512   const double *iptr=getConstPointer();
1513   double *optr=ret->getPointer();
1514   for(int i=0;i<nbTuples;i++)
1515     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1516   ret->copyStringInfoFrom(*this);
1517   return ret.retn();
1518 }
1519
1520 /*!
1521  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1522  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1523  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1524  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1525  * \a old2New[ i ] is negative, is missing from the result array.
1526  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1527  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1528  *     giving a new position for i-th old tuple and giving negative position for
1529  *     for i-th old tuple that should be omitted.
1530  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1531  *          is to delete using decrRef() as it is no more needed.
1532  */
1533 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1534 {
1535   checkAllocated();
1536   int nbTuples=getNumberOfTuples();
1537   int nbOfCompo=getNumberOfComponents();
1538   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1539   ret->alloc(newNbOfTuple,nbOfCompo);
1540   const double *iptr=getConstPointer();
1541   double *optr=ret->getPointer();
1542   for(int i=0;i<nbTuples;i++)
1543     {
1544       int w=old2New[i];
1545       if(w>=0)
1546         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1547     }
1548   ret->copyStringInfoFrom(*this);
1549   return ret.retn();
1550 }
1551
1552 /*!
1553  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1554  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1555  * \a new2OldBg array.
1556  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1557  * This method is equivalent to renumberAndReduce() except that convention in input is
1558  * \c new2old and \b not \c old2new.
1559  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1560  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1561  *              tuple index in \a this array to fill the i-th tuple in the new array.
1562  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1563  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1564  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1565  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1566  *          is to delete using decrRef() as it is no more needed.
1567  */
1568 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1569 {
1570   checkAllocated();
1571   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1572   int nbComp=getNumberOfComponents();
1573   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1574   ret->copyStringInfoFrom(*this);
1575   double *pt=ret->getPointer();
1576   const double *srcPt=getConstPointer();
1577   int i=0;
1578   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1579     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1580   ret->copyStringInfoFrom(*this);
1581   return ret.retn();
1582 }
1583
1584 /*!
1585  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1586  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1587  * \a new2OldBg array.
1588  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1589  * This method is equivalent to renumberAndReduce() except that convention in input is
1590  * \c new2old and \b not \c old2new.
1591  * This method is equivalent to selectByTupleId() except that it prevents coping data
1592  * from behind the end of \a this array.
1593  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1594  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1595  *              tuple index in \a this array to fill the i-th tuple in the new array.
1596  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1597  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1598  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1599  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1600  *          is to delete using decrRef() as it is no more needed.
1601  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1602  */
1603 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1604 {
1605   checkAllocated();
1606   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1607   int nbComp=getNumberOfComponents();
1608   int oldNbOfTuples=getNumberOfTuples();
1609   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1610   ret->copyStringInfoFrom(*this);
1611   double *pt=ret->getPointer();
1612   const double *srcPt=getConstPointer();
1613   int i=0;
1614   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1615     if(*w>=0 && *w<oldNbOfTuples)
1616       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1617     else
1618       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1619   ret->copyStringInfoFrom(*this);
1620   return ret.retn();
1621 }
1622
1623 /*!
1624  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1625  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1626  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1627  * command \c range( \a bg, \a end2, \a step ).
1628  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1629  * not constructed explicitly.
1630  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1631  *  \param [in] bg - index of the first tuple to copy from \a this array.
1632  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1633  *  \param [in] step - index increment to get index of the next tuple to copy.
1634  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1635  *          is to delete using decrRef() as it is no more needed.
1636  *  \sa DataArrayDouble::substr.
1637  */
1638 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1639 {
1640   checkAllocated();
1641   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1642   int nbComp=getNumberOfComponents();
1643   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1644   ret->alloc(newNbOfTuples,nbComp);
1645   double *pt=ret->getPointer();
1646   const double *srcPt=getConstPointer()+bg*nbComp;
1647   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1648     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1649   ret->copyStringInfoFrom(*this);
1650   return ret.retn();
1651 }
1652
1653 /*!
1654  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1655  * of tuples specified by \a ranges parameter.
1656  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1657  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1658  *              of tuples in [\c begin,\c end) format.
1659  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1660  *          is to delete using decrRef() as it is no more needed.
1661  *  \throw If \a end < \a begin.
1662  *  \throw If \a end > \a this->getNumberOfTuples().
1663  *  \throw If \a this is not allocated.
1664  */
1665 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1666 {
1667   checkAllocated();
1668   int nbOfComp=getNumberOfComponents();
1669   int nbOfTuplesThis=getNumberOfTuples();
1670   if(ranges.empty())
1671     {
1672       DataArrayDouble *ret=DataArrayDouble::New();
1673       ret->alloc(0,nbOfComp);
1674       ret->copyStringInfoFrom(*this);
1675       return ret;
1676     }
1677   int ref=ranges.front().first;
1678   int nbOfTuples=0;
1679   bool isIncreasing=true;
1680   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1681     {
1682       if((*it).first<=(*it).second)
1683         {
1684           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1685             {
1686               nbOfTuples+=(*it).second-(*it).first;
1687               if(isIncreasing)
1688                 isIncreasing=ref<=(*it).first;
1689               ref=(*it).second;
1690             }
1691           else
1692             {
1693               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1694               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1695               throw INTERP_KERNEL::Exception(oss.str().c_str());
1696             }
1697         }
1698       else
1699         {
1700           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1701           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1702           throw INTERP_KERNEL::Exception(oss.str().c_str());
1703         }
1704     }
1705   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1706     return deepCpy();
1707   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1708   ret->alloc(nbOfTuples,nbOfComp);
1709   ret->copyStringInfoFrom(*this);
1710   const double *src=getConstPointer();
1711   double *work=ret->getPointer();
1712   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1713     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1714   return ret.retn();
1715 }
1716
1717 /*!
1718  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1719  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1720  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1721  * This method is a specialization of selectByTupleId2().
1722  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1723  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1724  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1725  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1726  *          is to delete using decrRef() as it is no more needed.
1727  *  \throw If \a tupleIdBg < 0.
1728  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1729     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1730  *  \sa DataArrayDouble::selectByTupleId2
1731  */
1732 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1733 {
1734   checkAllocated();
1735   int nbt=getNumberOfTuples();
1736   if(tupleIdBg<0)
1737     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1738   if(tupleIdBg>nbt)
1739     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1740   int trueEnd=tupleIdEnd;
1741   if(tupleIdEnd!=-1)
1742     {
1743       if(tupleIdEnd>nbt)
1744         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1745     }
1746   else
1747     trueEnd=nbt;
1748   int nbComp=getNumberOfComponents();
1749   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1750   ret->alloc(trueEnd-tupleIdBg,nbComp);
1751   ret->copyStringInfoFrom(*this);
1752   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1753   return ret.retn();
1754 }
1755
1756 /*!
1757  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1758  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1759  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1760  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1761  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1762  * components.  
1763  *  \param [in] newNbOfComp - number of components for the new array to have.
1764  *  \param [in] dftValue - value assigned to new values added to the new array.
1765  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1766  *          is to delete using decrRef() as it is no more needed.
1767  *  \throw If \a this is not allocated.
1768  */
1769 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1770 {
1771   checkAllocated();
1772   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1773   ret->alloc(getNumberOfTuples(),newNbOfComp);
1774   const double *oldc=getConstPointer();
1775   double *nc=ret->getPointer();
1776   int nbOfTuples=getNumberOfTuples();
1777   int oldNbOfComp=getNumberOfComponents();
1778   int dim=std::min(oldNbOfComp,newNbOfComp);
1779   for(int i=0;i<nbOfTuples;i++)
1780     {
1781       int j=0;
1782       for(;j<dim;j++)
1783         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1784       for(;j<newNbOfComp;j++)
1785         nc[newNbOfComp*i+j]=dftValue;
1786     }
1787   ret->setName(getName().c_str());
1788   for(int i=0;i<dim;i++)
1789     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1790   ret->setName(getName().c_str());
1791   return ret.retn();
1792 }
1793
1794 /*!
1795  * Changes the number of components within \a this array so that its raw data **does
1796  * not** change, instead splitting this data into tuples changes.
1797  *  \warning This method erases all (name and unit) component info set before!
1798  *  \param [in] newNbOfComp - number of components for \a this array to have.
1799  *  \throw If \a this is not allocated
1800  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1801  *  \throw If \a newNbOfCompo is lower than 1.
1802  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1803  *  \warning This method erases all (name and unit) component info set before!
1804  */
1805 void DataArrayDouble::rearrange(int newNbOfCompo)
1806 {
1807   checkAllocated();
1808   if(newNbOfCompo<1)
1809     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1810   std::size_t nbOfElems=getNbOfElems();
1811   if(nbOfElems%newNbOfCompo!=0)
1812     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1813   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1814     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1815   _info_on_compo.clear();
1816   _info_on_compo.resize(newNbOfCompo);
1817   declareAsNew();
1818 }
1819
1820 /*!
1821  * Changes the number of components within \a this array to be equal to its number
1822  * of tuples, and inversely its number of tuples to become equal to its number of 
1823  * components. So that its raw data **does not** change, instead splitting this
1824  * data into tuples changes.
1825  *  \warning This method erases all (name and unit) component info set before!
1826  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1827  *  \throw If \a this is not allocated.
1828  *  \sa rearrange()
1829  */
1830 void DataArrayDouble::transpose()
1831 {
1832   checkAllocated();
1833   int nbOfTuples=getNumberOfTuples();
1834   rearrange(nbOfTuples);
1835 }
1836
1837 /*!
1838  * Returns a copy of \a this array composed of selected components.
1839  * The new DataArrayDouble has the same number of tuples but includes components
1840  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1841  * can be either less, same or more than \a this->getNbOfElems().
1842  *  \param [in] compoIds - sequence of zero based indices of components to include
1843  *              into the new array.
1844  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1845  *          is to delete using decrRef() as it is no more needed.
1846  *  \throw If \a this is not allocated.
1847  *  \throw If a component index (\a i) is not valid: 
1848  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1849  *
1850  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1851  */
1852 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1853 {
1854   checkAllocated();
1855   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1856   std::size_t newNbOfCompo=compoIds.size();
1857   int oldNbOfCompo=getNumberOfComponents();
1858   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1859     if((*it)<0 || (*it)>=oldNbOfCompo)
1860       {
1861         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1862         throw INTERP_KERNEL::Exception(oss.str().c_str());
1863       }
1864   int nbOfTuples=getNumberOfTuples();
1865   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1866   ret->copyPartOfStringInfoFrom(*this,compoIds);
1867   const double *oldc=getConstPointer();
1868   double *nc=ret->getPointer();
1869   for(int i=0;i<nbOfTuples;i++)
1870     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1871       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1872   return ret.retn();
1873 }
1874
1875 /*!
1876  * Appends components of another array to components of \a this one, tuple by tuple.
1877  * So that the number of tuples of \a this array remains the same and the number of 
1878  * components increases.
1879  *  \param [in] other - the DataArrayDouble to append to \a this one.
1880  *  \throw If \a this is not allocated.
1881  *  \throw If \a this and \a other arrays have different number of tuples.
1882  *
1883  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1884  *
1885  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1886  */
1887 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1888 {
1889   checkAllocated();
1890   other->checkAllocated();
1891   int nbOfTuples=getNumberOfTuples();
1892   if(nbOfTuples!=other->getNumberOfTuples())
1893     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1894   int nbOfComp1=getNumberOfComponents();
1895   int nbOfComp2=other->getNumberOfComponents();
1896   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1897   double *w=newArr;
1898   const double *inp1=getConstPointer();
1899   const double *inp2=other->getConstPointer();
1900   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1901     {
1902       w=std::copy(inp1,inp1+nbOfComp1,w);
1903       w=std::copy(inp2,inp2+nbOfComp2,w);
1904     }
1905   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1906   std::vector<int> compIds(nbOfComp2);
1907   for(int i=0;i<nbOfComp2;i++)
1908     compIds[i]=nbOfComp1+i;
1909   copyPartOfStringInfoFrom2(compIds,*other);
1910 }
1911
1912 /*!
1913  * This method checks that all tuples in \a other are in \a this.
1914  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1915  * 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.
1916  *
1917  * \param [in] other - the array having the same number of components than \a this.
1918  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1919  * \sa DataArrayDouble::findCommonTuples
1920  */
1921 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1922 {
1923   if(!other)
1924     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1925   checkAllocated(); other->checkAllocated();
1926   if(getNumberOfComponents()!=other->getNumberOfComponents())
1927     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1928   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1929   DataArrayInt *c=0,*ci=0;
1930   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1932   int newNbOfTuples=-1;
1933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1934   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1935   tupleIds=ret1.retn();
1936   return newNbOfTuples==getNumberOfTuples();
1937 }
1938
1939 /*!
1940  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1941  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1942  * distance separating two points is computed with the infinite norm.
1943  *
1944  * Indices of coincident tuples are stored in output arrays.
1945  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1946  *
1947  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1948  * MEDCouplingUMesh::mergeNodes().
1949  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1950  *              considered not coincident.
1951  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1952  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1953  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1954  *               \a comm->getNumberOfComponents() == 1. 
1955  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1956  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1957  *               groups of (indices of) coincident tuples. Its every value is a tuple
1958  *               index where a next group of tuples begins. For example the second
1959  *               group of tuples in \a comm is described by following range of indices:
1960  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1961  *               gives the number of groups of coincident tuples.
1962  *  \throw If \a this is not allocated.
1963  *  \throw If the number of components is not in [1,2,3].
1964  *
1965  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1966  *
1967  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1968  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1969  */
1970 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1971 {
1972   checkAllocated();
1973   int nbOfCompo=getNumberOfComponents();
1974   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1975     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1976   
1977   int nbOfTuples=getNumberOfTuples();
1978   //
1979   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1980   switch(nbOfCompo)
1981     {
1982     case 3:
1983       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1984       break;
1985     case 2:
1986       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1987       break;
1988     case 1:
1989       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1990       break;
1991     default:
1992       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1993     }
1994   comm=c.retn();
1995   commIndex=cI.retn();
1996 }
1997
1998 /*!
1999  * 
2000  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2001  *             \a nbTimes  should be at least equal to 1.
2002  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2003  * \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.
2004  */
2005 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2006 {
2007   checkAllocated();
2008   if(getNumberOfComponents()!=1)
2009     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2010   if(nbTimes<1)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2012   int nbTuples=getNumberOfTuples();
2013   const double *inPtr=getConstPointer();
2014   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2015   double *retPtr=ret->getPointer();
2016   for(int i=0;i<nbTuples;i++,inPtr++)
2017     {
2018       double val=*inPtr;
2019       for(int j=0;j<nbTimes;j++,retPtr++)
2020         *retPtr=val;
2021     }
2022   ret->copyStringInfoFrom(*this);
2023   return ret.retn();
2024 }
2025
2026 /*!
2027  * This methods returns the minimal distance between the two set of points \a this and \a other.
2028  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2029  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2030  *
2031  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2032  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2033  * \return the minimal distance between the two set of points \a this and \a other.
2034  * \sa DataArrayDouble::findClosestTupleId
2035  */
2036 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2037 {
2038   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2039   int nbOfCompo(getNumberOfComponents());
2040   int otherNbTuples(other->getNumberOfTuples());
2041   const double *thisPt(begin()),*otherPt(other->begin());
2042   const int *part1Pt(part1->begin());
2043   double ret=std::numeric_limits<double>::max();
2044   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2045     {
2046       double tmp(0.);
2047       for(int j=0;j<nbOfCompo;j++)
2048         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2049       if(tmp<ret)
2050         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2051     }
2052   return sqrt(ret);
2053 }
2054
2055 /*!
2056  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2057  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2058  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2059  *
2060  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2061  * \sa DataArrayDouble::minimalDistanceTo
2062  */
2063 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2064 {
2065   if(!other)
2066     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2067   checkAllocated(); other->checkAllocated();
2068   int nbOfCompo=getNumberOfComponents();
2069   if(nbOfCompo!=other->getNumberOfComponents())
2070     {
2071       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2072       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2073       throw INTERP_KERNEL::Exception(oss.str().c_str());
2074     }
2075   int nbOfTuples=other->getNumberOfTuples();
2076   int thisNbOfTuples=getNumberOfTuples();
2077   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2078   double bounds[6];
2079   getMinMaxPerComponent(bounds);
2080   switch(nbOfCompo)
2081     {
2082     case 3:
2083       {
2084         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2085         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2086         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2087         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2088         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2089         break;
2090       }
2091     case 2:
2092       {
2093         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2094         double delta=std::max(xDelta,yDelta);
2095         double characSize=sqrt(delta/(double)thisNbOfTuples);
2096         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2097         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2098         break;
2099       }
2100     case 1:
2101       {
2102         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2103         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2104         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2105         break;
2106       }
2107     default:
2108       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2109     }
2110   return ret.retn();
2111 }
2112
2113 /*!
2114  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2115  * 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
2116  * how many bounding boxes in \a otherBBoxFrmt.
2117  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2118  *
2119  * \param [in] otherBBoxFrmt - It is an array .
2120  * \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.
2121  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2122  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2123  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2124  */
2125 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2126 {
2127   if(!otherBBoxFrmt)
2128     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2129   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2130     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2131   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2132   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2133     {
2134       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2135       throw INTERP_KERNEL::Exception(oss.str().c_str());
2136     }
2137   if(nbOfComp%2!=0)
2138     {
2139       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2140       throw INTERP_KERNEL::Exception(oss.str().c_str());
2141     }
2142   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2143   const double *thisBBPtr(begin());
2144   int *retPtr(ret->getPointer());
2145   switch(nbOfComp/2)
2146     {
2147     case 3:
2148       {
2149         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2150         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2151           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2152         break;
2153       }
2154     case 2:
2155       {
2156         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2157         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2158           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2159         break;
2160       }
2161     case 1:
2162       {
2163         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2164         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2165           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2166         break;
2167       }
2168     default:
2169       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2170     }
2171   
2172   return ret.retn();
2173 }
2174
2175 /*!
2176  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2177  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2178  * space. The distance between tuples is computed using norm2. If several tuples are
2179  * not far each from other than \a prec, only one of them remains in the result
2180  * array. The order of tuples in the result array is same as in \a this one except
2181  * that coincident tuples are excluded.
2182  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2183  *              considered not coincident.
2184  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2185  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2186  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2187  *          is to delete using decrRef() as it is no more needed.
2188  *  \throw If \a this is not allocated.
2189  *  \throw If the number of components is not in [1,2,3].
2190  *
2191  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2192  */
2193 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2194 {
2195   checkAllocated();
2196   DataArrayInt *c0=0,*cI0=0;
2197   findCommonTuples(prec,limitTupleId,c0,cI0);
2198   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2199   int newNbOfTuples=-1;
2200   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2201   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2202 }
2203
2204 /*!
2205  * Copy all components in a specified order from another DataArrayDouble.
2206  * Both numerical and textual data is copied. The number of tuples in \a this and
2207  * the other array can be different.
2208  *  \param [in] a - the array to copy data from.
2209  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2210  *              to be copied.
2211  *  \throw If \a a is NULL.
2212  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2213  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2214  *
2215  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2216  */
2217 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2218 {
2219   if(!a)
2220     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2221   checkAllocated();
2222   copyPartOfStringInfoFrom2(compoIds,*a);
2223   std::size_t partOfCompoSz=compoIds.size();
2224   int nbOfCompo=getNumberOfComponents();
2225   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2226   const double *ac=a->getConstPointer();
2227   double *nc=getPointer();
2228   for(int i=0;i<nbOfTuples;i++)
2229     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2230       nc[nbOfCompo*i+compoIds[j]]=*ac;
2231 }
2232
2233 /*!
2234  * Copy all values from another DataArrayDouble into specified tuples and components
2235  * of \a this array. Textual data is not copied.
2236  * The tree parameters defining set of indices of tuples and components are similar to
2237  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2238  *  \param [in] a - the array to copy values from.
2239  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2240  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2241  *              are located.
2242  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2243  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2244  *  \param [in] endComp - index of the component before which the components to assign
2245  *              to are located.
2246  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2247  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2248  *              must be equal to the number of columns to assign to, else an
2249  *              exception is thrown; if \a false, then it is only required that \a
2250  *              a->getNbOfElems() equals to number of values to assign to (this condition
2251  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2252  *              values to assign to is given by following Python expression:
2253  *              \a nbTargetValues = 
2254  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2255  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2256  *  \throw If \a a is NULL.
2257  *  \throw If \a a is not allocated.
2258  *  \throw If \a this is not allocated.
2259  *  \throw If parameters specifying tuples and components to assign to do not give a
2260  *            non-empty range of increasing indices.
2261  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2262  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2263  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2264  *
2265  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2266  */
2267 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2268 {
2269   if(!a)
2270     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2271   const char msg[]="DataArrayDouble::setPartOfValues1";
2272   checkAllocated();
2273   a->checkAllocated();
2274   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2275   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2276   int nbComp=getNumberOfComponents();
2277   int nbOfTuples=getNumberOfTuples();
2278   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2279   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2280   bool assignTech=true;
2281   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2282     {
2283       if(strictCompoCompare)
2284         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2285     }
2286   else
2287     {
2288       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2289       assignTech=false;
2290     }
2291   const double *srcPt=a->getConstPointer();
2292   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2293   if(assignTech)
2294     {
2295       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2296         for(int j=0;j<newNbOfComp;j++,srcPt++)
2297           pt[j*stepComp]=*srcPt;
2298     }
2299   else
2300     {
2301       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2302         {
2303           const double *srcPt2=srcPt;
2304           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2305             pt[j*stepComp]=*srcPt2;
2306         }
2307     }
2308 }
2309
2310 /*!
2311  * Assign a given value to values at specified tuples and components of \a this array.
2312  * The tree parameters defining set of indices of tuples and components are similar to
2313  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2314  *  \param [in] a - the value to assign.
2315  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2316  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2317  *              are located.
2318  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2319  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2320  *  \param [in] endComp - index of the component before which the components to assign
2321  *              to are located.
2322  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2323  *  \throw If \a this is not allocated.
2324  *  \throw If parameters specifying tuples and components to assign to, do not give a
2325  *            non-empty range of increasing indices or indices are out of a valid range
2326  *            for \this array.
2327  *
2328  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2329  */
2330 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2331 {
2332   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2333   checkAllocated();
2334   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2335   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2336   int nbComp=getNumberOfComponents();
2337   int nbOfTuples=getNumberOfTuples();
2338   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2339   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2340   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2341   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2342     for(int j=0;j<newNbOfComp;j++)
2343       pt[j*stepComp]=a;
2344 }
2345
2346 /*!
2347  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2348  * components of \a this array. Textual data is not copied.
2349  * The tuples and components to assign to are defined by C arrays of indices.
2350  * There are two *modes of usage*:
2351  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2352  *   of \a a is assigned to its own location within \a this array. 
2353  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2354  *   components of every specified tuple of \a this array. In this mode it is required
2355  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2356  *
2357  *  \param [in] a - the array to copy values from.
2358  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2359  *              assign values of \a a to.
2360  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2361  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2362  *              \a bgTuples <= \a pi < \a endTuples.
2363  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2364  *              assign values of \a a to.
2365  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2366  *              pointer to a component index <em>(pi)</em> varies as this: 
2367  *              \a bgComp <= \a pi < \a endComp.
2368  *  \param [in] strictCompoCompare - this parameter is checked only if the
2369  *               *mode of usage* is the first; if it is \a true (default), 
2370  *               then \a a->getNumberOfComponents() must be equal 
2371  *               to the number of specified columns, else this is not required.
2372  *  \throw If \a a is NULL.
2373  *  \throw If \a a is not allocated.
2374  *  \throw If \a this is not allocated.
2375  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2376  *         out of a valid range for \a this array.
2377  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2378  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2379  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2380  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2381  *
2382  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2383  */
2384 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2385 {
2386   if(!a)
2387     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2388   const char msg[]="DataArrayDouble::setPartOfValues2";
2389   checkAllocated();
2390   a->checkAllocated();
2391   int nbComp=getNumberOfComponents();
2392   int nbOfTuples=getNumberOfTuples();
2393   for(const int *z=bgComp;z!=endComp;z++)
2394     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2395   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2396   int newNbOfComp=(int)std::distance(bgComp,endComp);
2397   bool assignTech=true;
2398   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2399     {
2400       if(strictCompoCompare)
2401         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2402     }
2403   else
2404     {
2405       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2406       assignTech=false;
2407     }
2408   double *pt=getPointer();
2409   const double *srcPt=a->getConstPointer();
2410   if(assignTech)
2411     {    
2412       for(const int *w=bgTuples;w!=endTuples;w++)
2413         {
2414           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2415           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2416             {    
2417               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2418             }
2419         }
2420     }
2421   else
2422     {
2423       for(const int *w=bgTuples;w!=endTuples;w++)
2424         {
2425           const double *srcPt2=srcPt;
2426           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2427           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2428             {    
2429               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2430             }
2431         }
2432     }
2433 }
2434
2435 /*!
2436  * Assign a given value to values at specified tuples and components of \a this array.
2437  * The tuples and components to assign to are defined by C arrays of indices.
2438  *  \param [in] a - the value to assign.
2439  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2440  *              assign \a a to.
2441  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2442  *              pointer to a tuple index (\a pi) varies as this: 
2443  *              \a bgTuples <= \a pi < \a endTuples.
2444  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2445  *              assign \a a to.
2446  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2447  *              pointer to a component index (\a pi) varies as this: 
2448  *              \a bgComp <= \a pi < \a endComp.
2449  *  \throw If \a this is not allocated.
2450  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2451  *         out of a valid range for \a this array.
2452  *
2453  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2454  */
2455 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2456 {
2457   checkAllocated();
2458   int nbComp=getNumberOfComponents();
2459   int nbOfTuples=getNumberOfTuples();
2460   for(const int *z=bgComp;z!=endComp;z++)
2461     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2462   double *pt=getPointer();
2463   for(const int *w=bgTuples;w!=endTuples;w++)
2464     for(const int *z=bgComp;z!=endComp;z++)
2465       {
2466         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2467         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2468       }
2469 }
2470
2471 /*!
2472  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2473  * components of \a this array. Textual data is not copied.
2474  * The tuples to assign to are defined by a C array of indices.
2475  * The components to assign to are defined by three values similar to parameters of
2476  * the Python function \c range(\c start,\c stop,\c step).
2477  * There are two *modes of usage*:
2478  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2479  *   of \a a is assigned to its own location within \a this array. 
2480  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2481  *   components of every specified tuple of \a this array. In this mode it is required
2482  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2483  *
2484  *  \param [in] a - the array to copy values from.
2485  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2486  *              assign values of \a a to.
2487  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2488  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2489  *              \a bgTuples <= \a pi < \a endTuples.
2490  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2491  *  \param [in] endComp - index of the component before which the components to assign
2492  *              to are located.
2493  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2494  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2495  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2496  *               then \a a->getNumberOfComponents() must be equal 
2497  *               to the number of specified columns, else this is not required.
2498  *  \throw If \a a is NULL.
2499  *  \throw If \a a is not allocated.
2500  *  \throw If \a this is not allocated.
2501  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2502  *         \a this array.
2503  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2504  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2505  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2506  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2507  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2508  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2509  *  \throw If parameters specifying components to assign to, do not give a
2510  *            non-empty range of increasing indices or indices are out of a valid range
2511  *            for \this array.
2512  *
2513  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2514  */
2515 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2516 {
2517   if(!a)
2518     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2519   const char msg[]="DataArrayDouble::setPartOfValues3";
2520   checkAllocated();
2521   a->checkAllocated();
2522   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2523   int nbComp=getNumberOfComponents();
2524   int nbOfTuples=getNumberOfTuples();
2525   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2526   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2527   bool assignTech=true;
2528   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2529     {
2530       if(strictCompoCompare)
2531         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2532     }
2533   else
2534     {
2535       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2536       assignTech=false;
2537     }
2538   double *pt=getPointer()+bgComp;
2539   const double *srcPt=a->getConstPointer();
2540   if(assignTech)
2541     {
2542       for(const int *w=bgTuples;w!=endTuples;w++)
2543         for(int j=0;j<newNbOfComp;j++,srcPt++)
2544           {
2545             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2546             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2547           }
2548     }
2549   else
2550     {
2551       for(const int *w=bgTuples;w!=endTuples;w++)
2552         {
2553           const double *srcPt2=srcPt;
2554           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2555             {
2556               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2557               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2558             }
2559         }
2560     }
2561 }
2562
2563 /*!
2564  * Assign a given value to values at specified tuples and components of \a this array.
2565  * The tuples to assign to are defined by a C array of indices.
2566  * The components to assign to are defined by three values similar to parameters of
2567  * the Python function \c range(\c start,\c stop,\c step).
2568  *  \param [in] a - the value to assign.
2569  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2570  *              assign \a a to.
2571  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2572  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2573  *              \a bgTuples <= \a pi < \a endTuples.
2574  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2575  *  \param [in] endComp - index of the component before which the components to assign
2576  *              to are located.
2577  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2578  *  \throw If \a this is not allocated.
2579  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2580  *         \a this array.
2581  *  \throw If parameters specifying components to assign to, do not give a
2582  *            non-empty range of increasing indices or indices are out of a valid range
2583  *            for \this array.
2584  *
2585  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2586  */
2587 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2588 {
2589   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2590   checkAllocated();
2591   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2592   int nbComp=getNumberOfComponents();
2593   int nbOfTuples=getNumberOfTuples();
2594   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2595   double *pt=getPointer()+bgComp;
2596   for(const int *w=bgTuples;w!=endTuples;w++)
2597     for(int j=0;j<newNbOfComp;j++)
2598       {
2599         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2600         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2601       }
2602 }
2603
2604 /*!
2605  * Copy all values from another DataArrayDouble into specified tuples and components
2606  * of \a this array. Textual data is not copied.
2607  * The tree parameters defining set of indices of tuples and components are similar to
2608  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2609  *  \param [in] a - the array to copy values from.
2610  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2611  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2612  *              are located.
2613  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2614  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2615  *              assign \a a to.
2616  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2617  *              pointer to a component index (\a pi) varies as this: 
2618  *              \a bgComp <= \a pi < \a endComp.
2619  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2620  *              must be equal to the number of columns to assign to, else an
2621  *              exception is thrown; if \a false, then it is only required that \a
2622  *              a->getNbOfElems() equals to number of values to assign to (this condition
2623  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2624  *              values to assign to is given by following Python expression:
2625  *              \a nbTargetValues = 
2626  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2627  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2628  *  \throw If \a a is NULL.
2629  *  \throw If \a a is not allocated.
2630  *  \throw If \a this is not allocated.
2631  *  \throw If parameters specifying tuples and components to assign to do not give a
2632  *            non-empty range of increasing indices.
2633  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2634  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2635  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2636  *
2637  */
2638 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2639 {
2640   if(!a)
2641     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2642   const char msg[]="DataArrayDouble::setPartOfValues4";
2643   checkAllocated();
2644   a->checkAllocated();
2645   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2646   int newNbOfComp=(int)std::distance(bgComp,endComp);
2647   int nbComp=getNumberOfComponents();
2648   for(const int *z=bgComp;z!=endComp;z++)
2649     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2650   int nbOfTuples=getNumberOfTuples();
2651   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2652   bool assignTech=true;
2653   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2654     {
2655       if(strictCompoCompare)
2656         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2657     }
2658   else
2659     {
2660       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2661       assignTech=false;
2662     }
2663   const double *srcPt=a->getConstPointer();
2664   double *pt=getPointer()+bgTuples*nbComp;
2665   if(assignTech)
2666     {
2667       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2668         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2669           pt[*z]=*srcPt;
2670     }
2671   else
2672     {
2673       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2674         {
2675           const double *srcPt2=srcPt;
2676           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2677             pt[*z]=*srcPt2;
2678         }
2679     }
2680 }
2681
2682 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2683 {
2684   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2685   checkAllocated();
2686   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2687   int nbComp=getNumberOfComponents();
2688   for(const int *z=bgComp;z!=endComp;z++)
2689     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2690   int nbOfTuples=getNumberOfTuples();
2691   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2692   double *pt=getPointer()+bgTuples*nbComp;
2693   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2694     for(const int *z=bgComp;z!=endComp;z++)
2695       pt[*z]=a;
2696 }
2697
2698 /*!
2699  * Copy some tuples from another DataArrayDouble into specified tuples
2700  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2701  * components.
2702  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2703  * All components of selected tuples are copied.
2704  *  \param [in] a - the array to copy values from.
2705  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2706  *              target tuples of \a this. \a tuplesSelec has two components, and the
2707  *              first component specifies index of the source tuple and the second
2708  *              one specifies index of the target tuple.
2709  *  \throw If \a this is not allocated.
2710  *  \throw If \a a is NULL.
2711  *  \throw If \a a is not allocated.
2712  *  \throw If \a tuplesSelec is NULL.
2713  *  \throw If \a tuplesSelec is not allocated.
2714  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2715  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2716  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2717  *         the corresponding (\a this or \a a) array.
2718  */
2719 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2720 {
2721   if(!a || !tuplesSelec)
2722     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2723   checkAllocated();
2724   a->checkAllocated();
2725   tuplesSelec->checkAllocated();
2726   int nbOfComp=getNumberOfComponents();
2727   if(nbOfComp!=a->getNumberOfComponents())
2728     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2729   if(tuplesSelec->getNumberOfComponents()!=2)
2730     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2731   int thisNt=getNumberOfTuples();
2732   int aNt=a->getNumberOfTuples();
2733   double *valsToSet=getPointer();
2734   const double *valsSrc=a->getConstPointer();
2735   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2736     {
2737       if(tuple[1]>=0 && tuple[1]<aNt)
2738         {
2739           if(tuple[0]>=0 && tuple[0]<thisNt)
2740             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2741           else
2742             {
2743               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2744               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2745               throw INTERP_KERNEL::Exception(oss.str().c_str());
2746             }
2747         }
2748       else
2749         {
2750           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2751           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2752           throw INTERP_KERNEL::Exception(oss.str().c_str());
2753         }
2754     }
2755 }
2756
2757 /*!
2758  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2759  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2760  * components.
2761  * The tuples to assign to are defined by index of the first tuple, and
2762  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2763  * The tuples to copy are defined by values of a DataArrayInt.
2764  * All components of selected tuples are copied.
2765  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2766  *              values to.
2767  *  \param [in] aBase - the array to copy values from.
2768  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2769  *  \throw If \a this is not allocated.
2770  *  \throw If \a aBase is NULL.
2771  *  \throw If \a aBase is not allocated.
2772  *  \throw If \a tuplesSelec is NULL.
2773  *  \throw If \a tuplesSelec is not allocated.
2774  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2775  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2776  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2777  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2778  *         \a aBase array.
2779  */
2780 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2781 {
2782   if(!aBase || !tuplesSelec)
2783     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2784   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2785   if(!a)
2786     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2787   checkAllocated();
2788   a->checkAllocated();
2789   tuplesSelec->checkAllocated();
2790   int nbOfComp=getNumberOfComponents();
2791   if(nbOfComp!=a->getNumberOfComponents())
2792     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2793   if(tuplesSelec->getNumberOfComponents()!=1)
2794     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2795   int thisNt=getNumberOfTuples();
2796   int aNt=a->getNumberOfTuples();
2797   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2798   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2799   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2800     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2801   const double *valsSrc=a->getConstPointer();
2802   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2803     {
2804       if(*tuple>=0 && *tuple<aNt)
2805         {
2806           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2807         }
2808       else
2809         {
2810           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2811           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2812           throw INTERP_KERNEL::Exception(oss.str().c_str());
2813         }
2814     }
2815 }
2816
2817 /*!
2818  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2819  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2820  * components.
2821  * The tuples to copy are defined by three values similar to parameters of
2822  * the Python function \c range(\c start,\c stop,\c step).
2823  * The tuples to assign to are defined by index of the first tuple, and
2824  * their number is defined by number of tuples to copy.
2825  * All components of selected tuples are copied.
2826  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2827  *              values to.
2828  *  \param [in] aBase - the array to copy values from.
2829  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2830  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2831  *              are located.
2832  *  \param [in] step - index increment to get index of the next tuple to copy.
2833  *  \throw If \a this is not allocated.
2834  *  \throw If \a aBase is NULL.
2835  *  \throw If \a aBase is not allocated.
2836  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2837  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2838  *  \throw If parameters specifying tuples to copy, do not give a
2839  *            non-empty range of increasing indices or indices are out of a valid range
2840  *            for the array \a aBase.
2841  */
2842 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2843 {
2844   if(!aBase)
2845     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2846   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2847   if(!a)
2848     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2849   checkAllocated();
2850   a->checkAllocated();
2851   int nbOfComp=getNumberOfComponents();
2852   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2853   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2854   if(nbOfComp!=a->getNumberOfComponents())
2855     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2856   int thisNt=getNumberOfTuples();
2857   int aNt=a->getNumberOfTuples();
2858   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2859   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2860     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2861   if(end2>aNt)
2862     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2863   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2864   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2865     {
2866       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2867     }
2868 }
2869
2870 /*!
2871  * Returns a value located at specified tuple and component.
2872  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2873  * parameters is checked. So this method is safe but expensive if used to go through
2874  * all values of \a this.
2875  *  \param [in] tupleId - index of tuple of interest.
2876  *  \param [in] compoId - index of component of interest.
2877  *  \return double - value located by \a tupleId and \a compoId.
2878  *  \throw If \a this is not allocated.
2879  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2880  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2881  */
2882 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2883 {
2884   checkAllocated();
2885   if(tupleId<0 || tupleId>=getNumberOfTuples())
2886     {
2887       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2888       throw INTERP_KERNEL::Exception(oss.str().c_str());
2889     }
2890   if(compoId<0 || compoId>=getNumberOfComponents())
2891     {
2892       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2893       throw INTERP_KERNEL::Exception(oss.str().c_str());
2894     }
2895   return _mem[tupleId*_info_on_compo.size()+compoId];
2896 }
2897
2898 /*!
2899  * Returns the first value of \a this. 
2900  *  \return double - the last value of \a this array.
2901  *  \throw If \a this is not allocated.
2902  *  \throw If \a this->getNumberOfComponents() != 1.
2903  *  \throw If \a this->getNumberOfTuples() < 1.
2904  */
2905 double DataArrayDouble::front() const
2906 {
2907   checkAllocated();
2908   if(getNumberOfComponents()!=1)
2909     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2910   int nbOfTuples=getNumberOfTuples();
2911   if(nbOfTuples<1)
2912     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2913   return *(getConstPointer());
2914 }
2915
2916 /*!
2917  * Returns the last value of \a this. 
2918  *  \return double - the last value of \a this array.
2919  *  \throw If \a this is not allocated.
2920  *  \throw If \a this->getNumberOfComponents() != 1.
2921  *  \throw If \a this->getNumberOfTuples() < 1.
2922  */
2923 double DataArrayDouble::back() const
2924 {
2925   checkAllocated();
2926   if(getNumberOfComponents()!=1)
2927     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2928   int nbOfTuples=getNumberOfTuples();
2929   if(nbOfTuples<1)
2930     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2931   return *(getConstPointer()+nbOfTuples-1);
2932 }
2933
2934 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2935 {
2936   if(newArray!=arrayToSet)
2937     {
2938       if(arrayToSet)
2939         arrayToSet->decrRef();
2940       arrayToSet=newArray;
2941       if(arrayToSet)
2942         arrayToSet->incrRef();
2943     }
2944 }
2945
2946 /*!
2947  * Sets a C array to be used as raw data of \a this. The previously set info
2948  *  of components is retained and re-sized. 
2949  * For more info see \ref MEDCouplingArraySteps1.
2950  *  \param [in] array - the C array to be used as raw data of \a this.
2951  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2952  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2953  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2954  *                     \c free(\c array ) will be called.
2955  *  \param [in] nbOfTuple - new number of tuples in \a this.
2956  *  \param [in] nbOfCompo - new number of components in \a this.
2957  */
2958 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2959 {
2960   _info_on_compo.resize(nbOfCompo);
2961   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2962   declareAsNew();
2963 }
2964
2965 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
2966 {
2967   _info_on_compo.resize(nbOfCompo);
2968   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2969   declareAsNew();
2970 }
2971
2972 /*!
2973  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2974  * is thrown.
2975  * \throw If zero is found in \a this array.
2976  */
2977 void DataArrayDouble::checkNoNullValues() const
2978 {
2979   const double *tmp=getConstPointer();
2980   std::size_t nbOfElems=getNbOfElems();
2981   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2982   if(where!=tmp+nbOfElems)
2983     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2984 }
2985
2986 /*!
2987  * Computes minimal and maximal value in each component. An output array is filled
2988  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2989  * enough memory before calling this method.
2990  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2991  *               It is filled as follows:<br>
2992  *               \a bounds[0] = \c min_of_component_0 <br>
2993  *               \a bounds[1] = \c max_of_component_0 <br>
2994  *               \a bounds[2] = \c min_of_component_1 <br>
2995  *               \a bounds[3] = \c max_of_component_1 <br>
2996  *               ...
2997  */
2998 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
2999 {
3000   checkAllocated();
3001   int dim=getNumberOfComponents();
3002   for (int idim=0; idim<dim; idim++)
3003     {
3004       bounds[idim*2]=std::numeric_limits<double>::max();
3005       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3006     } 
3007   const double *ptr=getConstPointer();
3008   int nbOfTuples=getNumberOfTuples();
3009   for(int i=0;i<nbOfTuples;i++)
3010     {
3011       for(int idim=0;idim<dim;idim++)
3012         {
3013           if(bounds[idim*2]>ptr[i*dim+idim])
3014             {
3015               bounds[idim*2]=ptr[i*dim+idim];
3016             }
3017           if(bounds[idim*2+1]<ptr[i*dim+idim])
3018             {
3019               bounds[idim*2+1]=ptr[i*dim+idim];
3020             }
3021         }
3022     }
3023 }
3024
3025 /*!
3026  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3027  * to store both the min and max per component of each tuples. 
3028  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3029  *
3030  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3031  *
3032  * \throw If \a this is not allocated yet.
3033  */
3034 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3035 {
3036   checkAllocated();
3037   const double *dataPtr=getConstPointer();
3038   int nbOfCompo=getNumberOfComponents();
3039   int nbTuples=getNumberOfTuples();
3040   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3041   bbox->alloc(nbTuples,2*nbOfCompo);
3042   double *bboxPtr=bbox->getPointer();
3043   for(int i=0;i<nbTuples;i++)
3044     {
3045       for(int j=0;j<nbOfCompo;j++)
3046         {
3047           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3048           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3049         }
3050     }
3051   return bbox.retn();
3052 }
3053
3054 /*!
3055  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3056  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3057  * 
3058  * \param [in] other a DataArrayDouble having same number of components than \a this.
3059  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3060  * \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.
3061  *             \a cI allows to extract information in \a c.
3062  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3063  *
3064  * \throw In case of:
3065  *  - \a this is not allocated
3066  *  - \a other is not allocated or null
3067  *  - \a this and \a other do not have the same number of components
3068  *  - if number of components of \a this is not in [1,2,3]
3069  *
3070  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3071  */
3072 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3073 {
3074   if(!other)
3075     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3076   checkAllocated();
3077   other->checkAllocated();
3078   int nbOfCompo=getNumberOfComponents();
3079   int otherNbOfCompo=other->getNumberOfComponents();
3080   if(nbOfCompo!=otherNbOfCompo)
3081     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3082   int nbOfTuplesOther=other->getNumberOfTuples();
3083   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3084   switch(nbOfCompo)
3085     {
3086     case 3:
3087       {
3088         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3089         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3090         break;
3091       }
3092     case 2:
3093       {
3094         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3095         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3096         break;
3097       }
3098     case 1:
3099       {
3100         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3101         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3102         break;
3103       }
3104     default:
3105       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3106     }
3107   c=cArr.retn(); cI=cIArr.retn();
3108 }
3109
3110 /*!
3111  * 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
3112  * around origin of 'radius' 1.
3113  * 
3114  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3115  */
3116 void DataArrayDouble::recenterForMaxPrecision(double eps)
3117 {
3118   checkAllocated();
3119   int dim=getNumberOfComponents();
3120   std::vector<double> bounds(2*dim);
3121   getMinMaxPerComponent(&bounds[0]);
3122   for(int i=0;i<dim;i++)
3123     {
3124       double delta=bounds[2*i+1]-bounds[2*i];
3125       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3126       if(delta>eps)
3127         applyLin(1./delta,-offset/delta,i);
3128       else
3129         applyLin(1.,-offset,i);
3130     }
3131 }
3132
3133 /*!
3134  * Returns the maximal value and its location within \a this one-dimensional array.
3135  *  \param [out] tupleId - index of the tuple holding the maximal value.
3136  *  \return double - the maximal value among all values of \a this array.
3137  *  \throw If \a this->getNumberOfComponents() != 1
3138  *  \throw If \a this->getNumberOfTuples() < 1
3139  */
3140 double DataArrayDouble::getMaxValue(int& tupleId) const
3141 {
3142   checkAllocated();
3143   if(getNumberOfComponents()!=1)
3144     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 !");
3145   int nbOfTuples=getNumberOfTuples();
3146   if(nbOfTuples<=0)
3147     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3148   const double *vals=getConstPointer();
3149   const double *loc=std::max_element(vals,vals+nbOfTuples);
3150   tupleId=(int)std::distance(vals,loc);
3151   return *loc;
3152 }
3153
3154 /*!
3155  * Returns the maximal value within \a this array that is allowed to have more than
3156  *  one component.
3157  *  \return double - the maximal value among all values of \a this array.
3158  *  \throw If \a this is not allocated.
3159  */
3160 double DataArrayDouble::getMaxValueInArray() const
3161 {
3162   checkAllocated();
3163   const double *loc=std::max_element(begin(),end());
3164   return *loc;
3165 }
3166
3167 /*!
3168  * Returns the maximal value and all its locations within \a this one-dimensional array.
3169  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3170  *               tuples holding the maximal value. The caller is to delete it using
3171  *               decrRef() as it is no more needed.
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::getMaxValue2(DataArrayInt*& tupleIds) const
3177 {
3178   int tmp;
3179   tupleIds=0;
3180   double ret=getMaxValue(tmp);
3181   tupleIds=getIdsInRange(ret,ret);
3182   return ret;
3183 }
3184
3185 /*!
3186  * Returns the minimal value and its location within \a this one-dimensional array.
3187  *  \param [out] tupleId - index of the tuple holding the minimal value.
3188  *  \return double - the minimal value among all values of \a this array.
3189  *  \throw If \a this->getNumberOfComponents() != 1
3190  *  \throw If \a this->getNumberOfTuples() < 1
3191  */
3192 double DataArrayDouble::getMinValue(int& tupleId) const
3193 {
3194   checkAllocated();
3195   if(getNumberOfComponents()!=1)
3196     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3197   int nbOfTuples=getNumberOfTuples();
3198   if(nbOfTuples<=0)
3199     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3200   const double *vals=getConstPointer();
3201   const double *loc=std::min_element(vals,vals+nbOfTuples);
3202   tupleId=(int)std::distance(vals,loc);
3203   return *loc;
3204 }
3205
3206 /*!
3207  * Returns the minimal value within \a this array that is allowed to have more than
3208  *  one component.
3209  *  \return double - the minimal value among all values of \a this array.
3210  *  \throw If \a this is not allocated.
3211  */
3212 double DataArrayDouble::getMinValueInArray() const
3213 {
3214   checkAllocated();
3215   const double *loc=std::min_element(begin(),end());
3216   return *loc;
3217 }
3218
3219 /*!
3220  * Returns the minimal value and all its locations within \a this one-dimensional array.
3221  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3222  *               tuples holding the minimal value. The caller is to delete it using
3223  *               decrRef() as it is no more needed.
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::getMinValue2(DataArrayInt*& tupleIds) const
3229 {
3230   int tmp;
3231   tupleIds=0;
3232   double ret=getMinValue(tmp);
3233   tupleIds=getIdsInRange(ret,ret);
3234   return ret;
3235 }
3236
3237 /*!
3238  * 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.
3239  * This method only works for single component array.
3240  *
3241  * \return a value in [ 0, \c this->getNumberOfTuples() )
3242  *
3243  * \throw If \a this is not allocated
3244  *
3245  */
3246 int DataArrayDouble::count(double value, double eps) const
3247 {
3248   int ret=0;
3249   checkAllocated();
3250   if(getNumberOfComponents()!=1)
3251     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3252   const double *vals=begin();
3253   int nbOfTuples=getNumberOfTuples();
3254   for(int i=0;i<nbOfTuples;i++,vals++)
3255     if(fabs(*vals-value)<=eps)
3256       ret++;
3257   return ret;
3258 }
3259
3260 /*!
3261  * Returns the average value of \a this one-dimensional array.
3262  *  \return double - the average value over all values of \a this array.
3263  *  \throw If \a this->getNumberOfComponents() != 1
3264  *  \throw If \a this->getNumberOfTuples() < 1
3265  */
3266 double DataArrayDouble::getAverageValue() const
3267 {
3268   if(getNumberOfComponents()!=1)
3269     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3270   int nbOfTuples=getNumberOfTuples();
3271   if(nbOfTuples<=0)
3272     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3273   const double *vals=getConstPointer();
3274   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3275   return ret/nbOfTuples;
3276 }
3277
3278 /*!
3279  * Returns the Euclidean norm of the vector defined by \a this array.
3280  *  \return double - the value of the Euclidean norm, i.e.
3281  *          the square root of the inner product of vector.
3282  *  \throw If \a this is not allocated.
3283  */
3284 double DataArrayDouble::norm2() const
3285 {
3286   checkAllocated();
3287   double ret=0.;
3288   std::size_t nbOfElems=getNbOfElems();
3289   const double *pt=getConstPointer();
3290   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3291     ret+=(*pt)*(*pt);
3292   return sqrt(ret);
3293 }
3294
3295 /*!
3296  * Returns the maximum norm of the vector defined by \a this array.
3297  *  \return double - the value of the maximum norm, i.e.
3298  *          the maximal absolute value among values of \a this array.
3299  *  \throw If \a this is not allocated.
3300  */
3301 double DataArrayDouble::normMax() const
3302 {
3303   checkAllocated();
3304   double ret=-1.;
3305   std::size_t nbOfElems=getNbOfElems();
3306   const double *pt=getConstPointer();
3307   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3308     {
3309       double val=std::abs(*pt);
3310       if(val>ret)
3311         ret=val;
3312     }
3313   return ret;
3314 }
3315
3316 /*!
3317  * Accumulates values of each component of \a this array.
3318  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3319  *         by the caller, that is filled by this method with sum value for each
3320  *         component.
3321  *  \throw If \a this is not allocated.
3322  */
3323 void DataArrayDouble::accumulate(double *res) const
3324 {
3325   checkAllocated();
3326   const double *ptr=getConstPointer();
3327   int nbTuple=getNumberOfTuples();
3328   int nbComps=getNumberOfComponents();
3329   std::fill(res,res+nbComps,0.);
3330   for(int i=0;i<nbTuple;i++)
3331     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3332 }
3333
3334 /*!
3335  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3336  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3337  *
3338  *
3339  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3340  * \a tupleEnd. If not an exception will be thrown.
3341  *
3342  * \param [in] tupleBg start pointer (included) of input external tuple
3343  * \param [in] tupleEnd end pointer (not included) of input external tuple
3344  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3345  * \return the min distance.
3346  * \sa MEDCouplingUMesh::distanceToPoint
3347  */
3348 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3349 {
3350   checkAllocated();
3351   int nbTuple=getNumberOfTuples();
3352   int nbComps=getNumberOfComponents();
3353   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3354     { 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()); }
3355   if(nbTuple==0)
3356     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3357   double ret0=std::numeric_limits<double>::max();
3358   tupleId=-1;
3359   const double *work=getConstPointer();
3360   for(int i=0;i<nbTuple;i++)
3361     {
3362       double val=0.;
3363       for(int j=0;j<nbComps;j++,work++) 
3364         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3365       if(val>=ret0)
3366         continue;
3367       else
3368         { ret0=val; tupleId=i; }
3369     }
3370   return sqrt(ret0);
3371 }
3372
3373 /*!
3374  * Accumulate values of the given component of \a this array.
3375  *  \param [in] compId - the index of the component of interest.
3376  *  \return double - a sum value of \a compId-th component.
3377  *  \throw If \a this is not allocated.
3378  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3379  *         not respected.
3380  */
3381 double DataArrayDouble::accumulate(int compId) const
3382 {
3383   checkAllocated();
3384   const double *ptr=getConstPointer();
3385   int nbTuple=getNumberOfTuples();
3386   int nbComps=getNumberOfComponents();
3387   if(compId<0 || compId>=nbComps)
3388     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3389   double ret=0.;
3390   for(int i=0;i<nbTuple;i++)
3391     ret+=ptr[i*nbComps+compId];
3392   return ret;
3393 }
3394
3395 /*!
3396  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3397  * The returned array will have same number of components than \a this and number of tuples equal to
3398  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3399  *
3400  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3401  * 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.
3402  *
3403  * \param [in] bgOfIndex - begin (included) of the input index array.
3404  * \param [in] endOfIndex - end (excluded) of the input index array.
3405  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3406  * 
3407  * \throw If bgOfIndex or end is NULL.
3408  * \throw If input index array is not ascendingly sorted.
3409  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3410  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3411  */
3412 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3413 {
3414   if(!bgOfIndex || !endOfIndex)
3415     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3416   checkAllocated();
3417   int nbCompo=getNumberOfComponents();
3418   int nbOfTuples=getNumberOfTuples();
3419   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3420   if(sz<1)
3421     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3422   sz--;
3423   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3424   const int *w=bgOfIndex;
3425   if(*w<0 || *w>=nbOfTuples)
3426     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3427   const double *srcPt=begin()+(*w)*nbCompo;
3428   double *tmp=ret->getPointer();
3429   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3430     {
3431       std::fill(tmp,tmp+nbCompo,0.);
3432       if(w[1]>=w[0])
3433         {
3434           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3435             {
3436               if(j>=0 && j<nbOfTuples)
3437                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3438               else
3439                 {
3440                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3441                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3442                 }
3443             }
3444         }
3445       else
3446         {
3447           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3448           throw INTERP_KERNEL::Exception(oss.str().c_str());
3449         }
3450     }
3451   ret->copyStringInfoFrom(*this);
3452   return ret.retn();
3453 }
3454
3455 /*!
3456  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3457  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3458  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3459  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3460  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3461  *          is to delete this array using decrRef() as it is no more needed. The array
3462  *          does not contain any textual info on components.
3463  *  \throw If \a this->getNumberOfComponents() != 2.
3464  */
3465 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3466 {
3467   checkAllocated();
3468   int nbOfComp=getNumberOfComponents();
3469   if(nbOfComp!=2)
3470     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3471   int nbOfTuple=getNumberOfTuples();
3472   DataArrayDouble *ret=DataArrayDouble::New();
3473   ret->alloc(nbOfTuple,2);
3474   double *w=ret->getPointer();
3475   const double *wIn=getConstPointer();
3476   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3477     {
3478       w[0]=wIn[0]*cos(wIn[1]);
3479       w[1]=wIn[0]*sin(wIn[1]);
3480     }
3481   return ret;
3482 }
3483
3484 /*!
3485  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3486  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3487  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3488  * the Cylindrical CS.
3489  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3490  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3491  *          on the third component is copied from \a this array. The caller
3492  *          is to delete this array using decrRef() as it is no more needed. 
3493  *  \throw If \a this->getNumberOfComponents() != 3.
3494  */
3495 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3496 {
3497   checkAllocated();
3498   int nbOfComp=getNumberOfComponents();
3499   if(nbOfComp!=3)
3500     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3501   int nbOfTuple=getNumberOfTuples();
3502   DataArrayDouble *ret=DataArrayDouble::New();
3503   ret->alloc(getNumberOfTuples(),3);
3504   double *w=ret->getPointer();
3505   const double *wIn=getConstPointer();
3506   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3507     {
3508       w[0]=wIn[0]*cos(wIn[1]);
3509       w[1]=wIn[0]*sin(wIn[1]);
3510       w[2]=wIn[2];
3511     }
3512   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3513   return ret;
3514 }
3515
3516 /*!
3517  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3518  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3519  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3520  * point in the Cylindrical CS.
3521  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3522  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3523  *          on the third component is copied from \a this array. The caller
3524  *          is to delete this array using decrRef() as it is no more needed.
3525  *  \throw If \a this->getNumberOfComponents() != 3.
3526  */
3527 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3528 {
3529   checkAllocated();
3530   int nbOfComp=getNumberOfComponents();
3531   if(nbOfComp!=3)
3532     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3533   int nbOfTuple=getNumberOfTuples();
3534   DataArrayDouble *ret=DataArrayDouble::New();
3535   ret->alloc(getNumberOfTuples(),3);
3536   double *w=ret->getPointer();
3537   const double *wIn=getConstPointer();
3538   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3539     {
3540       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3541       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3542       w[2]=wIn[0]*cos(wIn[1]);
3543     }
3544   return ret;
3545 }
3546
3547 /*!
3548  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3549  * array contating 6 components.
3550  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3551  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3552  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3553  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3554  *  \throw If \a this->getNumberOfComponents() != 6.
3555  */
3556 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3557 {
3558   checkAllocated();
3559   int nbOfComp=getNumberOfComponents();
3560   if(nbOfComp!=6)
3561     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3562   DataArrayDouble *ret=DataArrayDouble::New();
3563   int nbOfTuple=getNumberOfTuples();
3564   ret->alloc(nbOfTuple,1);
3565   const double *src=getConstPointer();
3566   double *dest=ret->getPointer();
3567   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3568     *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];
3569   return ret;
3570 }
3571
3572 /*!
3573  * Computes the determinant of every square matrix defined by the tuple of \a this
3574  * array, which contains either 4, 6 or 9 components. The case of 6 components
3575  * corresponds to that of the upper triangular matrix.
3576  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3577  *          is the determinant of matrix of the corresponding tuple of \a this array.
3578  *          The caller is to delete this result array using decrRef() as it is no more
3579  *          needed. 
3580  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3581  */
3582 DataArrayDouble *DataArrayDouble::determinant() const
3583 {
3584   checkAllocated();
3585   DataArrayDouble *ret=DataArrayDouble::New();
3586   int nbOfTuple=getNumberOfTuples();
3587   ret->alloc(nbOfTuple,1);
3588   const double *src=getConstPointer();
3589   double *dest=ret->getPointer();
3590   switch(getNumberOfComponents())
3591     {
3592     case 6:
3593       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3594         *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];
3595       return ret;
3596     case 4:
3597       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3598         *dest=src[0]*src[3]-src[1]*src[2];
3599       return ret;
3600     case 9:
3601       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3602         *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];
3603       return ret;
3604     default:
3605       ret->decrRef();
3606       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3607     }
3608 }
3609
3610 /*!
3611  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3612  * \a this array, which contains 6 components.
3613  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3614  *          components, whose each tuple contains the eigenvalues of the matrix of
3615  *          corresponding tuple of \a this array. 
3616  *          The caller is to delete this result array using decrRef() as it is no more
3617  *          needed. 
3618  *  \throw If \a this->getNumberOfComponents() != 6.
3619  */
3620 DataArrayDouble *DataArrayDouble::eigenValues() const
3621 {
3622   checkAllocated();
3623   int nbOfComp=getNumberOfComponents();
3624   if(nbOfComp!=6)
3625     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3626   DataArrayDouble *ret=DataArrayDouble::New();
3627   int nbOfTuple=getNumberOfTuples();
3628   ret->alloc(nbOfTuple,3);
3629   const double *src=getConstPointer();
3630   double *dest=ret->getPointer();
3631   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3632     INTERP_KERNEL::computeEigenValues6(src,dest);
3633   return ret;
3634 }
3635
3636 /*!
3637  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3638  * \a this array, which contains 6 components.
3639  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3640  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3641  *          corresponding tuple of \a this array.
3642  *          The caller is to delete this result array using decrRef() as it is no more
3643  *          needed.
3644  *  \throw If \a this->getNumberOfComponents() != 6.
3645  */
3646 DataArrayDouble *DataArrayDouble::eigenVectors() const
3647 {
3648   checkAllocated();
3649   int nbOfComp=getNumberOfComponents();
3650   if(nbOfComp!=6)
3651     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3652   DataArrayDouble *ret=DataArrayDouble::New();
3653   int nbOfTuple=getNumberOfTuples();
3654   ret->alloc(nbOfTuple,9);
3655   const double *src=getConstPointer();
3656   double *dest=ret->getPointer();
3657   for(int i=0;i<nbOfTuple;i++,src+=6)
3658     {
3659       double tmp[3];
3660       INTERP_KERNEL::computeEigenValues6(src,tmp);
3661       for(int j=0;j<3;j++,dest+=3)
3662         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3663     }
3664   return ret;
3665 }
3666
3667 /*!
3668  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3669  * array, which contains either 4, 6 or 9 components. The case of 6 components
3670  * corresponds to that of the upper triangular matrix.
3671  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3672  *          same number of components as \a this one, whose each tuple is the inverse
3673  *          matrix of the matrix of corresponding tuple of \a this array. 
3674  *          The caller is to delete this result array using decrRef() as it is no more
3675  *          needed. 
3676  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3677  */
3678 DataArrayDouble *DataArrayDouble::inverse() const
3679 {
3680   checkAllocated();
3681   int nbOfComp=getNumberOfComponents();
3682   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3683     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3684   DataArrayDouble *ret=DataArrayDouble::New();
3685   int nbOfTuple=getNumberOfTuples();
3686   ret->alloc(nbOfTuple,nbOfComp);
3687   const double *src=getConstPointer();
3688   double *dest=ret->getPointer();
3689 if(nbOfComp==6)
3690     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3691       {
3692         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];
3693         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3694         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3695         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3696         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3697         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3698         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3699       }
3700   else if(nbOfComp==4)
3701     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3702       {
3703         double det=src[0]*src[3]-src[1]*src[2];
3704         dest[0]=src[3]/det;
3705         dest[1]=-src[1]/det;
3706         dest[2]=-src[2]/det;
3707         dest[3]=src[0]/det;
3708       }
3709   else
3710     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3711       {
3712         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];
3713         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3714         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3715         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3716         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3717         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3718         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3719         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3720         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3721         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3722       }
3723   return ret;
3724 }
3725
3726 /*!
3727  * Computes the trace of every matrix defined by the tuple of \a this
3728  * array, which contains either 4, 6 or 9 components. The case of 6 components
3729  * corresponds to that of the upper triangular matrix.
3730  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3731  *          1 component, whose each tuple is the trace of
3732  *          the matrix of corresponding tuple of \a this array. 
3733  *          The caller is to delete this result array using decrRef() as it is no more
3734  *          needed. 
3735  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3736  */
3737 DataArrayDouble *DataArrayDouble::trace() const
3738 {
3739   checkAllocated();
3740   int nbOfComp=getNumberOfComponents();
3741   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3742     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3743   DataArrayDouble *ret=DataArrayDouble::New();
3744   int nbOfTuple=getNumberOfTuples();
3745   ret->alloc(nbOfTuple,1);
3746   const double *src=getConstPointer();
3747   double *dest=ret->getPointer();
3748   if(nbOfComp==6)
3749     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3750       *dest=src[0]+src[1]+src[2];
3751   else if(nbOfComp==4)
3752     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3753       *dest=src[0]+src[3];
3754   else
3755     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3756       *dest=src[0]+src[4]+src[8];
3757   return ret;
3758 }
3759
3760 /*!
3761  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3762  * \a this array, which contains 6 components.
3763  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3764  *          same number of components and tuples as \a this array.
3765  *          The caller is to delete this result array using decrRef() as it is no more
3766  *          needed.
3767  *  \throw If \a this->getNumberOfComponents() != 6.
3768  */
3769 DataArrayDouble *DataArrayDouble::deviator() const
3770 {
3771   checkAllocated();
3772   int nbOfComp=getNumberOfComponents();
3773   if(nbOfComp!=6)
3774     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3775   DataArrayDouble *ret=DataArrayDouble::New();
3776   int nbOfTuple=getNumberOfTuples();
3777   ret->alloc(nbOfTuple,6);
3778   const double *src=getConstPointer();
3779   double *dest=ret->getPointer();
3780   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3781     {
3782       double tr=(src[0]+src[1]+src[2])/3.;
3783       dest[0]=src[0]-tr;
3784       dest[1]=src[1]-tr;
3785       dest[2]=src[2]-tr;
3786       dest[3]=src[3];
3787       dest[4]=src[4];
3788       dest[5]=src[5];
3789     }
3790   return ret;
3791 }
3792
3793 /*!
3794  * Computes the magnitude of every vector defined by the tuple of
3795  * \a this array.
3796  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3797  *          same number of tuples as \a this array and one component.
3798  *          The caller is to delete this result array using decrRef() as it is no more
3799  *          needed.
3800  *  \throw If \a this is not allocated.
3801  */
3802 DataArrayDouble *DataArrayDouble::magnitude() const
3803 {
3804   checkAllocated();
3805   int nbOfComp=getNumberOfComponents();
3806   DataArrayDouble *ret=DataArrayDouble::New();
3807   int nbOfTuple=getNumberOfTuples();
3808   ret->alloc(nbOfTuple,1);
3809   const double *src=getConstPointer();
3810   double *dest=ret->getPointer();
3811   for(int i=0;i<nbOfTuple;i++,dest++)
3812     {
3813       double sum=0.;
3814       for(int j=0;j<nbOfComp;j++,src++)
3815         sum+=(*src)*(*src);
3816       *dest=sqrt(sum);
3817     }
3818   return ret;
3819 }
3820
3821 /*!
3822  * Computes for each tuple the sum of number of components values in the tuple and return it.
3823  * 
3824  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3825  *          same number of tuples as \a this array and one component.
3826  *          The caller is to delete this result array using decrRef() as it is no more
3827  *          needed.
3828  *  \throw If \a this is not allocated.
3829  */
3830 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3831 {
3832   checkAllocated();
3833   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3834   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3835   ret->alloc(nbOfTuple,1);
3836   const double *src(getConstPointer());
3837   double *dest(ret->getPointer());
3838   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3839     *dest=std::accumulate(src,src+nbOfComp,0.);
3840   return ret.retn();
3841 }
3842
3843 /*!
3844  * Computes the maximal value within every tuple of \a this array.
3845  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3846  *          same number of tuples as \a this array and one component.
3847  *          The caller is to delete this result array using decrRef() as it is no more
3848  *          needed.
3849  *  \throw If \a this is not allocated.
3850  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3851  */
3852 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3853 {
3854   checkAllocated();
3855   int nbOfComp=getNumberOfComponents();
3856   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3857   int nbOfTuple=getNumberOfTuples();
3858   ret->alloc(nbOfTuple,1);
3859   const double *src=getConstPointer();
3860   double *dest=ret->getPointer();
3861   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3862     *dest=*std::max_element(src,src+nbOfComp);
3863   return ret.retn();
3864 }
3865
3866 /*!
3867  * Computes the maximal value within every tuple of \a this array and it returns the first component
3868  * id for each tuple that corresponds to the maximal value within the tuple.
3869  * 
3870  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3871  *          same number of tuples and only one component.
3872  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3873  *          same number of tuples as \a this array and one component.
3874  *          The caller is to delete this result array using decrRef() as it is no more
3875  *          needed.
3876  *  \throw If \a this is not allocated.
3877  *  \sa DataArrayDouble::maxPerTuple
3878  */
3879 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3880 {
3881   checkAllocated();
3882   int nbOfComp=getNumberOfComponents();
3883   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3884   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3885   int nbOfTuple=getNumberOfTuples();
3886   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3887   const double *src=getConstPointer();
3888   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3889   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3890     {
3891       const double *loc=std::max_element(src,src+nbOfComp);
3892       *dest=*loc;
3893       *dest1=(int)std::distance(src,loc);
3894     }
3895   compoIdOfMaxPerTuple=ret1.retn();
3896   return ret0.retn();
3897 }
3898
3899 /*!
3900  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3901  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3902  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3903  * \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)
3904  *
3905  * \warning use this method with care because it can leads to big amount of consumed memory !
3906  * 
3907  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3908  *
3909  * \throw If \a this is not allocated.
3910  *
3911  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3912  */
3913 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3914 {
3915   checkAllocated();
3916   int nbOfComp=getNumberOfComponents();
3917   int nbOfTuples=getNumberOfTuples();
3918   const double *inData=getConstPointer();
3919   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3920   ret->alloc(nbOfTuples*nbOfTuples,1);
3921   double *outData=ret->getPointer();
3922   for(int i=0;i<nbOfTuples;i++)
3923     {
3924       outData[i*nbOfTuples+i]=0.;
3925       for(int j=i+1;j<nbOfTuples;j++)
3926         {
3927           double dist=0.;
3928           for(int k=0;k<nbOfComp;k++)
3929             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3930           dist=sqrt(dist);
3931           outData[i*nbOfTuples+j]=dist;
3932           outData[j*nbOfTuples+i]=dist;
3933         }
3934     }
3935   return ret.retn();
3936 }
3937
3938 /*!
3939  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3940  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3941  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3942  * \n Output rectangular matrix is sorted along rows.
3943  * \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)
3944  *
3945  * \warning use this method with care because it can leads to big amount of consumed memory !
3946  * 
3947  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3948  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3949  *
3950  * \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.
3951  *
3952  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3953  */
3954 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
3955 {
3956   if(!other)
3957     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3958   checkAllocated();
3959   other->checkAllocated();
3960   int nbOfComp=getNumberOfComponents();
3961   int otherNbOfComp=other->getNumberOfComponents();
3962   if(nbOfComp!=otherNbOfComp)
3963     {
3964       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3965       throw INTERP_KERNEL::Exception(oss.str().c_str());
3966     }
3967   int nbOfTuples=getNumberOfTuples();
3968   int otherNbOfTuples=other->getNumberOfTuples();
3969   const double *inData=getConstPointer();
3970   const double *inDataOther=other->getConstPointer();
3971   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3972   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3973   double *outData=ret->getPointer();
3974   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3975     {
3976       for(int j=0;j<nbOfTuples;j++)
3977         {
3978           double dist=0.;
3979           for(int k=0;k<nbOfComp;k++)
3980             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3981           dist=sqrt(dist);
3982           outData[i*nbOfTuples+j]=dist;
3983         }
3984     }
3985   return ret.retn();
3986 }
3987
3988 /*!
3989  * Sorts value within every tuple of \a this array.
3990  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3991  *              in descending order.
3992  *  \throw If \a this is not allocated.
3993  */
3994 void DataArrayDouble::sortPerTuple(bool asc)
3995 {
3996   checkAllocated();
3997   double *pt=getPointer();
3998   int nbOfTuple=getNumberOfTuples();
3999   int nbOfComp=getNumberOfComponents();
4000   if(asc)
4001     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4002       std::sort(pt,pt+nbOfComp);
4003   else
4004     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4005       std::sort(pt,pt+nbOfComp,std::greater<double>());
4006   declareAsNew();
4007 }
4008
4009 /*!
4010  * Converts every value of \a this array to its absolute value.
4011  *  \throw If \a this is not allocated.
4012  */
4013 void DataArrayDouble::abs()
4014 {
4015   checkAllocated();
4016   double *ptr=getPointer();
4017   std::size_t nbOfElems=getNbOfElems();
4018   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4019   declareAsNew();
4020 }
4021
4022 /*!
4023  * Apply a liner function to a given component of \a this array, so that
4024  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4025  *  \param [in] a - the first coefficient of the function.
4026  *  \param [in] b - the second coefficient of the function.
4027  *  \param [in] compoId - the index of component to modify.
4028  *  \throw If \a this is not allocated.
4029  */
4030 void DataArrayDouble::applyLin(double a, double b, int compoId)
4031 {
4032   checkAllocated();
4033   double *ptr=getPointer()+compoId;
4034   int nbOfComp=getNumberOfComponents();
4035   int nbOfTuple=getNumberOfTuples();
4036   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4037     *ptr=a*(*ptr)+b;
4038   declareAsNew();
4039 }
4040
4041 /*!
4042  * Apply a liner function to all elements of \a this array, so that
4043  * an element _x_ becomes \f$ a * x + b \f$.
4044  *  \param [in] a - the first coefficient of the function.
4045  *  \param [in] b - the second coefficient of the function.
4046  *  \throw If \a this is not allocated.
4047  */
4048 void DataArrayDouble::applyLin(double a, double b)
4049 {
4050   checkAllocated();
4051   double *ptr=getPointer();
4052   std::size_t nbOfElems=getNbOfElems();
4053   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4054     *ptr=a*(*ptr)+b;
4055   declareAsNew();
4056 }
4057
4058 /*!
4059  * Modify all elements of \a this array, so that
4060  * an element _x_ becomes \f$ numerator / x \f$.
4061  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4062  *           array, all elements processed before detection of the zero element remain
4063  *           modified.
4064  *  \param [in] numerator - the numerator used to modify array elements.
4065  *  \throw If \a this is not allocated.
4066  *  \throw If there is an element equal to 0.0 in \a this array.
4067  */
4068 void DataArrayDouble::applyInv(double numerator)
4069 {
4070   checkAllocated();
4071   double *ptr=getPointer();
4072   std::size_t nbOfElems=getNbOfElems();
4073   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4074     {
4075       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4076         {
4077           *ptr=numerator/(*ptr);
4078         }
4079       else
4080         {
4081           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4082           oss << " !";
4083           throw INTERP_KERNEL::Exception(oss.str().c_str());
4084         }
4085     }
4086   declareAsNew();
4087 }
4088
4089 /*!
4090  * Returns a full copy of \a this array except that sign of all elements is reversed.
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  */
4097 DataArrayDouble *DataArrayDouble::negate() const
4098 {
4099   checkAllocated();
4100   DataArrayDouble *newArr=DataArrayDouble::New();
4101   int nbOfTuples=getNumberOfTuples();
4102   int nbOfComp=getNumberOfComponents();
4103   newArr->alloc(nbOfTuples,nbOfComp);
4104   const double *cptr=getConstPointer();
4105   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4106   newArr->copyStringInfoFrom(*this);
4107   return newArr;
4108 }
4109
4110 /*!
4111  * Modify all elements of \a this array, so that
4112  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4113  * all values in \a this have to be >= 0 if val is \b not integer.
4114  *  \param [in] val - the value used to apply pow on all array elements.
4115  *  \throw If \a this is not allocated.
4116  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4117  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4118  *           modified.
4119  */
4120 void DataArrayDouble::applyPow(double val)
4121 {
4122   checkAllocated();
4123   double *ptr=getPointer();
4124   std::size_t nbOfElems=getNbOfElems();
4125   int val2=(int)val;
4126   bool isInt=((double)val2)==val;
4127   if(!isInt)
4128     {
4129       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4130         {
4131           if(*ptr>=0)
4132             *ptr=pow(*ptr,val);
4133           else
4134             {
4135               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4136               throw INTERP_KERNEL::Exception(oss.str().c_str());
4137             }
4138         }
4139     }
4140   else
4141     {
4142       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4143         *ptr=pow(*ptr,val2);
4144     }
4145   declareAsNew();
4146 }
4147
4148 /*!
4149  * Modify all elements of \a this array, so that
4150  * an element _x_ becomes \f$ val ^ x \f$.
4151  *  \param [in] val - the value used to apply pow on all array elements.
4152  *  \throw If \a this is not allocated.
4153  *  \throw If \a val < 0.
4154  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4155  *           array, all elements processed before detection of the zero element remain
4156  *           modified.
4157  */
4158 void DataArrayDouble::applyRPow(double val)
4159 {
4160   checkAllocated();
4161   if(val<0.)
4162     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4163   double *ptr=getPointer();
4164   std::size_t nbOfElems=getNbOfElems();
4165   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4166     *ptr=pow(val,*ptr);
4167   declareAsNew();
4168 }
4169
4170 /*!
4171  * Returns a new DataArrayDouble created from \a this one by applying \a
4172  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4173  * For more info see \ref MEDCouplingArrayApplyFunc
4174  *  \param [in] nbOfComp - number of components in the result array.
4175  *  \param [in] func - the \a FunctionToEvaluate declared as 
4176  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4177  *              where \a pos points to the first component of a tuple of \a this array
4178  *              and \a res points to the first component of a tuple of the result array.
4179  *              Note that length (number of components) of \a pos can differ from
4180  *              that of \a res.
4181  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4182  *          same number of tuples as \a this array.
4183  *          The caller is to delete this result array using decrRef() as it is no more
4184  *          needed.
4185  *  \throw If \a this is not allocated.
4186  *  \throw If \a func returns \a false.
4187  */
4188 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4189 {
4190   checkAllocated();
4191   DataArrayDouble *newArr=DataArrayDouble::New();
4192   int nbOfTuples=getNumberOfTuples();
4193   int oldNbOfComp=getNumberOfComponents();
4194   newArr->alloc(nbOfTuples,nbOfComp);
4195   const double *ptr=getConstPointer();
4196   double *ptrToFill=newArr->getPointer();
4197   for(int i=0;i<nbOfTuples;i++)
4198     {
4199       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4200         {
4201           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4202           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4203           oss << ") : Evaluation of function failed !";
4204           newArr->decrRef();
4205           throw INTERP_KERNEL::Exception(oss.str().c_str());
4206         }
4207     }
4208   return newArr;
4209 }
4210
4211 /*!
4212  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4213  * tuple of \a this array. Textual data is not copied.
4214  * For more info see \ref MEDCouplingArrayApplyFunc1.
4215  *  \param [in] nbOfComp - number of components in the result array.
4216  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4217  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4218  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4219  *          same number of tuples as \a this array and \a nbOfComp components.
4220  *          The caller is to delete this result array using decrRef() as it is no more
4221  *          needed.
4222  *  \throw If \a this is not allocated.
4223  *  \throw If computing \a func fails.
4224  */
4225 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const
4226 {
4227   checkAllocated();
4228   INTERP_KERNEL::ExprParser expr(func);
4229   expr.parse();
4230   std::set<std::string> vars;
4231   expr.getTrueSetOfVars(vars);
4232   int oldNbOfComp=getNumberOfComponents();
4233   if((int)vars.size()>oldNbOfComp)
4234     {
4235       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4236       oss << vars.size() << " variables : ";
4237       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4238       throw INTERP_KERNEL::Exception(oss.str().c_str());
4239     }
4240   std::vector<std::string> varsV(vars.begin(),vars.end());
4241   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4242   //
4243   DataArrayDouble *newArr=DataArrayDouble::New();
4244   int nbOfTuples=getNumberOfTuples();
4245   newArr->alloc(nbOfTuples,nbOfComp);
4246   const double *ptr=getConstPointer();
4247   double *ptrToFill=newArr->getPointer();
4248   for(int i=0;i<nbOfTuples;i++)
4249     {
4250       try
4251         {
4252           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4253         }
4254       catch(INTERP_KERNEL::Exception& e)
4255         {
4256           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4257           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4258           oss << ") : Evaluation of function failed !" << e.what();
4259           newArr->decrRef();
4260           throw INTERP_KERNEL::Exception(oss.str().c_str());
4261         }
4262     }
4263   return newArr;
4264 }
4265
4266 /*!
4267  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4268  * tuple of \a this array. Textual data is not copied.
4269  * For more info see \ref MEDCouplingArrayApplyFunc0.
4270  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4271  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4272  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4273  *          same number of tuples and components as \a this array.
4274  *          The caller is to delete this result array using decrRef() as it is no more
4275  *          needed.
4276  *  \throw If \a this is not allocated.
4277  *  \throw If computing \a func fails.
4278  */
4279 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const
4280 {
4281   checkAllocated();
4282   INTERP_KERNEL::ExprParser expr(func);
4283   expr.parse();
4284   expr.prepareExprEvaluationVec();
4285   //
4286   DataArrayDouble *newArr=DataArrayDouble::New();
4287   int nbOfTuples=getNumberOfTuples();
4288   int nbOfComp=getNumberOfComponents();
4289   newArr->alloc(nbOfTuples,nbOfComp);
4290   const double *ptr=getConstPointer();
4291   double *ptrToFill=newArr->getPointer();
4292   for(int i=0;i<nbOfTuples;i++)
4293     {
4294       try
4295         {
4296           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4297         }
4298       catch(INTERP_KERNEL::Exception& e)
4299         {
4300           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4301           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4302           oss << ") : Evaluation of function failed ! " << e.what();
4303           newArr->decrRef();
4304           throw INTERP_KERNEL::Exception(oss.str().c_str());
4305         }
4306     }
4307   return newArr;
4308 }
4309
4310 /*!
4311  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4312  * tuple of \a this array. Textual data is not copied.
4313  * For more info see \ref MEDCouplingArrayApplyFunc2.
4314  *  \param [in] nbOfComp - number of components in the result array.
4315  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4316  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4317  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4318  *          same number of tuples as \a this array.
4319  *          The caller is to delete this result array using decrRef() as it is no more
4320  *          needed.
4321  *  \throw If \a this is not allocated.
4322  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4323  *  \throw If computing \a func fails.
4324  */
4325 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const
4326 {
4327   checkAllocated();
4328   INTERP_KERNEL::ExprParser expr(func);
4329   expr.parse();
4330   std::set<std::string> vars;
4331   expr.getTrueSetOfVars(vars);
4332   int oldNbOfComp=getNumberOfComponents();
4333   if((int)vars.size()>oldNbOfComp)
4334     {
4335       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4336       oss << vars.size() << " variables : ";
4337       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4338       throw INTERP_KERNEL::Exception(oss.str().c_str());
4339     }
4340   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4341   //
4342   DataArrayDouble *newArr=DataArrayDouble::New();
4343   int nbOfTuples=getNumberOfTuples();
4344   newArr->alloc(nbOfTuples,nbOfComp);
4345   const double *ptr=getConstPointer();
4346   double *ptrToFill=newArr->getPointer();
4347   for(int i=0;i<nbOfTuples;i++)
4348     {
4349       try
4350         {
4351           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4352         }
4353       catch(INTERP_KERNEL::Exception& e)
4354         {
4355           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4356           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4357           oss << ") : Evaluation of function failed !" << e.what();
4358           newArr->decrRef();
4359           throw INTERP_KERNEL::Exception(oss.str().c_str());
4360         }
4361     }
4362   return newArr;
4363 }
4364
4365 /*!
4366  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4367  * tuple of \a this array. Textual data is not copied.
4368  * For more info see \ref MEDCouplingArrayApplyFunc3.
4369  *  \param [in] nbOfComp - number of components in the result array.
4370  *  \param [in] varsOrder - sequence of vars defining their order.
4371  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4372  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4373  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4374  *          same number of tuples as \a this array.
4375  *          The caller is to delete this result array using decrRef() as it is no more
4376  *          needed.
4377  *  \throw If \a this is not allocated.
4378  *  \throw If \a func contains vars not in \a varsOrder.
4379  *  \throw If computing \a func fails.
4380  */
4381 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
4382 {
4383   checkAllocated();
4384   INTERP_KERNEL::ExprParser expr(func);
4385   expr.parse();
4386   std::set<std::string> vars;
4387   expr.getTrueSetOfVars(vars);
4388   int oldNbOfComp=getNumberOfComponents();
4389   if((int)vars.size()>oldNbOfComp)
4390     {
4391       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4392       oss << vars.size() << " variables : ";
4393       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4394       throw INTERP_KERNEL::Exception(oss.str().c_str());
4395     }
4396   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4397   //
4398   DataArrayDouble *newArr=DataArrayDouble::New();
4399   int nbOfTuples=getNumberOfTuples();
4400   newArr->alloc(nbOfTuples,nbOfComp);
4401   const double *ptr=getConstPointer();
4402   double *ptrToFill=newArr->getPointer();
4403   for(int i=0;i<nbOfTuples;i++)
4404     {
4405       try
4406         {
4407           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4408         }
4409       catch(INTERP_KERNEL::Exception& e)
4410         {
4411           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4412           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4413           oss << ") : Evaluation of function failed !" << e.what();
4414           newArr->decrRef();
4415           throw INTERP_KERNEL::Exception(oss.str().c_str());
4416         }
4417     }
4418   return newArr;
4419 }
4420
4421 void DataArrayDouble::applyFuncFast32(const char *func)
4422 {
4423   checkAllocated();
4424   INTERP_KERNEL::ExprParser expr(func);
4425   expr.parse();
4426   char *funcStr=expr.compileX86();
4427   MYFUNCPTR funcPtr;
4428   *((void **)&funcPtr)=funcStr;//he he...
4429   //
4430   double *ptr=getPointer();
4431   int nbOfComp=getNumberOfComponents();
4432   int nbOfTuples=getNumberOfTuples();
4433   int nbOfElems=nbOfTuples*nbOfComp;
4434   for(int i=0;i<nbOfElems;i++,ptr++)
4435     *ptr=funcPtr(*ptr);
4436   declareAsNew();
4437 }
4438
4439 void DataArrayDouble::applyFuncFast64(const char *func)
4440 {
4441   checkAllocated();
4442   INTERP_KERNEL::ExprParser expr(func);
4443   expr.parse();
4444   char *funcStr=expr.compileX86_64();
4445   MYFUNCPTR funcPtr;
4446   *((void **)&funcPtr)=funcStr;//he he...
4447   //
4448   double *ptr=getPointer();
4449   int nbOfComp=getNumberOfComponents();
4450   int nbOfTuples=getNumberOfTuples();
4451   int nbOfElems=nbOfTuples*nbOfComp;
4452   for(int i=0;i<nbOfElems;i++,ptr++)
4453     *ptr=funcPtr(*ptr);
4454   declareAsNew();
4455 }
4456
4457 DataArrayDoubleIterator *DataArrayDouble::iterator()
4458 {
4459   return new DataArrayDoubleIterator(this);
4460 }
4461
4462 /*!
4463  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4464  * array whose values are within a given range. Textual data is not copied.
4465  *  \param [in] vmin - a lowest acceptable value (included).
4466  *  \param [in] vmax - a greatest acceptable value (included).
4467  *  \return DataArrayInt * - the new instance of DataArrayInt.
4468  *          The caller is to delete this result array using decrRef() as it is no more
4469  *          needed.
4470  *  \throw If \a this->getNumberOfComponents() != 1.
4471  *
4472  *  \sa DataArrayDouble::getIdsNotInRange
4473  *
4474  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4475  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4476  */
4477 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4478 {
4479   checkAllocated();
4480   if(getNumberOfComponents()!=1)
4481     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4482   const double *cptr(begin());
4483   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4484   int nbOfTuples(getNumberOfTuples());
4485   for(int i=0;i<nbOfTuples;i++,cptr++)
4486     if(*cptr>=vmin && *cptr<=vmax)
4487       ret->pushBackSilent(i);
4488   return ret.retn();
4489 }
4490
4491 /*!
4492  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4493  * array whose values are not within a given range. Textual data is not copied.
4494  *  \param [in] vmin - a lowest not acceptable value (excluded).
4495  *  \param [in] vmax - a greatest not acceptable value (excluded).
4496  *  \return DataArrayInt * - the new instance of DataArrayInt.
4497  *          The caller is to delete this result array using decrRef() as it is no more
4498  *          needed.
4499  *  \throw If \a this->getNumberOfComponents() != 1.
4500  *
4501  *  \sa DataArrayDouble::getIdsInRange
4502  */
4503 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4504 {
4505   checkAllocated();
4506   if(getNumberOfComponents()!=1)
4507     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4508   const double *cptr(begin());
4509   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4510   int nbOfTuples(getNumberOfTuples());
4511   for(int i=0;i<nbOfTuples;i++,cptr++)
4512     if(*cptr<vmin || *cptr>vmax)
4513       ret->pushBackSilent(i);
4514   return ret.retn();
4515 }
4516
4517 /*!
4518  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4519  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4520  * the number of component in the result array is same as that of each of given arrays.
4521  * Info on components is copied from the first of the given arrays. Number of components
4522  * in the given arrays must be  the same.
4523  *  \param [in] a1 - an array to include in the result array.
4524  *  \param [in] a2 - another array to include in the result array.
4525  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4526  *          The caller is to delete this result array using decrRef() as it is no more
4527  *          needed.
4528  *  \throw If both \a a1 and \a a2 are NULL.
4529  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4530  */
4531 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4532 {
4533   std::vector<const DataArrayDouble *> tmp(2);
4534   tmp[0]=a1; tmp[1]=a2;
4535   return Aggregate(tmp);
4536 }
4537
4538 /*!
4539  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4540  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4541  * the number of component in the result array is same as that of each of given arrays.
4542  * Info on components is copied from the first of the given arrays. Number of components
4543  * in the given arrays must be  the same.
4544  *  \param [in] arr - a sequence of arrays to include in the result array.
4545  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4546  *          The caller is to delete this result array using decrRef() as it is no more
4547  *          needed.
4548  *  \throw If all arrays within \a arr are NULL.
4549  *  \throw If getNumberOfComponents() of arrays within \a arr.
4550  */
4551 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4552 {
4553   std::vector<const DataArrayDouble *> a;
4554   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4555     if(*it4)
4556       a.push_back(*it4);
4557   if(a.empty())
4558     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4559   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4560   int nbOfComp=(*it)->getNumberOfComponents();
4561   int nbt=(*it++)->getNumberOfTuples();
4562   for(int i=1;it!=a.end();it++,i++)
4563     {
4564       if((*it)->getNumberOfComponents()!=nbOfComp)
4565         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4566       nbt+=(*it)->getNumberOfTuples();
4567     }
4568   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4569   ret->alloc(nbt,nbOfComp);
4570   double *pt=ret->getPointer();
4571   for(it=a.begin();it!=a.end();it++)
4572     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4573   ret->copyStringInfoFrom(*(a[0]));
4574   return ret.retn();
4575 }
4576
4577 /*!
4578  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4579  * of components in the result array is a sum of the number of components of given arrays
4580  * and (2) the number of tuples in the result array is same as that of each of given
4581  * arrays. In other words the i-th tuple of result array includes all components of
4582  * i-th tuples of all given arrays.
4583  * Number of tuples in the given arrays must be  the same.
4584  *  \param [in] a1 - an array to include in the result array.
4585  *  \param [in] a2 - another array to include in the result array.
4586  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4587  *          The caller is to delete this result array using decrRef() as it is no more
4588  *          needed.
4589  *  \throw If both \a a1 and \a a2 are NULL.
4590  *  \throw If any given array is not allocated.
4591  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4592  */
4593 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4594 {
4595   std::vector<const DataArrayDouble *> arr(2);
4596   arr[0]=a1; arr[1]=a2;
4597   return Meld(arr);
4598 }
4599
4600 /*!
4601  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4602  * of components in the result array is a sum of the number of components of given arrays
4603  * and (2) the number of tuples in the result array is same as that of each of given
4604  * arrays. In other words the i-th tuple of result array includes all components of
4605  * i-th tuples of all given arrays.
4606  * Number of tuples in the given arrays must be  the same.
4607  *  \param [in] arr - a sequence of arrays to include in the result array.
4608  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4609  *          The caller is to delete this result array using decrRef() as it is no more
4610  *          needed.
4611  *  \throw If all arrays within \a arr are NULL.
4612  *  \throw If any given array is not allocated.
4613  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4614  */
4615 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4616 {
4617   std::vector<const DataArrayDouble *> a;
4618   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4619     if(*it4)
4620       a.push_back(*it4);
4621   if(a.empty())
4622     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4623   std::vector<const DataArrayDouble *>::const_iterator it;
4624   for(it=a.begin();it!=a.end();it++)
4625     (*it)->checkAllocated();
4626   it=a.begin();
4627   int nbOfTuples=(*it)->getNumberOfTuples();
4628   std::vector<int> nbc(a.size());
4629   std::vector<const double *> pts(a.size());
4630   nbc[0]=(*it)->getNumberOfComponents();
4631   pts[0]=(*it++)->getConstPointer();
4632   for(int i=1;it!=a.end();it++,i++)
4633     {
4634       if(nbOfTuples!=(*it)->getNumberOfTuples())
4635         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4636       nbc[i]=(*it)->getNumberOfComponents();
4637       pts[i]=(*it)->getConstPointer();
4638     }
4639   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4640   DataArrayDouble *ret=DataArrayDouble::New();
4641   ret->alloc(nbOfTuples,totalNbOfComp);
4642   double *retPtr=ret->getPointer();
4643   for(int i=0;i<nbOfTuples;i++)
4644     for(int j=0;j<(int)a.size();j++)
4645       {
4646         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4647         pts[j]+=nbc[j];
4648       }
4649   int k=0;
4650   for(int i=0;i<(int)a.size();i++)
4651     for(int j=0;j<nbc[i];j++,k++)
4652       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4653   return ret;
4654 }
4655
4656 /*!
4657  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4658  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4659  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4660  * Info on components and name is copied from the first of the given arrays.
4661  * Number of tuples and components in the given arrays must be the same.
4662  *  \param [in] a1 - a given array.
4663  *  \param [in] a2 - another given array.
4664  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4665  *          The caller is to delete this result array using decrRef() as it is no more
4666  *          needed.
4667  *  \throw If either \a a1 or \a a2 is NULL.
4668  *  \throw If any given array is not allocated.
4669  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4670  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4671  */
4672 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4673 {
4674   if(!a1 || !a2)
4675     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4676   a1->checkAllocated();
4677   a2->checkAllocated();
4678   int nbOfComp=a1->getNumberOfComponents();
4679   if(nbOfComp!=a2->getNumberOfComponents())
4680     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4681   int nbOfTuple=a1->getNumberOfTuples();
4682   if(nbOfTuple!=a2->getNumberOfTuples())
4683     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4684   DataArrayDouble *ret=DataArrayDouble::New();
4685   ret->alloc(nbOfTuple,1);
4686   double *retPtr=ret->getPointer();
4687   const double *a1Ptr=a1->getConstPointer();
4688   const double *a2Ptr=a2->getConstPointer();
4689   for(int i=0;i<nbOfTuple;i++)
4690     {
4691       double sum=0.;
4692       for(int j=0;j<nbOfComp;j++)
4693         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4694       retPtr[i]=sum;
4695     }
4696   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4697   ret->setName(a1->getName().c_str());
4698   return ret;
4699 }
4700
4701 /*!
4702  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4703  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4704  * product of two vectors defined by the i-th tuples of given arrays.
4705  * Info on components is copied from the first of the given arrays.
4706  * Number of tuples in the given arrays must be the same.
4707  * Number of components in the given arrays must be 3.
4708  *  \param [in] a1 - a given array.
4709  *  \param [in] a2 - another given array.
4710  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4711  *          The caller is to delete this result array using decrRef() as it is no more
4712  *          needed.
4713  *  \throw If either \a a1 or \a a2 is NULL.
4714  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4715  *  \throw If \a a1->getNumberOfComponents() != 3
4716  *  \throw If \a a2->getNumberOfComponents() != 3
4717  */
4718 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4719 {
4720   if(!a1 || !a2)
4721     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4722   int nbOfComp=a1->getNumberOfComponents();
4723   if(nbOfComp!=a2->getNumberOfComponents())
4724     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4725   if(nbOfComp!=3)
4726     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4727   int nbOfTuple=a1->getNumberOfTuples();
4728   if(nbOfTuple!=a2->getNumberOfTuples())
4729     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4730   DataArrayDouble *ret=DataArrayDouble::New();
4731   ret->alloc(nbOfTuple,3);
4732   double *retPtr=ret->getPointer();
4733   const double *a1Ptr=a1->getConstPointer();
4734   const double *a2Ptr=a2->getConstPointer();
4735   for(int i=0;i<nbOfTuple;i++)
4736     {
4737       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4738       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4739       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4740     }
4741   ret->copyStringInfoFrom(*a1);
4742   return ret;
4743 }
4744
4745 /*!
4746  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4747  * Info on components is copied from the first of the given arrays.
4748  * Number of tuples and components in the given arrays must be the same.
4749  *  \param [in] a1 - an array to compare values with another one.
4750  *  \param [in] a2 - another array to compare values with the first one.
4751  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4752  *          The caller is to delete this result array using decrRef() as it is no more
4753  *          needed.
4754  *  \throw If either \a a1 or \a a2 is NULL.
4755  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4756  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4757  */
4758 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4759 {
4760   if(!a1 || !a2)
4761     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4762   int nbOfComp=a1->getNumberOfComponents();
4763   if(nbOfComp!=a2->getNumberOfComponents())
4764     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4765   int nbOfTuple=a1->getNumberOfTuples();
4766   if(nbOfTuple!=a2->getNumberOfTuples())
4767     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4768   DataArrayDouble *ret=DataArrayDouble::New();
4769   ret->alloc(nbOfTuple,nbOfComp);
4770   double *retPtr=ret->getPointer();
4771   const double *a1Ptr=a1->getConstPointer();
4772   const double *a2Ptr=a2->getConstPointer();
4773   int nbElem=nbOfTuple*nbOfComp;
4774   for(int i=0;i<nbElem;i++)
4775     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4776   ret->copyStringInfoFrom(*a1);
4777   return ret;
4778 }
4779
4780 /*!
4781  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4782  * Info on components is copied from the first of the given arrays.
4783  * Number of tuples and components in the given arrays must be the same.
4784  *  \param [in] a1 - an array to compare values with another one.
4785  *  \param [in] a2 - another array to compare values with the first one.
4786  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4787  *          The caller is to delete this result array using decrRef() as it is no more
4788  *          needed.
4789  *  \throw If either \a a1 or \a a2 is NULL.
4790  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4791  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4792  */
4793 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4794 {
4795   if(!a1 || !a2)
4796     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4797   int nbOfComp=a1->getNumberOfComponents();
4798   if(nbOfComp!=a2->getNumberOfComponents())
4799     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4800   int nbOfTuple=a1->getNumberOfTuples();
4801   if(nbOfTuple!=a2->getNumberOfTuples())
4802     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4803   DataArrayDouble *ret=DataArrayDouble::New();
4804   ret->alloc(nbOfTuple,nbOfComp);
4805   double *retPtr=ret->getPointer();
4806   const double *a1Ptr=a1->getConstPointer();
4807   const double *a2Ptr=a2->getConstPointer();
4808   int nbElem=nbOfTuple*nbOfComp;
4809   for(int i=0;i<nbElem;i++)
4810     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4811   ret->copyStringInfoFrom(*a1);
4812   return ret;
4813 }
4814
4815 /*!
4816  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4817  * valid cases.
4818  * 1.  The arrays have same number of tuples and components. Then each value of
4819  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4820  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4821  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4822  *   component. Then
4823  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4824  * 3.  The arrays have same number of components and one array, say _a2_, has one
4825  *   tuple. Then
4826  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4827  *
4828  * Info on components is copied either from the first array (in the first case) or from
4829  * the array with maximal number of elements (getNbOfElems()).
4830  *  \param [in] a1 - an array to sum up.
4831  *  \param [in] a2 - another array to sum up.
4832  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4833  *          The caller is to delete this result array using decrRef() as it is no more
4834  *          needed.
4835  *  \throw If either \a a1 or \a a2 is NULL.
4836  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4837  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4838  *         none of them has number of tuples or components equal to 1.
4839  */
4840 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4841 {
4842   if(!a1 || !a2)
4843     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4844   int nbOfTuple=a1->getNumberOfTuples();
4845   int nbOfTuple2=a2->getNumberOfTuples();
4846   int nbOfComp=a1->getNumberOfComponents();
4847   int nbOfComp2=a2->getNumberOfComponents();
4848   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4849   if(nbOfTuple==nbOfTuple2)
4850     {
4851       if(nbOfComp==nbOfComp2)
4852         {
4853           ret=DataArrayDouble::New();
4854           ret->alloc(nbOfTuple,nbOfComp);
4855           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4856           ret->copyStringInfoFrom(*a1);
4857         }
4858       else
4859         {
4860           int nbOfCompMin,nbOfCompMax;
4861           const DataArrayDouble *aMin, *aMax;
4862           if(nbOfComp>nbOfComp2)
4863             {
4864               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4865               aMin=a2; aMax=a1;
4866             }
4867           else
4868             {
4869               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4870               aMin=a1; aMax=a2;
4871             }
4872           if(nbOfCompMin==1)
4873             {
4874               ret=DataArrayDouble::New();
4875               ret->alloc(nbOfTuple,nbOfCompMax);
4876               const double *aMinPtr=aMin->getConstPointer();
4877               const double *aMaxPtr=aMax->getConstPointer();
4878               double *res=ret->getPointer();
4879               for(int i=0;i<nbOfTuple;i++)
4880                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4881               ret->copyStringInfoFrom(*aMax);
4882             }
4883           else
4884             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4885         }
4886     }
4887   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4888     {
4889       if(nbOfComp==nbOfComp2)
4890         {
4891           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4892           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4893           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4894           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4895           ret=DataArrayDouble::New();
4896           ret->alloc(nbOfTupleMax,nbOfComp);
4897           double *res=ret->getPointer();
4898           for(int i=0;i<nbOfTupleMax;i++)
4899             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4900           ret->copyStringInfoFrom(*aMax);
4901         }
4902       else
4903         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4904     }
4905   else
4906     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4907   return ret.retn();
4908 }
4909
4910 /*!
4911  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4912  * valid cases.
4913  * 1.  The arrays have same number of tuples and components. Then each value of
4914  *   \a other array is added to the corresponding value of \a this array, i.e.:
4915  *   _a_ [ i, j ] += _other_ [ i, j ].
4916  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4917  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4918  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4919  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4920  *
4921  *  \param [in] other - an array to add to \a this one.
4922  *  \throw If \a other is NULL.
4923  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4924  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4925  *         \a other has number of both tuples and components not equal to 1.
4926  */
4927 void DataArrayDouble::addEqual(const DataArrayDouble *other)
4928 {
4929   if(!other)
4930     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4931   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4932   checkAllocated();
4933   other->checkAllocated();
4934   int nbOfTuple=getNumberOfTuples();
4935   int nbOfTuple2=other->getNumberOfTuples();
4936   int nbOfComp=getNumberOfComponents();
4937   int nbOfComp2=other->getNumberOfComponents();
4938   if(nbOfTuple==nbOfTuple2)
4939     {
4940       if(nbOfComp==nbOfComp2)
4941         {
4942           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4943         }
4944       else if(nbOfComp2==1)
4945         {
4946           double *ptr=getPointer();
4947           const double *ptrc=other->getConstPointer();
4948           for(int i=0;i<nbOfTuple;i++)
4949             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4950         }
4951       else
4952         throw INTERP_KERNEL::Exception(msg);
4953     }
4954   else if(nbOfTuple2==1)
4955     {
4956       if(nbOfComp2==nbOfComp)
4957         {
4958           double *ptr=getPointer();
4959           const double *ptrc=other->getConstPointer();
4960           for(int i=0;i<nbOfTuple;i++)
4961             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4962         }
4963       else
4964         throw INTERP_KERNEL::Exception(msg);
4965     }
4966   else
4967     throw INTERP_KERNEL::Exception(msg);
4968   declareAsNew();
4969 }
4970
4971 /*!
4972  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4973  * valid cases.
4974  * 1.  The arrays have same number of tuples and components. Then each value of
4975  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4976  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4977  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4978  *   component. Then
4979  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4980  * 3.  The arrays have same number of components and one array, say _a2_, has one
4981  *   tuple. Then
4982  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4983  *
4984  * Info on components is copied either from the first array (in the first case) or from
4985  * the array with maximal number of elements (getNbOfElems()).
4986  *  \param [in] a1 - an array to subtract from.
4987  *  \param [in] a2 - an array to subtract.
4988  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4989  *          The caller is to delete this result array using decrRef() as it is no more
4990  *          needed.
4991  *  \throw If either \a a1 or \a a2 is NULL.
4992  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4993  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4994  *         none of them has number of tuples or components equal to 1.
4995  */
4996 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
4997 {
4998   if(!a1 || !a2)
4999     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5000   int nbOfTuple1=a1->getNumberOfTuples();
5001   int nbOfTuple2=a2->getNumberOfTuples();
5002   int nbOfComp1=a1->getNumberOfComponents();
5003   int nbOfComp2=a2->getNumberOfComponents();
5004   if(nbOfTuple2==nbOfTuple1)
5005     {
5006       if(nbOfComp1==nbOfComp2)
5007         {
5008           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5009           ret->alloc(nbOfTuple2,nbOfComp1);
5010           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5011           ret->copyStringInfoFrom(*a1);
5012           return ret.retn();
5013         }
5014       else if(nbOfComp2==1)
5015         {
5016           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5017           ret->alloc(nbOfTuple1,nbOfComp1);
5018           const double *a2Ptr=a2->getConstPointer();
5019           const double *a1Ptr=a1->getConstPointer();
5020           double *res=ret->getPointer();
5021           for(int i=0;i<nbOfTuple1;i++)
5022             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5023           ret->copyStringInfoFrom(*a1);
5024           return ret.retn();
5025         }
5026       else
5027         {
5028           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5029           return 0;
5030         }
5031     }
5032   else if(nbOfTuple2==1)
5033     {
5034       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5035       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5036       ret->alloc(nbOfTuple1,nbOfComp1);
5037       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5038       double *pt=ret->getPointer();
5039       for(int i=0;i<nbOfTuple1;i++)
5040         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5041       ret->copyStringInfoFrom(*a1);
5042       return ret.retn();
5043     }
5044   else
5045     {
5046       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5047       return 0;
5048     }
5049 }
5050
5051 /*!
5052  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5053  * valid cases.
5054  * 1.  The arrays have same number of tuples and components. Then each value of
5055  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5056  *   _a_ [ i, j ] -= _other_ [ i, j ].
5057  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5058  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5059  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5060  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5061  *
5062  *  \param [in] other - an array to subtract from \a this one.
5063  *  \throw If \a other is NULL.
5064  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5065  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5066  *         \a other has number of both tuples and components not equal to 1.
5067  */
5068 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5069 {
5070   if(!other)
5071     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5072   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5073   checkAllocated();
5074   other->checkAllocated();
5075   int nbOfTuple=getNumberOfTuples();
5076   int nbOfTuple2=other->getNumberOfTuples();
5077   int nbOfComp=getNumberOfComponents();
5078   int nbOfComp2=other->getNumberOfComponents();
5079   if(nbOfTuple==nbOfTuple2)
5080     {
5081       if(nbOfComp==nbOfComp2)
5082         {
5083           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5084         }
5085       else if(nbOfComp2==1)
5086         {
5087           double *ptr=getPointer();
5088           const double *ptrc=other->getConstPointer();
5089           for(int i=0;i<nbOfTuple;i++)
5090             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5091         }
5092       else
5093         throw INTERP_KERNEL::Exception(msg);
5094     }
5095   else if(nbOfTuple2==1)
5096     {
5097       if(nbOfComp2==nbOfComp)
5098         {
5099           double *ptr=getPointer();
5100           const double *ptrc=other->getConstPointer();
5101           for(int i=0;i<nbOfTuple;i++)
5102             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5103         }
5104       else
5105         throw INTERP_KERNEL::Exception(msg);
5106     }
5107   else
5108     throw INTERP_KERNEL::Exception(msg);
5109   declareAsNew();
5110 }
5111
5112 /*!
5113  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5114  * valid cases.
5115  * 1.  The arrays have same number of tuples and components. Then each value of
5116  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5117  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5118  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5119  *   component. Then
5120  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5121  * 3.  The arrays have same number of components and one array, say _a2_, has one
5122  *   tuple. Then
5123  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5124  *
5125  * Info on components is copied either from the first array (in the first case) or from
5126  * the array with maximal number of elements (getNbOfElems()).
5127  *  \param [in] a1 - a factor array.
5128  *  \param [in] a2 - another factor array.
5129  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5130  *          The caller is to delete this result array using decrRef() as it is no more
5131  *          needed.
5132  *  \throw If either \a a1 or \a a2 is NULL.
5133  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5134  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5135  *         none of them has number of tuples or components equal to 1.
5136  */
5137 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5138 {
5139   if(!a1 || !a2)
5140     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5141   int nbOfTuple=a1->getNumberOfTuples();
5142   int nbOfTuple2=a2->getNumberOfTuples();
5143   int nbOfComp=a1->getNumberOfComponents();
5144   int nbOfComp2=a2->getNumberOfComponents();
5145   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5146   if(nbOfTuple==nbOfTuple2)
5147     {
5148       if(nbOfComp==nbOfComp2)
5149         {
5150           ret=DataArrayDouble::New();
5151           ret->alloc(nbOfTuple,nbOfComp);
5152           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5153           ret->copyStringInfoFrom(*a1);
5154         }
5155       else
5156         {
5157           int nbOfCompMin,nbOfCompMax;
5158           const DataArrayDouble *aMin, *aMax;
5159           if(nbOfComp>nbOfComp2)
5160             {
5161               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5162               aMin=a2; aMax=a1;
5163             }
5164           else
5165             {
5166               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5167               aMin=a1; aMax=a2;
5168             }
5169           if(nbOfCompMin==1)
5170             {
5171               ret=DataArrayDouble::New();
5172               ret->alloc(nbOfTuple,nbOfCompMax);
5173               const double *aMinPtr=aMin->getConstPointer();
5174               const double *aMaxPtr=aMax->getConstPointer();
5175               double *res=ret->getPointer();
5176               for(int i=0;i<nbOfTuple;i++)
5177                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5178               ret->copyStringInfoFrom(*aMax);
5179             }
5180           else
5181             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5182         }
5183     }
5184   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5185     {
5186       if(nbOfComp==nbOfComp2)
5187         {
5188           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5189           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5190           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5191           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5192           ret=DataArrayDouble::New();
5193           ret->alloc(nbOfTupleMax,nbOfComp);
5194           double *res=ret->getPointer();
5195           for(int i=0;i<nbOfTupleMax;i++)
5196             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5197           ret->copyStringInfoFrom(*aMax);
5198         }
5199       else
5200         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5201     }
5202   else
5203     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5204   return ret.retn();
5205 }
5206
5207 /*!
5208  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5209  * valid cases.
5210  * 1.  The arrays have same number of tuples and components. Then each value of
5211  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5212  *   _this_ [ i, j ] *= _other_ [ i, j ].
5213  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5214  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5215  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5216  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5217  *
5218  *  \param [in] other - an array to multiply to \a this one.
5219  *  \throw If \a other is NULL.
5220  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5221  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5222  *         \a other has number of both tuples and components not equal to 1.
5223  */
5224 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5225 {
5226   if(!other)
5227     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5228   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5229   checkAllocated();
5230   other->checkAllocated();
5231   int nbOfTuple=getNumberOfTuples();
5232   int nbOfTuple2=other->getNumberOfTuples();
5233   int nbOfComp=getNumberOfComponents();
5234   int nbOfComp2=other->getNumberOfComponents();
5235   if(nbOfTuple==nbOfTuple2)
5236     {
5237       if(nbOfComp==nbOfComp2)
5238         {
5239           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5240         }
5241       else if(nbOfComp2==1)
5242         {
5243           double *ptr=getPointer();
5244           const double *ptrc=other->getConstPointer();
5245           for(int i=0;i<nbOfTuple;i++)
5246             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5247         }
5248       else
5249         throw INTERP_KERNEL::Exception(msg);
5250     }
5251   else if(nbOfTuple2==1)
5252     {
5253       if(nbOfComp2==nbOfComp)
5254         {
5255           double *ptr=getPointer();
5256           const double *ptrc=other->getConstPointer();
5257           for(int i=0;i<nbOfTuple;i++)
5258             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5259         }
5260       else
5261         throw INTERP_KERNEL::Exception(msg);
5262     }
5263   else
5264     throw INTERP_KERNEL::Exception(msg);
5265   declareAsNew();
5266 }
5267
5268 /*!
5269  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5270  * valid cases.
5271  * 1.  The arrays have same number of tuples and components. Then each value of
5272  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5273  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5274  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5275  *   component. Then
5276  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5277  * 3.  The arrays have same number of components and one array, say _a2_, has one
5278  *   tuple. Then
5279  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5280  *
5281  * Info on components is copied either from the first array (in the first case) or from
5282  * the array with maximal number of elements (getNbOfElems()).
5283  *  \warning No check of division by zero is performed!
5284  *  \param [in] a1 - a numerator array.
5285  *  \param [in] a2 - a denominator array.
5286  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5287  *          The caller is to delete this result array using decrRef() as it is no more
5288  *          needed.
5289  *  \throw If either \a a1 or \a a2 is NULL.
5290  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5291  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5292  *         none of them has number of tuples or components equal to 1.
5293  */
5294 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5295 {
5296   if(!a1 || !a2)
5297     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5298   int nbOfTuple1=a1->getNumberOfTuples();
5299   int nbOfTuple2=a2->getNumberOfTuples();
5300   int nbOfComp1=a1->getNumberOfComponents();
5301   int nbOfComp2=a2->getNumberOfComponents();
5302   if(nbOfTuple2==nbOfTuple1)
5303     {
5304       if(nbOfComp1==nbOfComp2)
5305         {
5306           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5307           ret->alloc(nbOfTuple2,nbOfComp1);
5308           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5309           ret->copyStringInfoFrom(*a1);
5310           return ret.retn();
5311         }
5312       else if(nbOfComp2==1)
5313         {
5314           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5315           ret->alloc(nbOfTuple1,nbOfComp1);
5316           const double *a2Ptr=a2->getConstPointer();
5317           const double *a1Ptr=a1->getConstPointer();
5318           double *res=ret->getPointer();
5319           for(int i=0;i<nbOfTuple1;i++)
5320             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5321           ret->copyStringInfoFrom(*a1);
5322           return ret.retn();
5323         }
5324       else
5325         {
5326           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5327           return 0;
5328         }
5329     }
5330   else if(nbOfTuple2==1)
5331     {
5332       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5333       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5334       ret->alloc(nbOfTuple1,nbOfComp1);
5335       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5336       double *pt=ret->getPointer();
5337       for(int i=0;i<nbOfTuple1;i++)
5338         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5339       ret->copyStringInfoFrom(*a1);
5340       return ret.retn();
5341     }
5342   else
5343     {
5344       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5345       return 0;
5346     }
5347 }
5348
5349 /*!
5350  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5351  * valid cases.
5352  * 1.  The arrays have same number of tuples and components. Then each value of
5353  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5354  *   _a_ [ i, j ] /= _other_ [ i, j ].
5355  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5356  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5357  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5358  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5359  *
5360  *  \warning No check of division by zero is performed!
5361  *  \param [in] other - an array to divide \a this one by.
5362  *  \throw If \a other is NULL.
5363  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5364  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5365  *         \a other has number of both tuples and components not equal to 1.
5366  */
5367 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5368 {
5369   if(!other)
5370     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5371   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5372   checkAllocated();
5373   other->checkAllocated();
5374   int nbOfTuple=getNumberOfTuples();
5375   int nbOfTuple2=other->getNumberOfTuples();
5376   int nbOfComp=getNumberOfComponents();
5377   int nbOfComp2=other->getNumberOfComponents();
5378   if(nbOfTuple==nbOfTuple2)
5379     {
5380       if(nbOfComp==nbOfComp2)
5381         {
5382           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5383         }
5384       else if(nbOfComp2==1)
5385         {
5386           double *ptr=getPointer();
5387           const double *ptrc=other->getConstPointer();
5388           for(int i=0;i<nbOfTuple;i++)
5389             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5390         }
5391       else
5392         throw INTERP_KERNEL::Exception(msg);
5393     }
5394   else if(nbOfTuple2==1)
5395     {
5396       if(nbOfComp2==nbOfComp)
5397         {
5398           double *ptr=getPointer();
5399           const double *ptrc=other->getConstPointer();
5400           for(int i=0;i<nbOfTuple;i++)
5401             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5402         }
5403       else
5404         throw INTERP_KERNEL::Exception(msg);
5405     }
5406   else
5407     throw INTERP_KERNEL::Exception(msg);
5408   declareAsNew();
5409 }
5410
5411 /*!
5412  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5413  * valid cases.
5414  *
5415  *  \param [in] a1 - an array to pow up.
5416  *  \param [in] a2 - another array to sum up.
5417  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5418  *          The caller is to delete this result array using decrRef() as it is no more
5419  *          needed.
5420  *  \throw If either \a a1 or \a a2 is NULL.
5421  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5422  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5423  *  \throw If there is a negative value in \a a1.
5424  */
5425 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5426 {
5427   if(!a1 || !a2)
5428     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5429   int nbOfTuple=a1->getNumberOfTuples();
5430   int nbOfTuple2=a2->getNumberOfTuples();
5431   int nbOfComp=a1->getNumberOfComponents();
5432   int nbOfComp2=a2->getNumberOfComponents();
5433   if(nbOfTuple!=nbOfTuple2)
5434     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5435   if(nbOfComp!=1 || nbOfComp2!=1)
5436     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5437   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5438   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5439   double *ptr=ret->getPointer();
5440   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5441     {
5442       if(*ptr1>=0)
5443         {
5444           *ptr=pow(*ptr1,*ptr2);
5445         }
5446       else
5447         {
5448           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5449           throw INTERP_KERNEL::Exception(oss.str().c_str());
5450         }
5451     }
5452   return ret.retn();
5453 }
5454
5455 /*!
5456  * Apply pow on values of another DataArrayDouble to values of \a this one.
5457  *
5458  *  \param [in] other - an array to pow to \a this one.
5459  *  \throw If \a other is NULL.
5460  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5461  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5462  *  \throw If there is a negative value in \a this.
5463  */
5464 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5465 {
5466   if(!other)
5467     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5468   int nbOfTuple=getNumberOfTuples();
5469   int nbOfTuple2=other->getNumberOfTuples();
5470   int nbOfComp=getNumberOfComponents();
5471   int nbOfComp2=other->getNumberOfComponents();
5472   if(nbOfTuple!=nbOfTuple2)
5473     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5474   if(nbOfComp!=1 || nbOfComp2!=1)
5475     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5476   double *ptr=getPointer();
5477   const double *ptrc=other->begin();
5478   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5479     {
5480       if(*ptr>=0)
5481         *ptr=pow(*ptr,*ptrc);
5482       else
5483         {
5484           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5485           throw INTERP_KERNEL::Exception(oss.str().c_str());
5486         }
5487     }
5488   declareAsNew();
5489 }
5490
5491 /*!
5492  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5493  * Server side.
5494  */
5495 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5496 {
5497   tinyInfo.resize(2);
5498   if(isAllocated())
5499     {
5500       tinyInfo[0]=getNumberOfTuples();
5501       tinyInfo[1]=getNumberOfComponents();
5502     }
5503   else
5504     {
5505       tinyInfo[0]=-1;
5506       tinyInfo[1]=-1;
5507     }
5508 }
5509
5510 /*!
5511  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5512  * Server side.
5513  */
5514 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5515 {
5516   if(isAllocated())
5517     {
5518       int nbOfCompo=getNumberOfComponents();
5519       tinyInfo.resize(nbOfCompo+1);
5520       tinyInfo[0]=getName();
5521       for(int i=0;i<nbOfCompo;i++)
5522         tinyInfo[i+1]=getInfoOnComponent(i);
5523     }
5524   else
5525     {
5526       tinyInfo.resize(1);
5527       tinyInfo[0]=getName();
5528     }
5529 }
5530
5531 /*!
5532  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5533  * This method returns if a feeding is needed.
5534  */
5535 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5536 {
5537   int nbOfTuple=tinyInfoI[0];
5538   int nbOfComp=tinyInfoI[1];
5539   if(nbOfTuple!=-1 || nbOfComp!=-1)
5540     {
5541       alloc(nbOfTuple,nbOfComp);
5542       return true;
5543     }
5544   return false;
5545 }
5546
5547 /*!
5548  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5549  */
5550 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5551 {
5552   setName(tinyInfoS[0].c_str());
5553   if(isAllocated())
5554     {
5555       int nbOfCompo=getNumberOfComponents();
5556       for(int i=0;i<nbOfCompo;i++)
5557         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5558     }
5559 }
5560
5561 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5562 {
5563   if(_da)
5564     {
5565       _da->incrRef();
5566       if(_da->isAllocated())
5567         {
5568           _nb_comp=da->getNumberOfComponents();
5569           _nb_tuple=da->getNumberOfTuples();
5570           _pt=da->getPointer();
5571         }
5572     }
5573 }
5574
5575 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5576 {
5577   if(_da)
5578     _da->decrRef();
5579 }
5580
5581 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5582 {
5583   if(_tuple_id<_nb_tuple)
5584     {
5585       _tuple_id++;
5586       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5587       _pt+=_nb_comp;
5588       return ret;
5589     }
5590   else
5591     return 0;
5592 }
5593
5594 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5595 {
5596 }
5597
5598
5599 std::string DataArrayDoubleTuple::repr() const
5600 {
5601   std::ostringstream oss; oss.precision(17); oss << "(";
5602   for(int i=0;i<_nb_of_compo-1;i++)
5603     oss << _pt[i] << ", ";
5604   oss << _pt[_nb_of_compo-1] << ")";
5605   return oss.str();
5606 }
5607
5608 double DataArrayDoubleTuple::doubleValue() const
5609 {
5610   if(_nb_of_compo==1)
5611     return *_pt;
5612   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5613 }
5614
5615 /*!
5616  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5617  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5618  * 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
5619  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5620  */
5621 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5622 {
5623   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5624     {
5625       DataArrayDouble *ret=DataArrayDouble::New();
5626       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5627       return ret;
5628     }
5629   else
5630     {
5631       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5632       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5633       throw INTERP_KERNEL::Exception(oss.str().c_str());
5634     }
5635 }
5636
5637 /*!
5638  * Returns a new instance of DataArrayInt. The caller is to delete this array
5639  * using decrRef() as it is no more needed. 
5640  */
5641 DataArrayInt *DataArrayInt::New()
5642 {
5643   return new DataArrayInt;
5644 }
5645
5646 /*!
5647  * Checks if raw data is allocated. Read more on the raw data
5648  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5649  *  \return bool - \a true if the raw data is allocated, \a false else.
5650  */
5651 bool DataArrayInt::isAllocated() const
5652 {
5653   return getConstPointer()!=0;
5654 }
5655
5656 /*!
5657  * Checks if raw data is allocated and throws an exception if it is not the case.
5658  *  \throw If the raw data is not allocated.
5659  */
5660 void DataArrayInt::checkAllocated() const
5661 {
5662   if(!isAllocated())
5663     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5664 }
5665
5666 /*!
5667  * This method desallocated \a this without modification of informations relative to the components.
5668  * After call of this method, DataArrayInt::isAllocated will return false.
5669  * If \a this is already not allocated, \a this is let unchanged.
5670  */
5671 void DataArrayInt::desallocate()
5672 {
5673   _mem.destroy();
5674 }
5675
5676 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5677 {
5678   std::size_t sz(_mem.getNbOfElemAllocated());
5679   sz*=sizeof(int);
5680   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5681 }
5682
5683 /*!
5684  * Returns the only one value in \a this, if and only if number of elements
5685  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5686  *  \return double - the sole value stored in \a this array.
5687  *  \throw If at least one of conditions stated above is not fulfilled.
5688  */
5689 int DataArrayInt::intValue() const
5690 {
5691   if(isAllocated())
5692     {
5693       if(getNbOfElems()==1)
5694         {
5695           return *getConstPointer();
5696         }
5697       else
5698         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5699     }
5700   else
5701     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5702 }
5703
5704 /*!
5705  * Returns an integer value characterizing \a this array, which is useful for a quick
5706  * comparison of many instances of DataArrayInt.
5707  *  \return int - the hash value.
5708  *  \throw If \a this is not allocated.
5709  */
5710 int DataArrayInt::getHashCode() const
5711 {
5712   checkAllocated();
5713   std::size_t nbOfElems=getNbOfElems();
5714   int ret=nbOfElems*65536;
5715   int delta=3;
5716   if(nbOfElems>48)
5717     delta=nbOfElems/8;
5718   int ret0=0;
5719   const int *pt=begin();
5720   for(std::size_t i=0;i<nbOfElems;i+=delta)
5721     ret0+=pt[i] & 0x1FFF;
5722   return ret+ret0;
5723 }
5724
5725 /*!
5726  * Checks the number of tuples.
5727  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5728  *  \throw If \a this is not allocated.
5729  */
5730 bool DataArrayInt::empty() const
5731 {
5732   checkAllocated();
5733   return getNumberOfTuples()==0;
5734 }
5735
5736 /*!
5737  * Returns a full copy of \a this. For more info on copying data arrays see
5738  * \ref MEDCouplingArrayBasicsCopyDeep.
5739  *  \return DataArrayInt * - a new instance of DataArrayInt.
5740  */
5741 DataArrayInt *DataArrayInt::deepCpy() const
5742 {
5743   return new DataArrayInt(*this);
5744 }
5745
5746 /*!
5747  * Returns either a \a deep or \a shallow copy of this array. For more info see
5748  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5749  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5750  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5751  *          == \a true) or \a this instance (if \a dCpy == \a false).
5752  */
5753 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5754 {
5755   if(dCpy)
5756     return deepCpy();
5757   else
5758     {
5759       incrRef();
5760       return const_cast<DataArrayInt *>(this);
5761     }
5762 }
5763
5764 /*!
5765  * Copies all the data from another DataArrayInt. For more info see
5766  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5767  *  \param [in] other - another instance of DataArrayInt to copy data from.
5768  *  \throw If the \a other is not allocated.
5769  */
5770 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5771 {
5772   other.checkAllocated();
5773   int nbOfTuples=other.getNumberOfTuples();
5774   int nbOfComp=other.getNumberOfComponents();
5775   allocIfNecessary(nbOfTuples,nbOfComp);
5776   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5777   int *pt=getPointer();
5778   const int *ptI=other.getConstPointer();
5779   for(std::size_t i=0;i<nbOfElems;i++)
5780     pt[i]=ptI[i];
5781   copyStringInfoFrom(other);
5782 }
5783
5784 /*!
5785  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5786  * 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.
5787  * If \a this has not already been allocated, number of components is set to one.
5788  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5789  * 
5790  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5791  */
5792 void DataArrayInt::reserve(std::size_t nbOfElems)
5793 {
5794   int nbCompo=getNumberOfComponents();
5795   if(nbCompo==1)
5796     {
5797       _mem.reserve(nbOfElems);
5798     }
5799   else if(nbCompo==0)
5800     {
5801       _mem.reserve(nbOfElems);
5802       _info_on_compo.resize(1);
5803     }
5804   else
5805     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5806 }
5807
5808 /*!
5809  * 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
5810  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5811  *
5812  * \param [in] val the value to be added in \a this
5813  * \throw If \a this has already been allocated with number of components different from one.
5814  * \sa DataArrayInt::pushBackValsSilent
5815  */
5816 void DataArrayInt::pushBackSilent(int val)
5817 {
5818   int nbCompo=getNumberOfComponents();
5819   if(nbCompo==1)
5820     _mem.pushBack(val);
5821   else if(nbCompo==0)
5822     {
5823       _info_on_compo.resize(1);
5824       _mem.pushBack(val);
5825     }
5826   else
5827     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5828 }
5829
5830 /*!
5831  * 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
5832  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5833  *
5834  *  \param [in] valsBg - an array of values to push at the end of \this.
5835  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5836  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5837  * \throw If \a this has already been allocated with number of components different from one.
5838  * \sa DataArrayInt::pushBackSilent
5839  */
5840 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5841 {
5842   int nbCompo=getNumberOfComponents();
5843   if(nbCompo==1)
5844     _mem.insertAtTheEnd(valsBg,valsEnd);
5845   else if(nbCompo==0)
5846     {
5847       _info_on_compo.resize(1);
5848       _mem.insertAtTheEnd(valsBg,valsEnd);
5849     }
5850   else
5851     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5852 }
5853
5854 /*!
5855  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5856  * \throw If \a this is already empty.
5857  * \throw If \a this has number of components different from one.
5858  */
5859 int DataArrayInt::popBackSilent()
5860 {
5861   if(getNumberOfComponents()==1)
5862     return _mem.popBack();
5863   else
5864     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5865 }
5866
5867 /*!
5868  * 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.
5869  *
5870  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5871  */
5872 void DataArrayInt::pack() const
5873 {
5874   _mem.pack();
5875 }
5876
5877 /*!
5878  * Allocates the raw data in memory. If exactly as same memory as needed already
5879  * allocated, it is not re-allocated.
5880  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5881  *  \param [in] nbOfCompo - number of components of data to allocate.
5882  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5883  */
5884 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5885 {
5886   if(isAllocated())
5887     {
5888       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5889         alloc(nbOfTuple,nbOfCompo);
5890     }
5891   else
5892     alloc(nbOfTuple,nbOfCompo);
5893 }
5894
5895 /*!
5896  * Allocates the raw data in memory. If the memory was already allocated, then it is
5897  * freed and re-allocated. See an example of this method use
5898  * \ref MEDCouplingArraySteps1WC "here".
5899  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5900  *  \param [in] nbOfCompo - number of components of data to allocate.
5901  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5902  */
5903 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
5904 {
5905   if(nbOfTuple<0 || nbOfCompo<0)
5906     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5907   _info_on_compo.resize(nbOfCompo);
5908   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5909   declareAsNew();
5910 }
5911
5912 /*!
5913  * Assign zero to all values in \a this array. To know more on filling arrays see
5914  * \ref MEDCouplingArrayFill.
5915  * \throw If \a this is not allocated.
5916  */
5917 void DataArrayInt::fillWithZero()
5918 {
5919   checkAllocated();
5920   _mem.fillWithValue(0);
5921   declareAsNew();
5922 }
5923
5924 /*!
5925  * Assign \a val to all values in \a this array. To know more on filling arrays see
5926  * \ref MEDCouplingArrayFill.
5927  *  \param [in] val - the value to fill with.
5928  *  \throw If \a this is not allocated.
5929  */
5930 void DataArrayInt::fillWithValue(int val)
5931 {
5932   checkAllocated();
5933   _mem.fillWithValue(val);
5934   declareAsNew();
5935 }
5936
5937 /*!
5938  * Set all values in \a this array so that the i-th element equals to \a init + i
5939  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5940  *  \param [in] init - value to assign to the first element of array.
5941  *  \throw If \a this->getNumberOfComponents() != 1
5942  *  \throw If \a this is not allocated.
5943  */
5944 void DataArrayInt::iota(int init)
5945 {
5946   checkAllocated();
5947   if(getNumberOfComponents()!=1)
5948     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5949   int *ptr=getPointer();
5950   int ntuples=getNumberOfTuples();
5951   for(int i=0;i<ntuples;i++)
5952     ptr[i]=init+i;
5953   declareAsNew();
5954 }
5955
5956 /*!
5957  * Returns a textual and human readable representation of \a this instance of
5958  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5959  *  \return std::string - text describing \a this DataArrayInt.
5960  */
5961 std::string DataArrayInt::repr() const
5962 {
5963   std::ostringstream ret;
5964   reprStream(ret);
5965   return ret.str();
5966 }
5967
5968 std::string DataArrayInt::reprZip() const
5969 {
5970   std::ostringstream ret;
5971   reprZipStream(ret);
5972   return ret.str();
5973 }
5974
5975 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
5976 {
5977   static const char SPACE[4]={' ',' ',' ',' '};
5978   checkAllocated();
5979   std::string idt(indent,' ');
5980   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5981   if(byteArr)
5982     {
5983       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5984       if(std::string(type)=="Int32")
5985         {
5986           const char *data(reinterpret_cast<const char *>(begin()));
5987           std::size_t sz(getNbOfElems()*sizeof(int));
5988           byteArr->insertAtTheEnd(data,data+sz);
5989           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5990         }
5991       else if(std::string(type)=="Int8")
5992         {
5993           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5994           std::copy(begin(),end(),(char *)tmp);
5995           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5996           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5997         }
5998       else if(std::string(type)=="UInt8")
5999         {
6000           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6001           std::copy(begin(),end(),(unsigned char *)tmp);
6002           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6003           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6004         }
6005       else
6006         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6007     }
6008   else
6009     {
6010       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6011       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6012     }
6013   ofs << std::endl << idt << "</DataArray>\n";
6014 }
6015
6016 void DataArrayInt::reprStream(std::ostream& stream) const
6017 {
6018   stream << "Name of int array : \"" << _name << "\"\n";
6019   reprWithoutNameStream(stream);
6020 }
6021
6022 void DataArrayInt::reprZipStream(std::ostream& stream) const
6023 {
6024   stream << "Name of int array : \"" << _name << "\"\n";
6025   reprZipWithoutNameStream(stream);
6026 }
6027
6028 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6029 {
6030   DataArray::reprWithoutNameStream(stream);
6031   _mem.repr(getNumberOfComponents(),stream);
6032 }
6033
6034 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6035 {
6036   DataArray::reprWithoutNameStream(stream);
6037   _mem.reprZip(getNumberOfComponents(),stream);
6038 }
6039
6040 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
6041 {
6042   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6043   const int *data=getConstPointer();
6044   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6045   if(nbTuples*nbComp>=1)
6046     {
6047       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6048       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6049       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6050       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6051     }
6052   else
6053     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6054   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6055 }
6056
6057 /*!
6058  * Method that gives a quick overvien of \a this for python.
6059  */
6060 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6061 {
6062   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6063   stream << "DataArrayInt C++ instance at " << this << ". ";
6064   if(isAllocated())
6065     {
6066       int nbOfCompo=(int)_info_on_compo.size();
6067       if(nbOfCompo>=1)
6068         {
6069           int nbOfTuples=getNumberOfTuples();
6070           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6071           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6072         }
6073       else
6074         stream << "Number of components : 0.";
6075     }
6076   else
6077     stream << "*** No data allocated ****";
6078 }
6079
6080 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6081 {
6082   const int *data=begin();
6083   int nbOfTuples=getNumberOfTuples();
6084   int nbOfCompo=(int)_info_on_compo.size();
6085   std::ostringstream oss2; oss2 << "[";
6086   std::string oss2Str(oss2.str());
6087   bool isFinished=true;
6088   for(int i=0;i<nbOfTuples && isFinished;i++)
6089     {
6090       if(nbOfCompo>1)
6091         {
6092           oss2 << "(";
6093           for(int j=0;j<nbOfCompo;j++,data++)
6094             {
6095               oss2 << *data;
6096               if(j!=nbOfCompo-1) oss2 << ", ";
6097             }
6098           oss2 << ")";
6099         }
6100       else
6101         oss2 << *data++;
6102       if(i!=nbOfTuples-1) oss2 << ", ";
6103       std::string oss3Str(oss2.str());
6104       if(oss3Str.length()<maxNbOfByteInRepr)
6105         oss2Str=oss3Str;
6106       else
6107         isFinished=false;
6108     }
6109   stream << oss2Str;
6110   if(!isFinished)
6111     stream << "... ";
6112   stream << "]";
6113 }
6114
6115 /*!
6116  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6117  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6118  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6119  *         to \a this array.
6120  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6121  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6122  *  \throw If \a this->getNumberOfComponents() != 1
6123  *  \throw If any value of \a this can't be used as a valid index for 
6124  *         [\a indArrBg, \a indArrEnd).
6125  */
6126 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6127 {
6128   checkAllocated();
6129   if(getNumberOfComponents()!=1)
6130     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6131   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6132   int nbOfTuples=getNumberOfTuples();
6133   int *pt=getPointer();
6134   for(int i=0;i<nbOfTuples;i++,pt++)
6135     {
6136       if(*pt>=0 && *pt<nbElemsIn)
6137         *pt=indArrBg[*pt];
6138       else
6139         {
6140           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6141           throw INTERP_KERNEL::Exception(oss.str().c_str());
6142         }
6143     }
6144   declareAsNew();
6145 }
6146
6147 /*!
6148  * Computes distribution of values of \a this one-dimensional array between given value
6149  * ranges (casts). This method is typically useful for entity number spliting by types,
6150  * for example. 
6151  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6152  *           check of this is be done. If not, the result is not warranted. 
6153  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6154  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6155  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6156  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6157  *         should be more than every value in \a this array.
6158  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6159  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6160  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6161  *         (same number of tuples and components), the caller is to delete 
6162  *         using decrRef() as it is no more needed.
6163  *         This array contains indices of ranges for every value of \a this array. I.e.
6164  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6165  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6166  *         this in which cast it holds.
6167  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6168  *         array, the caller is to delete using decrRef() as it is no more needed.
6169  *         This array contains ranks of values of \a this array within ranges
6170  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6171  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6172  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6173  *         for each tuple its rank inside its cast. The rank is computed as difference
6174  *         between the value and the lowest value of range.
6175  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6176  *         ranges (casts) to which at least one value of \a this array belongs.
6177  *         Or, in other words, this param contains the casts that \a this contains.
6178  *         The caller is to delete this array using decrRef() as it is no more needed.
6179  *
6180  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6181  *            the output of this method will be : 
6182  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6183  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6184  * - \a castsPresent  : [0,1]
6185  *
6186  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6187  * range #1 and its rank within this range is 2; etc.
6188  *
6189  *  \throw If \a this->getNumberOfComponents() != 1.
6190  *  \throw If \a arrEnd - arrBg < 2.
6191  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6192  */
6193 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6194                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6195 {
6196   checkAllocated();
6197   if(getNumberOfComponents()!=1)
6198     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6199   int nbOfTuples=getNumberOfTuples();
6200   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6201   if(nbOfCast<2)
6202     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6203   nbOfCast--;
6204   const int *work=getConstPointer();
6205   typedef std::reverse_iterator<const int *> rintstart;
6206   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6207   rintstart end2(arrBg);
6208   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6209   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6210   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6211   ret1->alloc(nbOfTuples,1);
6212   ret2->alloc(nbOfTuples,1);
6213   int *ret1Ptr=ret1->getPointer();
6214   int *ret2Ptr=ret2->getPointer();
6215   std::set<std::size_t> castsDetected;
6216   for(int i=0;i<nbOfTuples;i++)
6217     {
6218       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6219       std::size_t pos=std::distance(bg,res);
6220       std::size_t pos2=nbOfCast-pos;
6221       if(pos2<nbOfCast)
6222         {
6223           ret1Ptr[i]=(int)pos2;
6224           ret2Ptr[i]=work[i]-arrBg[pos2];
6225           castsDetected.insert(pos2);
6226         }
6227       else
6228         {
6229           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6230           throw INTERP_KERNEL::Exception(oss.str().c_str());
6231         }
6232     }
6233   ret3->alloc((int)castsDetected.size(),1);
6234   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6235   castArr=ret1.retn();
6236   rankInsideCast=ret2.retn();
6237   castsPresent=ret3.retn();
6238 }
6239
6240 /*!
6241  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6242  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6243  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6244  * new value in place \a indArr[ \a v ] is i.
6245  *  \param [in] indArrBg - the array holding indices within the result array to assign
6246  *         indices of values of \a this array pointing to values of \a indArrBg.
6247  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6248  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6249  *  \return DataArrayInt * - the new instance of DataArrayInt.
6250  *          The caller is to delete this result array using decrRef() as it is no more
6251  *          needed.
6252  *  \throw If \a this->getNumberOfComponents() != 1.
6253  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6254  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6255  */
6256 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6257 {
6258   checkAllocated();
6259   if(getNumberOfComponents()!=1)
6260     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6261   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6262   int nbOfTuples=getNumberOfTuples();
6263   const int *pt=getConstPointer();
6264   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6265   ret->alloc(nbOfTuples,1);
6266   ret->fillWithValue(-1);
6267   int *tmp=ret->getPointer();
6268   for(int i=0;i<nbOfTuples;i++,pt++)
6269     {
6270       if(*pt>=0 && *pt<nbElemsIn)
6271         {
6272           int pos=indArrBg[*pt];
6273           if(pos>=0 && pos<nbOfTuples)
6274             tmp[pos]=i;
6275           else
6276             {
6277               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6278               throw INTERP_KERNEL::Exception(oss.str().c_str());
6279             }
6280         }
6281       else
6282         {
6283           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6284           throw INTERP_KERNEL::Exception(oss.str().c_str());
6285         }
6286     }
6287   return ret.retn();
6288 }
6289
6290 /*!
6291  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6292  * from values of \a this array, which is supposed to contain a renumbering map in 
6293  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6294  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6295  *  \param [in] newNbOfElem - the number of tuples in the result array.
6296  *  \return DataArrayInt * - the new instance of DataArrayInt.
6297  *          The caller is to delete this result array using decrRef() as it is no more
6298  *          needed.
6299  * 
6300  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6301  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6302  */
6303 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6304 {
6305   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6306   ret->alloc(newNbOfElem,1);
6307   int nbOfOldNodes=getNumberOfTuples();
6308   const int *old2New=getConstPointer();
6309   int *pt=ret->getPointer();
6310   for(int i=0;i!=nbOfOldNodes;i++)
6311     {
6312       int newp(old2New[i]);
6313       if(newp!=-1)
6314         {
6315           if(newp>=0 && newp<newNbOfElem)
6316             pt[newp]=i;
6317           else
6318             {
6319               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6320               throw INTERP_KERNEL::Exception(oss.str().c_str());
6321             }
6322         }
6323     }
6324   return ret.retn();
6325 }
6326
6327 /*!
6328  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6329  * 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]
6330  */
6331 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6332 {
6333   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6334   ret->alloc(newNbOfElem,1);
6335   int nbOfOldNodes=getNumberOfTuples();
6336   const int *old2New=getConstPointer();
6337   int *pt=ret->getPointer();
6338   for(int i=nbOfOldNodes-1;i>=0;i--)
6339     {
6340       int newp(old2New[i]);
6341       if(newp!=-1)
6342         {
6343           if(newp>=0 && newp<newNbOfElem)
6344             pt[newp]=i;
6345           else
6346             {
6347               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6348               throw INTERP_KERNEL::Exception(oss.str().c_str());
6349             }
6350         }
6351     }
6352   return ret.retn();
6353 }
6354
6355 /*!
6356  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6357  * from values of \a this array, which is supposed to contain a renumbering map in 
6358  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6359  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6360  *  \param [in] newNbOfElem - the number of tuples in the result array.
6361  *  \return DataArrayInt * - the new instance of DataArrayInt.
6362  *          The caller is to delete this result array using decrRef() as it is no more
6363  *          needed.
6364  * 
6365  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6366  *
6367  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6368  */
6369 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6370 {
6371   checkAllocated();
6372   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6373   ret->alloc(oldNbOfElem,1);
6374   const int *new2Old=getConstPointer();
6375   int *pt=ret->getPointer();
6376   std::fill(pt,pt+oldNbOfElem,-1);
6377   int nbOfNewElems=getNumberOfTuples();
6378   for(int i=0;i<nbOfNewElems;i++)
6379     {
6380       int v(new2Old[i]);
6381       if(v>=0 && v<oldNbOfElem)
6382          pt[v]=i;
6383       else
6384         {
6385           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6386           throw INTERP_KERNEL::Exception(oss.str().c_str());
6387         }
6388     }
6389   return ret.retn();
6390 }
6391
6392 /*!
6393  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6394  * mismatch is given.
6395  * 
6396  * \param [in] other the instance to be compared with \a this
6397  * \param [out] reason In case of inequality returns the reason.
6398  * \sa DataArrayInt::isEqual
6399  */
6400 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6401 {
6402   if(!areInfoEqualsIfNotWhy(other,reason))
6403     return false;
6404   return _mem.isEqual(other._mem,0,reason);
6405 }
6406
6407 /*!
6408  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6409  * \ref MEDCouplingArrayBasicsCompare.
6410  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6411  *  \return bool - \a true if the two arrays are equal, \a false else.
6412  */
6413 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6414 {
6415   std::string tmp;
6416   return isEqualIfNotWhy(other,tmp);
6417 }
6418
6419 /*!
6420  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6421  * \ref MEDCouplingArrayBasicsCompare.
6422  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6423  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6424  */
6425 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6426 {
6427   std::string tmp;
6428   return _mem.isEqual(other._mem,0,tmp);
6429 }
6430
6431 /*!
6432  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6433  * performed on sorted value sequences.
6434  * For more info see\ref MEDCouplingArrayBasicsCompare.
6435  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6436  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6437  */
6438 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6439 {
6440   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6441   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6442   a->sort();
6443   b->sort();
6444   return a->isEqualWithoutConsideringStr(*b);
6445 }
6446
6447 /*!
6448  * This method compares content of input vector \a v and \a this.
6449  * 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.
6450  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6451  *
6452  * \param [in] v - the vector of 'flags' to be compared with \a this.
6453  *
6454  * \throw If \a this is not sorted ascendingly.
6455  * \throw If \a this has not exactly one component.
6456  * \throw If \a this is not allocated.
6457  */
6458 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6459 {
6460   checkAllocated();
6461   if(getNumberOfComponents()!=1)
6462     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6463   int nbOfTuples(getNumberOfTuples());
6464   const int *w(begin()),*end2(end());
6465   int refVal=-std::numeric_limits<int>::max();
6466   int i=0;
6467   std::vector<bool>::const_iterator it(v.begin());
6468   for(;it!=v.end();it++,i++)
6469     {
6470       if(*it)
6471         {
6472           if(w!=end2)
6473             {
6474               if(*w++==i)
6475                 {
6476                   if(i>refVal)
6477                     refVal=i;
6478                   else
6479                     {
6480                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6481                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6482                     }
6483                 }
6484               else
6485                 return false;
6486             }
6487           else
6488             return false;
6489         }
6490     }
6491   return w==end2;
6492 }
6493
6494 /*!
6495  * Sorts values of the array.
6496  *  \param [in] asc - \a true means ascending order, \a false, descending.
6497  *  \throw If \a this is not allocated.
6498  *  \throw If \a this->getNumberOfComponents() != 1.
6499  */
6500 void DataArrayInt::sort(bool asc)
6501 {
6502   checkAllocated();
6503   if(getNumberOfComponents()!=1)
6504     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6505   _mem.sort(asc);
6506   declareAsNew();
6507 }
6508
6509 /*!
6510  * Computes for each tuple the sum of number of components values in the tuple and return it.
6511  * 
6512  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6513  *          same number of tuples as \a this array and one component.
6514  *          The caller is to delete this result array using decrRef() as it is no more
6515  *          needed.
6516  *  \throw If \a this is not allocated.
6517  */
6518 DataArrayInt *DataArrayInt::sumPerTuple() const
6519 {
6520   checkAllocated();
6521   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6522   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6523   ret->alloc(nbOfTuple,1);
6524   const int *src(getConstPointer());
6525   int *dest(ret->getPointer());
6526   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6527     *dest=std::accumulate(src,src+nbOfComp,0);
6528   return ret.retn();
6529 }
6530
6531 /*!
6532  * Reverse the array values.
6533  *  \throw If \a this->getNumberOfComponents() < 1.
6534  *  \throw If \a this is not allocated.
6535  */
6536 void DataArrayInt::reverse()
6537 {
6538   checkAllocated();
6539   _mem.reverse(getNumberOfComponents());
6540   declareAsNew();
6541 }
6542
6543 /*!
6544  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6545  * If not an exception is thrown.
6546  *  \param [in] increasing - if \a true, the array values should be increasing.
6547  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6548  *         increasing arg.
6549  *  \throw If \a this->getNumberOfComponents() != 1.
6550  *  \throw If \a this is not allocated.
6551  */
6552 void DataArrayInt::checkMonotonic(bool increasing) const
6553 {
6554   if(!isMonotonic(increasing))
6555     {
6556       if (increasing)
6557         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6558       else
6559         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6560     }
6561 }
6562
6563 /*!
6564  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6565  *  \param [in] increasing - if \a true, array values should be increasing.
6566  *  \return bool - \a true if values change in accordance with \a increasing arg.
6567  *  \throw If \a this->getNumberOfComponents() != 1.
6568  *  \throw If \a this is not allocated.
6569  */
6570 bool DataArrayInt::isMonotonic(bool increasing) const
6571 {
6572   checkAllocated();
6573   if(getNumberOfComponents()!=1)
6574     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6575   int nbOfElements=getNumberOfTuples();
6576   const int *ptr=getConstPointer();
6577   if(nbOfElements==0)
6578     return true;
6579   int ref=ptr[0];
6580   if(increasing)
6581     {
6582       for(int i=1;i<nbOfElements;i++)
6583         {
6584           if(ptr[i]>=ref)
6585             ref=ptr[i];
6586           else
6587             return false;
6588         }
6589     }
6590   else
6591     {
6592       for(int i=1;i<nbOfElements;i++)
6593         {
6594           if(ptr[i]<=ref)
6595             ref=ptr[i];
6596           else
6597             return false;
6598         }
6599     }
6600   return true;
6601 }
6602
6603 /*!
6604  * This method check that array consistently INCREASING or DECREASING in value.
6605  */
6606 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6607 {
6608   checkAllocated();
6609   if(getNumberOfComponents()!=1)
6610     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6611   int nbOfElements=getNumberOfTuples();
6612   const int *ptr=getConstPointer();
6613   if(nbOfElements==0)
6614     return true;
6615   int ref=ptr[0];
6616   if(increasing)
6617     {
6618       for(int i=1;i<nbOfElements;i++)
6619         {
6620           if(ptr[i]>ref)
6621             ref=ptr[i];
6622           else
6623             return false;
6624         }
6625     }
6626   else
6627     {
6628       for(int i=1;i<nbOfElements;i++)
6629         {
6630           if(ptr[i]<ref)
6631             ref=ptr[i];
6632           else
6633             return false;
6634         }
6635     }
6636   return true;
6637 }
6638
6639 /*!
6640  * This method check that array consistently INCREASING or DECREASING in value.
6641  */
6642 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6643 {
6644   if(!isStrictlyMonotonic(increasing))
6645     {
6646       if (increasing)
6647         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6648       else
6649         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6650     }
6651 }
6652
6653 /*!
6654  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6655  * one-dimensional arrays that must be of the same length. The result array describes
6656  * correspondence between \a this and \a other arrays, so that 
6657  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6658  * not possible because some element in \a other is not in \a this, an exception is thrown.
6659  *  \param [in] other - an array to compute permutation to.
6660  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6661  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6662  * no more needed.
6663  *  \throw If \a this->getNumberOfComponents() != 1.
6664  *  \throw If \a other->getNumberOfComponents() != 1.
6665  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6666  *  \throw If \a other includes a value which is not in \a this array.
6667  * 
6668  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6669  *
6670  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6671  */
6672 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6673 {
6674   checkAllocated();
6675   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6676     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6677   int nbTuple=getNumberOfTuples();
6678   other.checkAllocated();
6679   if(nbTuple!=other.getNumberOfTuples())
6680     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6681   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6682   ret->alloc(nbTuple,1);
6683   ret->fillWithValue(-1);
6684   const int *pt=getConstPointer();
6685   std::map<int,int> mm;
6686   for(int i=0;i<nbTuple;i++)
6687     mm[pt[i]]=i;
6688   pt=other.getConstPointer();
6689   int *retToFill=ret->getPointer();
6690   for(int i=0;i<nbTuple;i++)
6691     {
6692       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6693       if(it==mm.end())
6694         {
6695           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6696           throw INTERP_KERNEL::Exception(oss.str().c_str());
6697         }
6698       retToFill[i]=(*it).second;
6699     }
6700   return ret.retn();
6701 }
6702
6703 /*!
6704  * Sets a C array to be used as raw data of \a this. The previously set info
6705  *  of components is retained and re-sized. 
6706  * For more info see \ref MEDCouplingArraySteps1.
6707  *  \param [in] array - the C array to be used as raw data of \a this.
6708  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6709  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6710  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6711  *                     \c free(\c array ) will be called.
6712  *  \param [in] nbOfTuple - new number of tuples in \a this.
6713  *  \param [in] nbOfCompo - new number of components in \a this.
6714  */
6715 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6716 {
6717   _info_on_compo.resize(nbOfCompo);
6718   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6719   declareAsNew();
6720 }
6721
6722 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6723 {
6724   _info_on_compo.resize(nbOfCompo);
6725   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6726   declareAsNew();
6727 }
6728
6729 /*!
6730  * Returns a new DataArrayInt holding the same values as \a this array but differently
6731  * arranged in memory. If \a this array holds 2 components of 3 values:
6732  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6733  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6734  *  \warning Do not confuse this method with transpose()!
6735  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6736  *          is to delete using decrRef() as it is no more needed.
6737  *  \throw If \a this is not allocated.
6738  */
6739 DataArrayInt *DataArrayInt::fromNoInterlace() const
6740 {
6741   checkAllocated();
6742   if(_mem.isNull())
6743     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6744   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6745   DataArrayInt *ret=DataArrayInt::New();
6746   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6747   return ret;
6748 }
6749
6750 /*!
6751  * Returns a new DataArrayInt holding the same values as \a this array but differently
6752  * arranged in memory. If \a this array holds 2 components of 3 values:
6753  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6754  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6755  *  \warning Do not confuse this method with transpose()!
6756  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6757  *          is to delete using decrRef() as it is no more needed.
6758  *  \throw If \a this is not allocated.
6759  */
6760 DataArrayInt *DataArrayInt::toNoInterlace() const
6761 {
6762   checkAllocated();
6763   if(_mem.isNull())
6764     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6765   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6766   DataArrayInt *ret=DataArrayInt::New();
6767   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6768   return ret;
6769 }
6770
6771 /*!
6772  * Permutes values of \a this array as required by \a old2New array. The values are
6773  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6774  * the same as in \this one.
6775  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6776  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6777  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6778  *     giving a new position for i-th old value.
6779  */
6780 void DataArrayInt::renumberInPlace(const int *old2New)
6781 {
6782   checkAllocated();
6783   int nbTuples=getNumberOfTuples();
6784   int nbOfCompo=getNumberOfComponents();
6785   int *tmp=new int[nbTuples*nbOfCompo];
6786   const int *iptr=getConstPointer();
6787   for(int i=0;i<nbTuples;i++)
6788     {
6789       int v=old2New[i];
6790       if(v>=0 && v<nbTuples)
6791         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6792       else
6793         {
6794           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6795           throw INTERP_KERNEL::Exception(oss.str().c_str());
6796         }
6797     }
6798   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6799   delete [] tmp;
6800   declareAsNew();
6801 }
6802
6803 /*!
6804  * Permutes values of \a this array as required by \a new2Old array. The values are
6805  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6806  * the same as in \this one.
6807  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6808  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6809  *     giving a previous position of i-th new value.
6810  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6811  *          is to delete using decrRef() as it is no more needed.
6812  */
6813 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6814 {
6815   checkAllocated();
6816   int nbTuples=getNumberOfTuples();
6817   int nbOfCompo=getNumberOfComponents();
6818   int *tmp=new int[nbTuples*nbOfCompo];
6819   const int *iptr=getConstPointer();
6820   for(int i=0;i<nbTuples;i++)
6821     {
6822       int v=new2Old[i];
6823       if(v>=0 && v<nbTuples)
6824         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6825       else
6826         {
6827           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6828           throw INTERP_KERNEL::Exception(oss.str().c_str());
6829         }
6830     }
6831   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6832   delete [] tmp;
6833   declareAsNew();
6834 }
6835
6836 /*!
6837  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6838  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6839  * Number of tuples in the result array remains the same as in \this one.
6840  * If a permutation reduction is needed, renumberAndReduce() should be used.
6841  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6842  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6843  *          giving a new position for i-th old value.
6844  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6845  *          is to delete using decrRef() as it is no more needed.
6846  *  \throw If \a this is not allocated.
6847  */
6848 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6849 {
6850   checkAllocated();
6851   int nbTuples=getNumberOfTuples();
6852   int nbOfCompo=getNumberOfComponents();
6853   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6854   ret->alloc(nbTuples,nbOfCompo);
6855   ret->copyStringInfoFrom(*this);
6856   const int *iptr=getConstPointer();
6857   int *optr=ret->getPointer();
6858   for(int i=0;i<nbTuples;i++)
6859     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6860   ret->copyStringInfoFrom(*this);
6861   return ret.retn();
6862 }
6863
6864 /*!
6865  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6866  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6867  * tuples in the result array remains the same as in \this one.
6868  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6869  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6870  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6871  *     giving a previous position of i-th new value.
6872  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6873  *          is to delete using decrRef() as it is no more needed.
6874  */
6875 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6876 {
6877   checkAllocated();
6878   int nbTuples=getNumberOfTuples();
6879   int nbOfCompo=getNumberOfComponents();
6880   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6881   ret->alloc(nbTuples,nbOfCompo);
6882   ret->copyStringInfoFrom(*this);
6883   const int *iptr=getConstPointer();
6884   int *optr=ret->getPointer();
6885   for(int i=0;i<nbTuples;i++)
6886     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6887   ret->copyStringInfoFrom(*this);
6888   return ret.retn();
6889 }
6890
6891 /*!
6892  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6893  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6894  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6895  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6896  * \a old2New[ i ] is negative, is missing from the result array.
6897  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6898  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6899  *     giving a new position for i-th old tuple and giving negative position for
6900  *     for i-th old tuple that should be omitted.
6901  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6902  *          is to delete using decrRef() as it is no more needed.
6903  */
6904 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6905 {
6906   checkAllocated();
6907   int nbTuples=getNumberOfTuples();
6908   int nbOfCompo=getNumberOfComponents();
6909   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6910   ret->alloc(newNbOfTuple,nbOfCompo);
6911   const int *iptr=getConstPointer();
6912   int *optr=ret->getPointer();
6913   for(int i=0;i<nbTuples;i++)
6914     {
6915       int w=old2New[i];
6916       if(w>=0)
6917         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6918     }
6919   ret->copyStringInfoFrom(*this);
6920   return ret.retn();
6921 }
6922
6923 /*!
6924  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6925  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6926  * \a new2OldBg array.
6927  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6928  * This method is equivalent to renumberAndReduce() except that convention in input is
6929  * \c new2old and \b not \c old2new.
6930  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6931  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6932  *              tuple index in \a this array to fill the i-th tuple in the new array.
6933  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6934  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6935  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6936  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6937  *          is to delete using decrRef() as it is no more needed.
6938  */
6939 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6940 {
6941   checkAllocated();
6942   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6943   int nbComp=getNumberOfComponents();
6944   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6945   ret->copyStringInfoFrom(*this);
6946   int *pt=ret->getPointer();
6947   const int *srcPt=getConstPointer();
6948   int i=0;
6949   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6950     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6951   ret->copyStringInfoFrom(*this);
6952   return ret.retn();
6953 }
6954
6955 /*!
6956  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6957  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6958  * \a new2OldBg array.
6959  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6960  * This method is equivalent to renumberAndReduce() except that convention in input is
6961  * \c new2old and \b not \c old2new.
6962  * This method is equivalent to selectByTupleId() except that it prevents coping data
6963  * from behind the end of \a this array.
6964  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6965  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6966  *              tuple index in \a this array to fill the i-th tuple in the new array.
6967  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6968  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6969  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6970  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6971  *          is to delete using decrRef() as it is no more needed.
6972  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6973  */
6974 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
6975 {
6976   checkAllocated();
6977   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6978   int nbComp=getNumberOfComponents();
6979   int oldNbOfTuples=getNumberOfTuples();
6980   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6981   ret->copyStringInfoFrom(*this);
6982   int *pt=ret->getPointer();
6983   const int *srcPt=getConstPointer();
6984   int i=0;
6985   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6986     if(*w>=0 && *w<oldNbOfTuples)
6987       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6988     else
6989       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6990   ret->copyStringInfoFrom(*this);
6991   return ret.retn();
6992 }
6993
6994 /*!
6995  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6996  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6997  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6998  * command \c range( \a bg, \a end2, \a step ).
6999  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7000  * not constructed explicitly.
7001  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7002  *  \param [in] bg - index of the first tuple to copy from \a this array.
7003  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7004  *  \param [in] step - index increment to get index of the next tuple to copy.
7005  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7006  *          is to delete using decrRef() as it is no more needed.
7007  *  \sa DataArrayInt::substr.
7008  */
7009 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7010 {
7011   checkAllocated();
7012   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7013   int nbComp=getNumberOfComponents();
7014   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7015   ret->alloc(newNbOfTuples,nbComp);
7016   int *pt=ret->getPointer();
7017   const int *srcPt=getConstPointer()+bg*nbComp;
7018   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7019     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7020   ret->copyStringInfoFrom(*this);
7021   return ret.retn();
7022 }
7023
7024 /*!
7025  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7026  * of tuples specified by \a ranges parameter.
7027  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7028  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7029  *              of tuples in [\c begin,\c end) format.
7030  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7031  *          is to delete using decrRef() as it is no more needed.
7032  *  \throw If \a end < \a begin.
7033  *  \throw If \a end > \a this->getNumberOfTuples().
7034  *  \throw If \a this is not allocated.
7035  */
7036 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7037 {
7038   checkAllocated();
7039   int nbOfComp=getNumberOfComponents();
7040   int nbOfTuplesThis=getNumberOfTuples();
7041   if(ranges.empty())
7042     {
7043       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7044       ret->alloc(0,nbOfComp);
7045       ret->copyStringInfoFrom(*this);
7046       return ret.retn();
7047     }
7048   int ref=ranges.front().first;
7049   int nbOfTuples=0;
7050   bool isIncreasing=true;
7051   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7052     {
7053       if((*it).first<=(*it).second)
7054         {
7055           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7056             {
7057               nbOfTuples+=(*it).second-(*it).first;
7058               if(isIncreasing)
7059                 isIncreasing=ref<=(*it).first;
7060               ref=(*it).second;
7061             }
7062           else
7063             {
7064               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7065               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7066               throw INTERP_KERNEL::Exception(oss.str().c_str());
7067             }
7068         }
7069       else
7070         {
7071           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7072           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7073           throw INTERP_KERNEL::Exception(oss.str().c_str());
7074         }
7075     }
7076   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7077     return deepCpy();
7078   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7079   ret->alloc(nbOfTuples,nbOfComp);
7080   ret->copyStringInfoFrom(*this);
7081   const int *src=getConstPointer();
7082   int *work=ret->getPointer();
7083   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7084     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7085   return ret.retn();
7086 }
7087
7088 /*!
7089  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7090  * This map, if applied to \a this array, would make it sorted. For example, if
7091  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7092  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7093  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7094  * This method is useful for renumbering (in MED file for example). For more info
7095  * on renumbering see \ref MEDCouplingArrayRenumbering.
7096  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7097  *          array using decrRef() as it is no more needed.
7098  *  \throw If \a this is not allocated.
7099  *  \throw If \a this->getNumberOfComponents() != 1.
7100  *  \throw If there are equal values in \a this array.
7101  */
7102 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7103 {
7104   checkAllocated();
7105   if(getNumberOfComponents()!=1)
7106     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7107   int nbTuples=getNumberOfTuples();
7108   const int *pt=getConstPointer();
7109   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7110   DataArrayInt *ret=DataArrayInt::New();
7111   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7112   return ret;
7113 }
7114
7115 /*!
7116  * 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
7117  * input array \a ids2.
7118  * \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.
7119  * 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
7120  * inversely.
7121  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7122  *
7123  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7124  *          array using decrRef() as it is no more needed.
7125  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7126  * 
7127  */
7128 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7129 {
7130   if(!ids1 || !ids2)
7131     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7132   if(!ids1->isAllocated() || !ids2->isAllocated())
7133     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7134   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7135     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7136   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7137     {
7138       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 !";
7139       throw INTERP_KERNEL::Exception(oss.str().c_str());
7140     }
7141   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7142   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7143   p1->sort(true); p2->sort(true);
7144   if(!p1->isEqualWithoutConsideringStr(*p2))
7145     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7146   p1=ids1->checkAndPreparePermutation();
7147   p2=ids2->checkAndPreparePermutation();
7148   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7149   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7150   return p2.retn();
7151 }
7152
7153 /*!
7154  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7155  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7156  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7157  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7158  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7159  * The first of out arrays returns indices of elements of \a this array, grouped by their
7160  * place in the set \a B. The second out array is the index of the first one; it shows how
7161  * many elements of \a A are mapped into each element of \a B. <br>
7162  * For more info on
7163  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7164  * \b Example:
7165  * - \a this: [0,3,2,3,2,2,1,2]
7166  * - \a targetNb: 4
7167  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7168  * - \a arrI: [0,1,2,6,8]
7169  *
7170  * This result means: <br>
7171  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7172  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7173  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7174  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7175  * \a arrI[ 2+1 ]]); <br> etc.
7176  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7177  *         than the maximal value of \a A.
7178  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7179  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7180  *         this array using decrRef() as it is no more needed.
7181  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7182  *         elements of \a this. The caller is to delete this array using decrRef() as it
7183  *         is no more needed.
7184  *  \throw If \a this is not allocated.
7185  *  \throw If \a this->getNumberOfComponents() != 1.
7186  *  \throw If any value in \a this is more or equal to \a targetNb.
7187  */
7188 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7189 {
7190   checkAllocated();
7191   if(getNumberOfComponents()!=1)
7192     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7193   int nbOfTuples=getNumberOfTuples();
7194   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7195   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7196   retI->alloc(targetNb+1,1);
7197   const int *input=getConstPointer();
7198   std::vector< std::vector<int> > tmp(targetNb);
7199   for(int i=0;i<nbOfTuples;i++)
7200     {
7201       int tmp2=input[i];
7202       if(tmp2>=0 && tmp2<targetNb)
7203         tmp[tmp2].push_back(i);
7204       else
7205         {
7206           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7207           throw INTERP_KERNEL::Exception(oss.str().c_str());
7208         }
7209     }
7210   int *retIPtr=retI->getPointer();
7211   *retIPtr=0;
7212   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7213     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7214   if(nbOfTuples!=retI->getIJ(targetNb,0))
7215     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7216   ret->alloc(nbOfTuples,1);
7217   int *retPtr=ret->getPointer();
7218   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7219     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7220   arr=ret.retn();
7221   arrI=retI.retn();
7222 }
7223
7224
7225 /*!
7226  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7227  * from a zip representation of a surjective format (returned e.g. by
7228  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7229  * for example). The result array minimizes the permutation. <br>
7230  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7231  * \b Example: <br>
7232  * - \a nbOfOldTuples: 10 
7233  * - \a arr          : [0,3, 5,7,9]
7234  * - \a arrIBg       : [0,2,5]
7235  * - \a newNbOfTuples: 7
7236  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7237  *
7238  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7239  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7240  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7241  *         (indices of) equal values. Its every element (except the last one) points to
7242  *         the first element of a group of equal values.
7243  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7244  *          arrIBg is \a arrIEnd[ -1 ].
7245  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7246  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7247  *          array using decrRef() as it is no more needed.
7248  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7249  */
7250 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7251 {
7252   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7253   ret->alloc(nbOfOldTuples,1);
7254   int *pt=ret->getPointer();
7255   std::fill(pt,pt+nbOfOldTuples,-1);
7256   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7257   const int *cIPtr=arrIBg;
7258   for(int i=0;i<nbOfGrps;i++)
7259     pt[arr[cIPtr[i]]]=-(i+2);
7260   int newNb=0;
7261   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7262     {
7263       if(pt[iNode]<0)
7264         {
7265           if(pt[iNode]==-1)
7266             pt[iNode]=newNb++;
7267           else
7268             {
7269               int grpId=-(pt[iNode]+2);
7270               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7271                 {
7272                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7273                     pt[arr[j]]=newNb;
7274                   else
7275                     {
7276                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7277                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7278                     }
7279                 }
7280               newNb++;
7281             }
7282         }
7283     }
7284   newNbOfTuples=newNb;
7285   return ret.retn();
7286 }
7287
7288 /*!
7289  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7290  * which if applied to \a this array would make it sorted ascendingly.
7291  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7292  * \b Example: <br>
7293  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7294  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7295  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7296  *
7297  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7298  *          array using decrRef() as it is no more needed.
7299  *  \throw If \a this is not allocated.
7300  *  \throw If \a this->getNumberOfComponents() != 1.
7301  */
7302 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7303 {
7304   checkAllocated();
7305   if(getNumberOfComponents()!=1)
7306     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7307   int nbOfTuples=getNumberOfTuples();
7308   const int *pt=getConstPointer();
7309   std::map<int,int> m;
7310   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7311   ret->alloc(nbOfTuples,1);
7312   int *opt=ret->getPointer();
7313   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7314     {
7315       int val=*pt;
7316       std::map<int,int>::iterator it=m.find(val);
7317       if(it!=m.end())
7318         {
7319           *opt=(*it).second;
7320           (*it).second++;
7321         }
7322       else
7323         {
7324           *opt=0;
7325           m.insert(std::pair<int,int>(val,1));
7326         }
7327     }
7328   int sum=0;
7329   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7330     {
7331       int vt=(*it).second;
7332       (*it).second=sum;
7333       sum+=vt;
7334     }
7335   pt=getConstPointer();
7336   opt=ret->getPointer();
7337   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7338     *opt+=m[*pt];
7339   //
7340   return ret.retn();
7341 }
7342
7343 /*!
7344  * Checks if contents of \a this array are equal to that of an array filled with
7345  * iota(). This method is particularly useful for DataArrayInt instances that represent
7346  * a renumbering array to check the real need in renumbering. 
7347  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7348  *  \throw If \a this is not allocated.
7349  *  \throw If \a this->getNumberOfComponents() != 1.
7350  */
7351 bool DataArrayInt::isIdentity() const
7352 {
7353   checkAllocated();
7354   if(getNumberOfComponents()!=1)
7355     return false;
7356   int nbOfTuples=getNumberOfTuples();
7357   const int *pt=getConstPointer();
7358   for(int i=0;i<nbOfTuples;i++,pt++)
7359     if(*pt!=i)
7360       return false;
7361   return true;
7362 }
7363
7364 /*!
7365  * Checks if all values in \a this array are equal to \a val.
7366  *  \param [in] val - value to check equality of array values to.
7367  *  \return bool - \a true if all values are \a val.
7368  *  \throw If \a this is not allocated.
7369  *  \throw If \a this->getNumberOfComponents() != 1
7370  */
7371 bool DataArrayInt::isUniform(int val) const
7372 {
7373   checkAllocated();
7374   if(getNumberOfComponents()!=1)
7375     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7376   int nbOfTuples=getNumberOfTuples();
7377   const int *w=getConstPointer();
7378   const int *end2=w+nbOfTuples;
7379   for(;w!=end2;w++)
7380     if(*w!=val)
7381       return false;
7382   return true;
7383 }
7384
7385 /*!
7386  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7387  * array to the new one.
7388  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7389  */
7390 DataArrayDouble *DataArrayInt::convertToDblArr() const
7391 {
7392   checkAllocated();
7393   DataArrayDouble *ret=DataArrayDouble::New();
7394   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7395   std::size_t nbOfVals=getNbOfElems();
7396   const int *src=getConstPointer();
7397   double *dest=ret->getPointer();
7398   std::copy(src,src+nbOfVals,dest);
7399   ret->copyStringInfoFrom(*this);
7400   return ret;
7401 }
7402
7403 /*!
7404  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7405  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7406  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7407  * This method is a specialization of selectByTupleId2().
7408  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7409  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7410  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7411  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7412  *          is to delete using decrRef() as it is no more needed.
7413  *  \throw If \a tupleIdBg < 0.
7414  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7415     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7416  *  \sa DataArrayInt::selectByTupleId2
7417  */
7418 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7419 {
7420   checkAllocated();
7421   int nbt=getNumberOfTuples();
7422   if(tupleIdBg<0)
7423     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7424   if(tupleIdBg>nbt)
7425     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7426   int trueEnd=tupleIdEnd;
7427   if(tupleIdEnd!=-1)
7428     {
7429       if(tupleIdEnd>nbt)
7430         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7431     }
7432   else
7433     trueEnd=nbt;
7434   int nbComp=getNumberOfComponents();
7435   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7436   ret->alloc(trueEnd-tupleIdBg,nbComp);
7437   ret->copyStringInfoFrom(*this);
7438   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7439   return ret.retn();
7440 }
7441
7442 /*!
7443  * Changes the number of components within \a this array so that its raw data **does
7444  * not** change, instead splitting this data into tuples changes.
7445  *  \warning This method erases all (name and unit) component info set before!
7446  *  \param [in] newNbOfComp - number of components for \a this array to have.
7447  *  \throw If \a this is not allocated
7448  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7449  *  \throw If \a newNbOfCompo is lower than 1.
7450  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7451  *  \warning This method erases all (name and unit) component info set before!
7452  */
7453 void DataArrayInt::rearrange(int newNbOfCompo)
7454 {
7455   checkAllocated();
7456   if(newNbOfCompo<1)
7457     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7458   std::size_t nbOfElems=getNbOfElems();
7459   if(nbOfElems%newNbOfCompo!=0)
7460     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7461   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7462     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7463   _info_on_compo.clear();
7464   _info_on_compo.resize(newNbOfCompo);
7465   declareAsNew();
7466 }
7467
7468 /*!
7469  * Changes the number of components within \a this array to be equal to its number
7470  * of tuples, and inversely its number of tuples to become equal to its number of 
7471  * components. So that its raw data **does not** change, instead splitting this
7472  * data into tuples changes.
7473  *  \warning This method erases all (name and unit) component info set before!
7474  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7475  *  \throw If \a this is not allocated.
7476  *  \sa rearrange()
7477  */
7478 void DataArrayInt::transpose()
7479 {
7480   checkAllocated();
7481   int nbOfTuples=getNumberOfTuples();
7482   rearrange(nbOfTuples);
7483 }
7484
7485 /*!
7486  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7487  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7488  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7489  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7490  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7491  * components.  
7492  *  \param [in] newNbOfComp - number of components for the new array to have.
7493  *  \param [in] dftValue - value assigned to new values added to the new array.
7494  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7495  *          is to delete using decrRef() as it is no more needed.
7496  *  \throw If \a this is not allocated.
7497  */
7498 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7499 {
7500   checkAllocated();
7501   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7502   ret->alloc(getNumberOfTuples(),newNbOfComp);
7503   const int *oldc=getConstPointer();
7504   int *nc=ret->getPointer();
7505   int nbOfTuples=getNumberOfTuples();
7506   int oldNbOfComp=getNumberOfComponents();
7507   int dim=std::min(oldNbOfComp,newNbOfComp);
7508   for(int i=0;i<nbOfTuples;i++)
7509     {
7510       int j=0;
7511       for(;j<dim;j++)
7512         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7513       for(;j<newNbOfComp;j++)
7514         nc[newNbOfComp*i+j]=dftValue;
7515     }
7516   ret->setName(getName().c_str());
7517   for(int i=0;i<dim;i++)
7518     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7519   ret->setName(getName().c_str());
7520   return ret.retn();
7521 }
7522
7523 /*!
7524  * Changes number of tuples in the array. If the new number of tuples is smaller
7525  * than the current number the array is truncated, otherwise the array is extended.
7526  *  \param [in] nbOfTuples - new number of tuples. 
7527  *  \throw If \a this is not allocated.
7528  *  \throw If \a nbOfTuples is negative.
7529  */
7530 void DataArrayInt::reAlloc(int nbOfTuples)
7531 {
7532   if(nbOfTuples<0)
7533     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7534   checkAllocated();
7535   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7536   declareAsNew();
7537 }
7538
7539
7540 /*!
7541  * Returns a copy of \a this array composed of selected components.
7542  * The new DataArrayInt has the same number of tuples but includes components
7543  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7544  * can be either less, same or more than \a this->getNbOfElems().
7545  *  \param [in] compoIds - sequence of zero based indices of components to include
7546  *              into the new array.
7547  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7548  *          is to delete using decrRef() as it is no more needed.
7549  *  \throw If \a this is not allocated.
7550  *  \throw If a component index (\a i) is not valid: 
7551  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7552  *
7553  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7554  */
7555 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7556 {
7557   checkAllocated();
7558   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7559   int newNbOfCompo=(int)compoIds.size();
7560   int oldNbOfCompo=getNumberOfComponents();
7561   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7562     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7563   int nbOfTuples=getNumberOfTuples();
7564   ret->alloc(nbOfTuples,newNbOfCompo);
7565   ret->copyPartOfStringInfoFrom(*this,compoIds);
7566   const int *oldc=getConstPointer();
7567   int *nc=ret->getPointer();
7568   for(int i=0;i<nbOfTuples;i++)
7569     for(int j=0;j<newNbOfCompo;j++,nc++)
7570       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7571   return ret.retn();
7572 }
7573
7574 /*!
7575  * Appends components of another array to components of \a this one, tuple by tuple.
7576  * So that the number of tuples of \a this array remains the same and the number of 
7577  * components increases.
7578  *  \param [in] other - the DataArrayInt to append to \a this one.
7579  *  \throw If \a this is not allocated.
7580  *  \throw If \a this and \a other arrays have different number of tuples.
7581  *
7582  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7583  *
7584  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7585  */
7586 void DataArrayInt::meldWith(const DataArrayInt *other)
7587 {
7588   if(!other)
7589     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7590   checkAllocated();
7591   other->checkAllocated();
7592   int nbOfTuples=getNumberOfTuples();
7593   if(nbOfTuples!=other->getNumberOfTuples())
7594     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7595   int nbOfComp1=getNumberOfComponents();
7596   int nbOfComp2=other->getNumberOfComponents();
7597   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7598   int *w=newArr;
7599   const int *inp1=getConstPointer();
7600   const int *inp2=other->getConstPointer();
7601   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7602     {
7603       w=std::copy(inp1,inp1+nbOfComp1,w);
7604       w=std::copy(inp2,inp2+nbOfComp2,w);
7605     }
7606   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7607   std::vector<int> compIds(nbOfComp2);
7608   for(int i=0;i<nbOfComp2;i++)
7609     compIds[i]=nbOfComp1+i;
7610   copyPartOfStringInfoFrom2(compIds,*other);
7611 }
7612
7613 /*!
7614  * Copy all components in a specified order from another DataArrayInt.
7615  * The specified components become the first ones in \a this array.
7616  * Both numerical and textual data is copied. The number of tuples in \a this and
7617  * the other array can be different.
7618  *  \param [in] a - the array to copy data from.
7619  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7620  *              to be copied.
7621  *  \throw If \a a is NULL.
7622  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7623  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7624  *
7625  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7626  */
7627 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7628 {
7629   if(!a)
7630     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7631   checkAllocated();
7632   a->checkAllocated();
7633   copyPartOfStringInfoFrom2(compoIds,*a);
7634   std::size_t partOfCompoSz=compoIds.size();
7635   int nbOfCompo=getNumberOfComponents();
7636   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7637   const int *ac=a->getConstPointer();
7638   int *nc=getPointer();
7639   for(int i=0;i<nbOfTuples;i++)
7640     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7641       nc[nbOfCompo*i+compoIds[j]]=*ac;
7642 }
7643
7644 /*!
7645  * Copy all values from another DataArrayInt into specified tuples and components
7646  * of \a this array. Textual data is not copied.
7647  * The tree parameters defining set of indices of tuples and components are similar to
7648  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7649  *  \param [in] a - the array to copy values from.
7650  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7651  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7652  *              are located.
7653  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7654  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7655  *  \param [in] endComp - index of the component before which the components to assign
7656  *              to are located.
7657  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7658  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7659  *              must be equal to the number of columns to assign to, else an
7660  *              exception is thrown; if \a false, then it is only required that \a
7661  *              a->getNbOfElems() equals to number of values to assign to (this condition
7662  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7663  *              values to assign to is given by following Python expression:
7664  *              \a nbTargetValues = 
7665  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7666  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7667  *  \throw If \a a is NULL.
7668  *  \throw If \a a is not allocated.
7669  *  \throw If \a this is not allocated.
7670  *  \throw If parameters specifying tuples and components to assign to do not give a
7671  *            non-empty range of increasing indices.
7672  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7673  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7674  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7675  *
7676  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7677  */
7678 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7679 {
7680   if(!a)
7681     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7682   const char msg[]="DataArrayInt::setPartOfValues1";
7683   checkAllocated();
7684   a->checkAllocated();
7685   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7686   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7687   int nbComp=getNumberOfComponents();
7688   int nbOfTuples=getNumberOfTuples();
7689   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7690   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7691   bool assignTech=true;
7692   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7693     {
7694       if(strictCompoCompare)
7695         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7696     }
7697   else
7698     {
7699       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7700       assignTech=false;
7701     }
7702   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7703   const int *srcPt=a->getConstPointer();
7704   if(assignTech)
7705     {
7706       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7707         for(int j=0;j<newNbOfComp;j++,srcPt++)
7708           pt[j*stepComp]=*srcPt;
7709     }
7710   else
7711     {
7712       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7713         {
7714           const int *srcPt2=srcPt;
7715           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7716             pt[j*stepComp]=*srcPt2;
7717         }
7718     }
7719 }
7720
7721 /*!
7722  * Assign a given value to values at specified tuples and components of \a this array.
7723  * The tree parameters defining set of indices of tuples and components are similar to
7724  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7725  *  \param [in] a - the value to assign.
7726  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7727  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7728  *              are located.
7729  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7730  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7731  *  \param [in] endComp - index of the component before which the components to assign
7732  *              to are located.
7733  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7734  *  \throw If \a this is not allocated.
7735  *  \throw If parameters specifying tuples and components to assign to, do not give a
7736  *            non-empty range of increasing indices or indices are out of a valid range
7737  *            for \this array.
7738  *
7739  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7740  */
7741 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7742 {
7743   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7744   checkAllocated();
7745   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7746   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7747   int nbComp=getNumberOfComponents();
7748   int nbOfTuples=getNumberOfTuples();
7749   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7750   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7751   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7752   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7753     for(int j=0;j<newNbOfComp;j++)
7754       pt[j*stepComp]=a;
7755 }
7756
7757
7758 /*!
7759  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7760  * components of \a this array. Textual data is not copied.
7761  * The tuples and components to assign to are defined by C arrays of indices.
7762  * There are two *modes of usage*:
7763  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7764  *   of \a a is assigned to its own location within \a this array. 
7765  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7766  *   components of every specified tuple of \a this array. In this mode it is required
7767  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7768  * 
7769  *  \param [in] a - the array to copy values from.
7770  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7771  *              assign values of \a a to.
7772  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7773  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7774  *              \a bgTuples <= \a pi < \a endTuples.
7775  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7776  *              assign values of \a a to.
7777  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7778  *              pointer to a component index <em>(pi)</em> varies as this: 
7779  *              \a bgComp <= \a pi < \a endComp.
7780  *  \param [in] strictCompoCompare - this parameter is checked only if the
7781  *               *mode of usage* is the first; if it is \a true (default), 
7782  *               then \a a->getNumberOfComponents() must be equal 
7783  *               to the number of specified columns, else this is not required.
7784  *  \throw If \a a is NULL.
7785  *  \throw If \a a is not allocated.
7786  *  \throw If \a this is not allocated.
7787  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7788  *         out of a valid range for \a this array.
7789  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7790  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7791  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7792  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7793  *
7794  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7795  */
7796 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7797 {
7798   if(!a)
7799     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7800   const char msg[]="DataArrayInt::setPartOfValues2";
7801   checkAllocated();
7802   a->checkAllocated();
7803   int nbComp=getNumberOfComponents();
7804   int nbOfTuples=getNumberOfTuples();
7805   for(const int *z=bgComp;z!=endComp;z++)
7806     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7807   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7808   int newNbOfComp=(int)std::distance(bgComp,endComp);
7809   bool assignTech=true;
7810   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7811     {
7812       if(strictCompoCompare)
7813         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7814     }
7815   else
7816     {
7817       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7818       assignTech=false;
7819     }
7820   int *pt=getPointer();
7821   const int *srcPt=a->getConstPointer();
7822   if(assignTech)
7823     {    
7824       for(const int *w=bgTuples;w!=endTuples;w++)
7825         {
7826           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7827           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7828             {    
7829               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7830             }
7831         }
7832     }
7833   else
7834     {
7835       for(const int *w=bgTuples;w!=endTuples;w++)
7836         {
7837           const int *srcPt2=srcPt;
7838           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7839           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7840             {    
7841               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7842             }
7843         }
7844     }
7845 }
7846
7847 /*!
7848  * Assign a given value to values at specified tuples and components of \a this array.
7849  * The tuples and components to assign to are defined by C arrays of indices.
7850  *  \param [in] a - the value to assign.
7851  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7852  *              assign \a a to.
7853  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7854  *              pointer to a tuple index (\a pi) varies as this: 
7855  *              \a bgTuples <= \a pi < \a endTuples.
7856  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7857  *              assign \a a to.
7858  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7859  *              pointer to a component index (\a pi) varies as this: 
7860  *              \a bgComp <= \a pi < \a endComp.
7861  *  \throw If \a this is not allocated.
7862  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7863  *         out of a valid range for \a this array.
7864  *
7865  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7866  */
7867 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7868 {
7869   checkAllocated();
7870   int nbComp=getNumberOfComponents();
7871   int nbOfTuples=getNumberOfTuples();
7872   for(const int *z=bgComp;z!=endComp;z++)
7873     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7874   int *pt=getPointer();
7875   for(const int *w=bgTuples;w!=endTuples;w++)
7876     for(const int *z=bgComp;z!=endComp;z++)
7877       {
7878         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7879         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7880       }
7881 }
7882
7883 /*!
7884  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7885  * components of \a this array. Textual data is not copied.
7886  * The tuples to assign to are defined by a C array of indices.
7887  * The components to assign to are defined by three values similar to parameters of
7888  * the Python function \c range(\c start,\c stop,\c step).
7889  * There are two *modes of usage*:
7890  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7891  *   of \a a is assigned to its own location within \a this array. 
7892  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7893  *   components of every specified tuple of \a this array. In this mode it is required
7894  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7895  *
7896  *  \param [in] a - the array to copy values from.
7897  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7898  *              assign values of \a a to.
7899  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7900  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7901  *              \a bgTuples <= \a pi < \a endTuples.
7902  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7903  *  \param [in] endComp - index of the component before which the components to assign
7904  *              to are located.
7905  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7906  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7907  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7908  *               then \a a->getNumberOfComponents() must be equal 
7909  *               to the number of specified columns, else this is not required.
7910  *  \throw If \a a is NULL.
7911  *  \throw If \a a is not allocated.
7912  *  \throw If \a this is not allocated.
7913  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7914  *         \a this array.
7915  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7916  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7917  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7918  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7919  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7920  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7921  *  \throw If parameters specifying components to assign to, do not give a
7922  *            non-empty range of increasing indices or indices are out of a valid range
7923  *            for \this array.
7924  *
7925  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7926  */
7927 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7928 {
7929   if(!a)
7930     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7931   const char msg[]="DataArrayInt::setPartOfValues3";
7932   checkAllocated();
7933   a->checkAllocated();
7934   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7935   int nbComp=getNumberOfComponents();
7936   int nbOfTuples=getNumberOfTuples();
7937   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7938   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7939   bool assignTech=true;
7940   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7941     {
7942       if(strictCompoCompare)
7943         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7944     }
7945   else
7946     {
7947       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7948       assignTech=false;
7949     }
7950   int *pt=getPointer()+bgComp;
7951   const int *srcPt=a->getConstPointer();
7952   if(assignTech)
7953     {
7954       for(const int *w=bgTuples;w!=endTuples;w++)
7955         for(int j=0;j<newNbOfComp;j++,srcPt++)
7956           {
7957             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7958             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7959           }
7960     }
7961   else
7962     {
7963       for(const int *w=bgTuples;w!=endTuples;w++)
7964         {
7965           const int *srcPt2=srcPt;
7966           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7967             {
7968               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7969               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7970             }
7971         }
7972     }
7973 }
7974
7975 /*!
7976  * Assign a given value to values at specified tuples and components of \a this array.
7977  * The tuples to assign to are defined by a C array of indices.
7978  * The components to assign to are defined by three values similar to parameters of
7979  * the Python function \c range(\c start,\c stop,\c step).
7980  *  \param [in] a - the value to assign.
7981  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7982  *              assign \a a to.
7983  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7984  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7985  *              \a bgTuples <= \a pi < \a endTuples.
7986  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7987  *  \param [in] endComp - index of the component before which the components to assign
7988  *              to are located.
7989  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7990  *  \throw If \a this is not allocated.
7991  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7992  *         \a this array.
7993  *  \throw If parameters specifying components to assign to, do not give a
7994  *            non-empty range of increasing indices or indices are out of a valid range
7995  *            for \this array.
7996  *
7997  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7998  */
7999 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8000 {
8001   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8002   checkAllocated();
8003   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8004   int nbComp=getNumberOfComponents();
8005   int nbOfTuples=getNumberOfTuples();
8006   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8007   int *pt=getPointer()+bgComp;
8008   for(const int *w=bgTuples;w!=endTuples;w++)
8009     for(int j=0;j<newNbOfComp;j++)
8010       {
8011         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8012         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8013       }
8014 }
8015
8016 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8017 {
8018   if(!a)
8019     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8020   const char msg[]="DataArrayInt::setPartOfValues4";
8021   checkAllocated();
8022   a->checkAllocated();
8023   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8024   int newNbOfComp=(int)std::distance(bgComp,endComp);
8025   int nbComp=getNumberOfComponents();
8026   for(const int *z=bgComp;z!=endComp;z++)
8027     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8028   int nbOfTuples=getNumberOfTuples();
8029   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8030   bool assignTech=true;
8031   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8032     {
8033       if(strictCompoCompare)
8034         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8035     }
8036   else
8037     {
8038       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8039       assignTech=false;
8040     }
8041   const int *srcPt=a->getConstPointer();
8042   int *pt=getPointer()+bgTuples*nbComp;
8043   if(assignTech)
8044     {
8045       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8046         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8047           pt[*z]=*srcPt;
8048     }
8049   else
8050     {
8051       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8052         {
8053           const int *srcPt2=srcPt;
8054           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8055             pt[*z]=*srcPt2;
8056         }
8057     }
8058 }
8059
8060 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8061 {
8062   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8063   checkAllocated();
8064   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8065   int nbComp=getNumberOfComponents();
8066   for(const int *z=bgComp;z!=endComp;z++)
8067     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8068   int nbOfTuples=getNumberOfTuples();
8069   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8070   int *pt=getPointer()+bgTuples*nbComp;
8071   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8072     for(const int *z=bgComp;z!=endComp;z++)
8073       pt[*z]=a;
8074 }
8075
8076 /*!
8077  * Copy some tuples from another DataArrayInt into specified tuples
8078  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8079  * components.
8080  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8081  * All components of selected tuples are copied.
8082  *  \param [in] a - the array to copy values from.
8083  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8084  *              target tuples of \a this. \a tuplesSelec has two components, and the
8085  *              first component specifies index of the source tuple and the second
8086  *              one specifies index of the target tuple.
8087  *  \throw If \a this is not allocated.
8088  *  \throw If \a a is NULL.
8089  *  \throw If \a a is not allocated.
8090  *  \throw If \a tuplesSelec is NULL.
8091  *  \throw If \a tuplesSelec is not allocated.
8092  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8093  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8094  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8095  *         the corresponding (\a this or \a a) array.
8096  */
8097 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8098 {
8099   if(!a || !tuplesSelec)
8100     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8101   checkAllocated();
8102   a->checkAllocated();
8103   tuplesSelec->checkAllocated();
8104   int nbOfComp=getNumberOfComponents();
8105   if(nbOfComp!=a->getNumberOfComponents())
8106     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8107   if(tuplesSelec->getNumberOfComponents()!=2)
8108     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8109   int thisNt=getNumberOfTuples();
8110   int aNt=a->getNumberOfTuples();
8111   int *valsToSet=getPointer();
8112   const int *valsSrc=a->getConstPointer();
8113   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8114     {
8115       if(tuple[1]>=0 && tuple[1]<aNt)
8116         {
8117           if(tuple[0]>=0 && tuple[0]<thisNt)
8118             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8119           else
8120             {
8121               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8122               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8123               throw INTERP_KERNEL::Exception(oss.str().c_str());
8124             }
8125         }
8126       else
8127         {
8128           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8129           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8130           throw INTERP_KERNEL::Exception(oss.str().c_str());
8131         }
8132     }
8133 }
8134
8135 /*!
8136  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8137  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8138  * components.
8139  * The tuples to assign to are defined by index of the first tuple, and
8140  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8141  * The tuples to copy are defined by values of a DataArrayInt.
8142  * All components of selected tuples are copied.
8143  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8144  *              values to.
8145  *  \param [in] aBase - the array to copy values from.
8146  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8147  *  \throw If \a this is not allocated.
8148  *  \throw If \a aBase is NULL.
8149  *  \throw If \a aBase is not allocated.
8150  *  \throw If \a tuplesSelec is NULL.
8151  *  \throw If \a tuplesSelec is not allocated.
8152  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8153  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8154  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8155  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8156  *         \a aBase array.
8157  */
8158 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8159 {
8160   if(!aBase || !tuplesSelec)
8161     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8162   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8163   if(!a)
8164     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8165   checkAllocated();
8166   a->checkAllocated();
8167   tuplesSelec->checkAllocated();
8168   int nbOfComp=getNumberOfComponents();
8169   if(nbOfComp!=a->getNumberOfComponents())
8170     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8171   if(tuplesSelec->getNumberOfComponents()!=1)
8172     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8173   int thisNt=getNumberOfTuples();
8174   int aNt=a->getNumberOfTuples();
8175   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8176   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8177   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8178     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8179   const int *valsSrc=a->getConstPointer();
8180   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8181     {
8182       if(*tuple>=0 && *tuple<aNt)
8183         {
8184           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8185         }
8186       else
8187         {
8188           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8189           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8190           throw INTERP_KERNEL::Exception(oss.str().c_str());
8191         }
8192     }
8193 }
8194
8195 /*!
8196  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8197  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8198  * components.
8199  * The tuples to copy are defined by three values similar to parameters of
8200  * the Python function \c range(\c start,\c stop,\c step).
8201  * The tuples to assign to are defined by index of the first tuple, and
8202  * their number is defined by number of tuples to copy.
8203  * All components of selected tuples are copied.
8204  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8205  *              values to.
8206  *  \param [in] aBase - the array to copy values from.
8207  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8208  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8209  *              are located.
8210  *  \param [in] step - index increment to get index of the next tuple to copy.
8211  *  \throw If \a this is not allocated.
8212  *  \throw If \a aBase is NULL.
8213  *  \throw If \a aBase is not allocated.
8214  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8215  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8216  *  \throw If parameters specifying tuples to copy, do not give a
8217  *            non-empty range of increasing indices or indices are out of a valid range
8218  *            for the array \a aBase.
8219  */
8220 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8221 {
8222   if(!aBase)
8223     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8224   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8225   if(!a)
8226     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8227   checkAllocated();
8228   a->checkAllocated();
8229   int nbOfComp=getNumberOfComponents();
8230   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8231   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8232   if(nbOfComp!=a->getNumberOfComponents())
8233     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8234   int thisNt=getNumberOfTuples();
8235   int aNt=a->getNumberOfTuples();
8236   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8237   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8238     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8239   if(end2>aNt)
8240     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8241   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8242   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8243     {
8244       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8245     }
8246 }
8247
8248 /*!
8249  * Returns a value located at specified tuple and component.
8250  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8251  * parameters is checked. So this method is safe but expensive if used to go through
8252  * all values of \a this.
8253  *  \param [in] tupleId - index of tuple of interest.
8254  *  \param [in] compoId - index of component of interest.
8255  *  \return double - value located by \a tupleId and \a compoId.
8256  *  \throw If \a this is not allocated.
8257  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8258  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8259  */
8260 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8261 {
8262   checkAllocated();
8263   if(tupleId<0 || tupleId>=getNumberOfTuples())
8264     {
8265       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8266       throw INTERP_KERNEL::Exception(oss.str().c_str());
8267     }
8268   if(compoId<0 || compoId>=getNumberOfComponents())
8269     {
8270       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8271       throw INTERP_KERNEL::Exception(oss.str().c_str());
8272     }
8273   return _mem[tupleId*_info_on_compo.size()+compoId];
8274 }
8275
8276 /*!
8277  * Returns the first value of \a this. 
8278  *  \return int - the last value of \a this array.
8279  *  \throw If \a this is not allocated.
8280  *  \throw If \a this->getNumberOfComponents() != 1.
8281  *  \throw If \a this->getNumberOfTuples() < 1.
8282  */
8283 int DataArrayInt::front() const
8284 {
8285   checkAllocated();
8286   if(getNumberOfComponents()!=1)
8287     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8288   int nbOfTuples=getNumberOfTuples();
8289   if(nbOfTuples<1)
8290     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8291   return *(getConstPointer());
8292 }
8293
8294 /*!
8295  * Returns the last value of \a this. 
8296  *  \return int - the last value of \a this array.
8297  *  \throw If \a this is not allocated.
8298  *  \throw If \a this->getNumberOfComponents() != 1.
8299  *  \throw If \a this->getNumberOfTuples() < 1.
8300  */
8301 int DataArrayInt::back() const
8302 {
8303   checkAllocated();
8304   if(getNumberOfComponents()!=1)
8305     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8306   int nbOfTuples=getNumberOfTuples();
8307   if(nbOfTuples<1)
8308     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8309   return *(getConstPointer()+nbOfTuples-1);
8310 }
8311
8312 /*!
8313  * Assign pointer to one array to a pointer to another appay. Reference counter of
8314  * \a arrayToSet is incremented / decremented.
8315  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8316  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8317  */
8318 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8319 {
8320   if(newArray!=arrayToSet)
8321     {
8322       if(arrayToSet)
8323         arrayToSet->decrRef();
8324       arrayToSet=newArray;
8325       if(arrayToSet)
8326         arrayToSet->incrRef();
8327     }
8328 }
8329
8330 DataArrayIntIterator *DataArrayInt::iterator()
8331 {
8332   return new DataArrayIntIterator(this);
8333 }
8334
8335 /*!
8336  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8337  * given one.
8338  *  \param [in] val - the value to find within \a this.
8339  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8340  *          array using decrRef() as it is no more needed.
8341  *  \throw If \a this is not allocated.
8342  *  \throw If \a this->getNumberOfComponents() != 1.
8343  */
8344 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8345 {
8346   checkAllocated();
8347   if(getNumberOfComponents()!=1)
8348     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8349   const int *cptr=getConstPointer();
8350   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8351   int nbOfTuples=getNumberOfTuples();
8352   for(int i=0;i<nbOfTuples;i++,cptr++)
8353     if(*cptr==val)
8354       ret->pushBackSilent(i);
8355   return ret.retn();
8356 }
8357
8358 /*!
8359  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8360  * equal to a given one. 
8361  *  \param [in] val - the value to ignore within \a this.
8362  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8363  *          array using decrRef() as it is no more needed.
8364  *  \throw If \a this is not allocated.
8365  *  \throw If \a this->getNumberOfComponents() != 1.
8366  */
8367 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8368 {
8369   checkAllocated();
8370   if(getNumberOfComponents()!=1)
8371     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8372   const int *cptr=getConstPointer();
8373   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8374   int nbOfTuples=getNumberOfTuples();
8375   for(int i=0;i<nbOfTuples;i++,cptr++)
8376     if(*cptr!=val)
8377       ret->pushBackSilent(i);
8378   return ret.retn();
8379 }
8380
8381
8382 /*!
8383  * Assigns \a newValue to all elements holding \a oldValue within \a this
8384  * one-dimensional array.
8385  *  \param [in] oldValue - the value to replace.
8386  *  \param [in] newValue - the value to assign.
8387  *  \return int - number of replacements performed.
8388  *  \throw If \a this is not allocated.
8389  *  \throw If \a this->getNumberOfComponents() != 1.
8390  */
8391 int DataArrayInt::changeValue(int oldValue, int newValue)
8392 {
8393   checkAllocated();
8394   if(getNumberOfComponents()!=1)
8395     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8396   int *start=getPointer();
8397   int *end2=start+getNbOfElems();
8398   int ret=0;
8399   for(int *val=start;val!=end2;val++)
8400     {
8401       if(*val==oldValue)
8402         {
8403           *val=newValue;
8404           ret++;
8405         }
8406     }
8407   return ret;
8408 }
8409
8410 /*!
8411  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8412  * one of given values.
8413  *  \param [in] valsBg - an array of values to find within \a this array.
8414  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8415  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8416  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8417  *          array using decrRef() as it is no more needed.
8418  *  \throw If \a this->getNumberOfComponents() != 1.
8419  */
8420 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8421 {
8422   if(getNumberOfComponents()!=1)
8423     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8424   std::set<int> vals2(valsBg,valsEnd);
8425   const int *cptr=getConstPointer();
8426   std::vector<int> res;
8427   int nbOfTuples=getNumberOfTuples();
8428   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8429   for(int i=0;i<nbOfTuples;i++,cptr++)
8430     if(vals2.find(*cptr)!=vals2.end())
8431       ret->pushBackSilent(i);
8432   return ret.retn();
8433 }
8434
8435 /*!
8436  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8437  * equal to any of given values.
8438  *  \param [in] valsBg - an array of values to ignore within \a this array.
8439  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8440  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8441  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8442  *          array using decrRef() as it is no more needed.
8443  *  \throw If \a this->getNumberOfComponents() != 1.
8444  */
8445 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8446 {
8447   if(getNumberOfComponents()!=1)
8448     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8449   std::set<int> vals2(valsBg,valsEnd);
8450   const int *cptr=getConstPointer();
8451   std::vector<int> res;
8452   int nbOfTuples=getNumberOfTuples();
8453   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8454   for(int i=0;i<nbOfTuples;i++,cptr++)
8455     if(vals2.find(*cptr)==vals2.end())
8456       ret->pushBackSilent(i);
8457   return ret.retn();
8458 }
8459
8460 /*!
8461  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8462  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8463  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8464  * If any the tuple id is returned. If not -1 is returned.
8465  * 
8466  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8467  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8468  *
8469  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8470  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8471  */
8472 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8473 {
8474   checkAllocated();
8475   int nbOfCompo=getNumberOfComponents();
8476   if(nbOfCompo==0)
8477     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8478   if(nbOfCompo!=(int)tupl.size())
8479     {
8480       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8481       throw INTERP_KERNEL::Exception(oss.str().c_str());
8482     }
8483   const int *cptr=getConstPointer();
8484   std::size_t nbOfVals=getNbOfElems();
8485   for(const int *work=cptr;work!=cptr+nbOfVals;)
8486     {
8487       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8488       if(work!=cptr+nbOfVals)
8489         {
8490           if(std::distance(cptr,work)%nbOfCompo!=0)
8491             work++;
8492           else
8493             return std::distance(cptr,work)/nbOfCompo;
8494         }
8495     }
8496   return -1;
8497 }
8498
8499 /*!
8500  * This method searches the sequence specified in input parameter \b vals in \b this.
8501  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8502  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8503  * \sa DataArrayInt::locateTuple
8504  */
8505 int DataArrayInt::search(const std::vector<int>& vals) const
8506 {
8507   checkAllocated();
8508   int nbOfCompo=getNumberOfComponents();
8509   if(nbOfCompo!=1)
8510     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8511   const int *cptr=getConstPointer();
8512   std::size_t nbOfVals=getNbOfElems();
8513   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8514   if(loc!=cptr+nbOfVals)
8515     return std::distance(cptr,loc);
8516   return -1;
8517 }
8518
8519 /*!
8520  * This method expects to be called when number of components of this is equal to one.
8521  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8522  * If not any tuple contains \b value -1 is returned.
8523  * \sa DataArrayInt::presenceOfValue
8524  */
8525 int DataArrayInt::locateValue(int value) const
8526 {
8527   checkAllocated();
8528   if(getNumberOfComponents()!=1)
8529     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8530   const int *cptr=getConstPointer();
8531   int nbOfTuples=getNumberOfTuples();
8532   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8533   if(ret!=cptr+nbOfTuples)
8534     return std::distance(cptr,ret);
8535   return -1;
8536 }
8537
8538 /*!
8539  * This method expects to be called when number of components of this is equal to one.
8540  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8541  * If not any tuple contains one of the values contained in 'vals' false is returned.
8542  * \sa DataArrayInt::presenceOfValue
8543  */
8544 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8545 {
8546   checkAllocated();
8547   if(getNumberOfComponents()!=1)
8548     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8549   std::set<int> vals2(vals.begin(),vals.end());
8550   const int *cptr=getConstPointer();
8551   int nbOfTuples=getNumberOfTuples();
8552   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8553     if(vals2.find(*w)!=vals2.end())
8554       return std::distance(cptr,w);
8555   return -1;
8556 }
8557
8558 /*!
8559  * This method returns the number of values in \a this that are equals to input parameter \a value.
8560  * This method only works for single component array.
8561  *
8562  * \return a value in [ 0, \c this->getNumberOfTuples() )
8563  *
8564  * \throw If \a this is not allocated
8565  *
8566  */
8567 int DataArrayInt::count(int value) const
8568 {
8569   int ret=0;
8570   checkAllocated();
8571   if(getNumberOfComponents()!=1)
8572     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8573   const int *vals=begin();
8574   int nbOfTuples=getNumberOfTuples();
8575   for(int i=0;i<nbOfTuples;i++,vals++)
8576     if(*vals==value)
8577       ret++;
8578   return ret;
8579 }
8580
8581 /*!
8582  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8583  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8584  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8585  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8586  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8587  * \sa DataArrayInt::locateTuple
8588  */
8589 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8590 {
8591   return locateTuple(tupl)!=-1;
8592 }
8593
8594
8595 /*!
8596  * Returns \a true if a given value is present within \a this one-dimensional array.
8597  *  \param [in] value - the value to find within \a this array.
8598  *  \return bool - \a true in case if \a value is present within \a this array.
8599  *  \throw If \a this is not allocated.
8600  *  \throw If \a this->getNumberOfComponents() != 1.
8601  *  \sa locateValue()
8602  */
8603 bool DataArrayInt::presenceOfValue(int value) const
8604 {
8605   return locateValue(value)!=-1;
8606 }
8607
8608 /*!
8609  * This method expects to be called when number of components of this is equal to one.
8610  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8611  * If not any tuple contains one of the values contained in 'vals' false is returned.
8612  * \sa DataArrayInt::locateValue
8613  */
8614 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8615 {
8616   return locateValue(vals)!=-1;
8617 }
8618
8619 /*!
8620  * Accumulates values of each component of \a this array.
8621  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8622  *         by the caller, that is filled by this method with sum value for each
8623  *         component.
8624  *  \throw If \a this is not allocated.
8625  */
8626 void DataArrayInt::accumulate(int *res) const
8627 {
8628   checkAllocated();
8629   const int *ptr=getConstPointer();
8630   int nbTuple=getNumberOfTuples();
8631   int nbComps=getNumberOfComponents();
8632   std::fill(res,res+nbComps,0);
8633   for(int i=0;i<nbTuple;i++)
8634     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8635 }
8636
8637 int DataArrayInt::accumulate(int compId) const
8638 {
8639   checkAllocated();
8640   const int *ptr=getConstPointer();
8641   int nbTuple=getNumberOfTuples();
8642   int nbComps=getNumberOfComponents();
8643   if(compId<0 || compId>=nbComps)
8644     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8645   int ret=0;
8646   for(int i=0;i<nbTuple;i++)
8647     ret+=ptr[i*nbComps+compId];
8648   return ret;
8649 }
8650
8651 /*!
8652  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8653  * The returned array will have same number of components than \a this and number of tuples equal to
8654  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8655  *
8656  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8657  *
8658  * \param [in] bgOfIndex - begin (included) of the input index array.
8659  * \param [in] endOfIndex - end (excluded) of the input index array.
8660  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8661  * 
8662  * \throw If bgOfIndex or end is NULL.
8663  * \throw If input index array is not ascendingly sorted.
8664  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8665  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8666  */
8667 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8668 {
8669   if(!bgOfIndex || !endOfIndex)
8670     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8671   checkAllocated();
8672   int nbCompo=getNumberOfComponents();
8673   int nbOfTuples=getNumberOfTuples();
8674   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8675   if(sz<1)
8676     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8677   sz--;
8678   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8679   const int *w=bgOfIndex;
8680   if(*w<0 || *w>=nbOfTuples)
8681     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8682   const int *srcPt=begin()+(*w)*nbCompo;
8683   int *tmp=ret->getPointer();
8684   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8685     {
8686       std::fill(tmp,tmp+nbCompo,0);
8687       if(w[1]>=w[0])
8688         {
8689           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8690             {
8691               if(j>=0 && j<nbOfTuples)
8692                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8693               else
8694                 {
8695                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8696                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8697                 }
8698             }
8699         }
8700       else
8701         {
8702           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8703           throw INTERP_KERNEL::Exception(oss.str().c_str());
8704         }
8705     }
8706   ret->copyStringInfoFrom(*this);
8707   return ret.retn();
8708 }
8709
8710 /*!
8711  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8712  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8713  * offsetA2</em> and (2)
8714  * the number of component in the result array is same as that of each of given arrays.
8715  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8716  * Info on components is copied from the first of the given arrays. Number of components
8717  * in the given arrays must be the same.
8718  *  \param [in] a1 - an array to include in the result array.
8719  *  \param [in] a2 - another array to include in the result array.
8720  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8721  *  \return DataArrayInt * - the new instance of DataArrayInt.
8722  *          The caller is to delete this result array using decrRef() as it is no more
8723  *          needed.
8724  *  \throw If either \a a1 or \a a2 is NULL.
8725  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8726  */
8727 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8728 {
8729   if(!a1 || !a2)
8730     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8731   int nbOfComp=a1->getNumberOfComponents();
8732   if(nbOfComp!=a2->getNumberOfComponents())
8733     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8734   int nbOfTuple1=a1->getNumberOfTuples();
8735   int nbOfTuple2=a2->getNumberOfTuples();
8736   DataArrayInt *ret=DataArrayInt::New();
8737   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8738   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8739   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8740   ret->copyStringInfoFrom(*a1);
8741   return ret;
8742 }
8743
8744 /*!
8745  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8746  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8747  * the number of component in the result array is same as that of each of given arrays.
8748  * Info on components is copied from the first of the given arrays. Number of components
8749  * in the given arrays must be  the same.
8750  *  \param [in] arr - a sequence of arrays to include in the result array.
8751  *  \return DataArrayInt * - the new instance of DataArrayInt.
8752  *          The caller is to delete this result array using decrRef() as it is no more
8753  *          needed.
8754  *  \throw If all arrays within \a arr are NULL.
8755  *  \throw If getNumberOfComponents() of arrays within \a arr.
8756  */
8757 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8758 {
8759   std::vector<const DataArrayInt *> a;
8760   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8761     if(*it4)
8762       a.push_back(*it4);
8763   if(a.empty())
8764     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8765   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8766   int nbOfComp=(*it)->getNumberOfComponents();
8767   int nbt=(*it++)->getNumberOfTuples();
8768   for(int i=1;it!=a.end();it++,i++)
8769     {
8770       if((*it)->getNumberOfComponents()!=nbOfComp)
8771         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8772       nbt+=(*it)->getNumberOfTuples();
8773     }
8774   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8775   ret->alloc(nbt,nbOfComp);
8776   int *pt=ret->getPointer();
8777   for(it=a.begin();it!=a.end();it++)
8778     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8779   ret->copyStringInfoFrom(*(a[0]));
8780   return ret.retn();
8781 }
8782
8783 /*!
8784  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8785  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8786  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8787  * 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.
8788  * 
8789  * \return DataArrayInt * - a new object to be managed by the caller.
8790  */
8791 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8792 {
8793   int retSz=1;
8794   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8795     {
8796       if(*it4)
8797         {
8798           (*it4)->checkAllocated();
8799           if((*it4)->getNumberOfComponents()!=1)
8800             {
8801               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8802               throw INTERP_KERNEL::Exception(oss.str().c_str());
8803             }
8804           int nbTupl=(*it4)->getNumberOfTuples();
8805           if(nbTupl<1)
8806             {
8807               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8808               throw INTERP_KERNEL::Exception(oss.str().c_str());
8809             }
8810           if((*it4)->front()!=0)
8811             {
8812               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8813               throw INTERP_KERNEL::Exception(oss.str().c_str());
8814             }
8815           retSz+=nbTupl-1;
8816         }
8817       else
8818         {
8819           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8820           throw INTERP_KERNEL::Exception(oss.str().c_str());
8821         }
8822     }
8823   if(arrs.empty())
8824     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8825   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8826   ret->alloc(retSz,1);
8827   int *pt=ret->getPointer(); *pt++=0;
8828   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8829     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8830   ret->copyStringInfoFrom(*(arrs[0]));
8831   return ret.retn();
8832 }
8833
8834 /*!
8835  * Returns the maximal value and its location within \a this one-dimensional array.
8836  *  \param [out] tupleId - index of the tuple holding the maximal value.
8837  *  \return int - the maximal value among all values of \a this array.
8838  *  \throw If \a this->getNumberOfComponents() != 1
8839  *  \throw If \a this->getNumberOfTuples() < 1
8840  */
8841 int DataArrayInt::getMaxValue(int& tupleId) const
8842 {
8843   checkAllocated();
8844   if(getNumberOfComponents()!=1)
8845     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8846   int nbOfTuples=getNumberOfTuples();
8847   if(nbOfTuples<=0)
8848     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8849   const int *vals=getConstPointer();
8850   const int *loc=std::max_element(vals,vals+nbOfTuples);
8851   tupleId=(int)std::distance(vals,loc);
8852   return *loc;
8853 }
8854
8855 /*!
8856  * Returns the maximal value within \a this array that is allowed to have more than
8857  *  one component.
8858  *  \return int - the maximal value among all values of \a this array.
8859  *  \throw If \a this is not allocated.
8860  */
8861 int DataArrayInt::getMaxValueInArray() const
8862 {
8863   checkAllocated();
8864   const int *loc=std::max_element(begin(),end());
8865   return *loc;
8866 }
8867
8868 /*!
8869  * Returns the minimal value and its location within \a this one-dimensional array.
8870  *  \param [out] tupleId - index of the tuple holding the minimal value.
8871  *  \return int - the minimal value among all values of \a this array.
8872  *  \throw If \a this->getNumberOfComponents() != 1
8873  *  \throw If \a this->getNumberOfTuples() < 1
8874  */
8875 int DataArrayInt::getMinValue(int& tupleId) const
8876 {
8877   checkAllocated();
8878   if(getNumberOfComponents()!=1)
8879     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8880   int nbOfTuples=getNumberOfTuples();
8881   if(nbOfTuples<=0)
8882     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8883   const int *vals=getConstPointer();
8884   const int *loc=std::min_element(vals,vals+nbOfTuples);
8885   tupleId=(int)std::distance(vals,loc);
8886   return *loc;
8887 }
8888
8889 /*!
8890  * Returns the minimal value within \a this array that is allowed to have more than
8891  *  one component.
8892  *  \return int - the minimal value among all values of \a this array.
8893  *  \throw If \a this is not allocated.
8894  */
8895 int DataArrayInt::getMinValueInArray() const
8896 {
8897   checkAllocated();
8898   const int *loc=std::min_element(begin(),end());
8899   return *loc;
8900 }
8901
8902 /*!
8903  * Converts every value of \a this array to its absolute value.
8904  *  \throw If \a this is not allocated.
8905  */
8906 void DataArrayInt::abs()
8907 {
8908   checkAllocated();
8909   int *ptr=getPointer();
8910   std::size_t nbOfElems=getNbOfElems();
8911   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8912   declareAsNew();
8913 }
8914
8915 /*!
8916  * Apply a liner function to a given component of \a this array, so that
8917  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8918  *  \param [in] a - the first coefficient of the function.
8919  *  \param [in] b - the second coefficient of the function.
8920  *  \param [in] compoId - the index of component to modify.
8921  *  \throw If \a this is not allocated.
8922  */
8923 void DataArrayInt::applyLin(int a, int b, int compoId)
8924 {
8925   checkAllocated();
8926   int *ptr=getPointer()+compoId;
8927   int nbOfComp=getNumberOfComponents();
8928   int nbOfTuple=getNumberOfTuples();
8929   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8930     *ptr=a*(*ptr)+b;
8931   declareAsNew();
8932 }
8933
8934 /*!
8935  * Apply a liner function to all elements of \a this array, so that
8936  * an element _x_ becomes \f$ a * x + b \f$.
8937  *  \param [in] a - the first coefficient of the function.
8938  *  \param [in] b - the second coefficient of the function.
8939  *  \throw If \a this is not allocated.
8940  */
8941 void DataArrayInt::applyLin(int a, int b)
8942 {
8943   checkAllocated();
8944   int *ptr=getPointer();
8945   std::size_t nbOfElems=getNbOfElems();
8946   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8947     *ptr=a*(*ptr)+b;
8948   declareAsNew();
8949 }
8950
8951 /*!
8952  * Returns a full copy of \a this array except that sign of all elements is reversed.
8953  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8954  *          same number of tuples and component as \a this array.
8955  *          The caller is to delete this result array using decrRef() as it is no more
8956  *          needed.
8957  *  \throw If \a this is not allocated.
8958  */
8959 DataArrayInt *DataArrayInt::negate() const
8960 {
8961   checkAllocated();
8962   DataArrayInt *newArr=DataArrayInt::New();
8963   int nbOfTuples=getNumberOfTuples();
8964   int nbOfComp=getNumberOfComponents();
8965   newArr->alloc(nbOfTuples,nbOfComp);
8966   const int *cptr=getConstPointer();
8967   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8968   newArr->copyStringInfoFrom(*this);
8969   return newArr;
8970 }
8971
8972 /*!
8973  * Modify all elements of \a this array, so that
8974  * an element _x_ becomes \f$ numerator / x \f$.
8975  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8976  *           array, all elements processed before detection of the zero element remain
8977  *           modified.
8978  *  \param [in] numerator - the numerator used to modify array elements.
8979  *  \throw If \a this is not allocated.
8980  *  \throw If there is an element equal to 0 in \a this array.
8981  */
8982 void DataArrayInt::applyInv(int numerator)
8983 {
8984   checkAllocated();
8985   int *ptr=getPointer();
8986   std::size_t nbOfElems=getNbOfElems();
8987   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8988     {
8989       if(*ptr!=0)
8990         {
8991           *ptr=numerator/(*ptr);
8992         }
8993       else
8994         {
8995           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8996           oss << " !";
8997           throw INTERP_KERNEL::Exception(oss.str().c_str());
8998         }
8999     }
9000   declareAsNew();
9001 }
9002
9003 /*!
9004  * Modify all elements of \a this array, so that
9005  * an element _x_ becomes \f$ x / val \f$.
9006  *  \param [in] val - the denominator used to modify array elements.
9007  *  \throw If \a this is not allocated.
9008  *  \throw If \a val == 0.
9009  */
9010 void DataArrayInt::applyDivideBy(int val)
9011 {
9012   if(val==0)
9013     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9014   checkAllocated();
9015   int *ptr=getPointer();
9016   std::size_t nbOfElems=getNbOfElems();
9017   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9018   declareAsNew();
9019 }
9020
9021 /*!
9022  * Modify all elements of \a this array, so that
9023  * an element _x_ becomes  <em> x % val </em>.
9024  *  \param [in] val - the divisor used to modify array elements.
9025  *  \throw If \a this is not allocated.
9026  *  \throw If \a val <= 0.
9027  */
9028 void DataArrayInt::applyModulus(int val)
9029 {
9030   if(val<=0)
9031     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9032   checkAllocated();
9033   int *ptr=getPointer();
9034   std::size_t nbOfElems=getNbOfElems();
9035   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9036   declareAsNew();
9037 }
9038
9039 /*!
9040  * This method works only on data array with one component.
9041  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9042  * this[*id] in [\b vmin,\b vmax)
9043  * 
9044  * \param [in] vmin begin of range. This value is included in range (included).
9045  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9046  * \return a newly allocated data array that the caller should deal with.
9047  *
9048  * \sa DataArrayInt::getIdsNotInRange
9049  */
9050 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9051 {
9052   checkAllocated();
9053   if(getNumberOfComponents()!=1)
9054     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9055   const int *cptr(begin());
9056   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9057   int nbOfTuples(getNumberOfTuples());
9058   for(int i=0;i<nbOfTuples;i++,cptr++)
9059     if(*cptr>=vmin && *cptr<vmax)
9060       ret->pushBackSilent(i);
9061   return ret.retn();
9062 }
9063
9064 /*!
9065  * This method works only on data array with one component.
9066  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9067  * this[*id] \b not in [\b vmin,\b vmax)
9068  * 
9069  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9070  * \param [in] vmax end of range. This value is included in range (included).
9071  * \return a newly allocated data array that the caller should deal with.
9072  * 
9073  * \sa DataArrayInt::getIdsInRange
9074  */
9075 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9076 {
9077   checkAllocated();
9078   if(getNumberOfComponents()!=1)
9079     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9080   const int *cptr(getConstPointer());
9081   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9082   int nbOfTuples(getNumberOfTuples());
9083   for(int i=0;i<nbOfTuples;i++,cptr++)
9084     if(*cptr<vmin || *cptr>=vmax)
9085       ret->pushBackSilent(i);
9086   return ret.retn();
9087 }
9088
9089 /*!
9090  * This method works only on data array with one component.
9091  * 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.
9092  * 
9093  * \param [in] vmin begin of range. This value is included in range (included).
9094  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9095  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9096 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9097 {
9098   checkAllocated();
9099   if(getNumberOfComponents()!=1)
9100     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9101   int nbOfTuples=getNumberOfTuples();
9102   bool ret=true;
9103   const int *cptr=getConstPointer();
9104   for(int i=0;i<nbOfTuples;i++,cptr++)
9105     {
9106       if(*cptr>=vmin && *cptr<vmax)
9107         { ret=ret && *cptr==i; }
9108       else
9109         {
9110           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9111           throw INTERP_KERNEL::Exception(oss.str().c_str());
9112         }
9113     }
9114   return ret;
9115 }
9116
9117 /*!
9118  * Modify all elements of \a this array, so that
9119  * an element _x_ becomes <em> val % x </em>.
9120  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9121  *           array, all elements processed before detection of the zero element remain
9122  *           modified.
9123  *  \param [in] val - the divident used to modify array elements.
9124  *  \throw If \a this is not allocated.
9125  *  \throw If there is an element equal to or less than 0 in \a this array.
9126  */
9127 void DataArrayInt::applyRModulus(int val)
9128 {
9129   checkAllocated();
9130   int *ptr=getPointer();
9131   std::size_t nbOfElems=getNbOfElems();
9132   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9133     {
9134       if(*ptr>0)
9135         {
9136           *ptr=val%(*ptr);
9137         }
9138       else
9139         {
9140           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9141           oss << " !";
9142           throw INTERP_KERNEL::Exception(oss.str().c_str());
9143         }
9144     }
9145   declareAsNew();
9146 }
9147
9148 /*!
9149  * Modify all elements of \a this array, so that
9150  * an element _x_ becomes <em> val ^ x </em>.
9151  *  \param [in] val - the value used to apply pow on all array elements.
9152  *  \throw If \a this is not allocated.
9153  *  \throw If \a val < 0.
9154  */
9155 void DataArrayInt::applyPow(int val)
9156 {
9157   checkAllocated();
9158   if(val<0)
9159     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9160   int *ptr=getPointer();
9161   std::size_t nbOfElems=getNbOfElems();
9162   if(val==0)
9163     {
9164       std::fill(ptr,ptr+nbOfElems,1);
9165       return ;
9166     }
9167   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9168     {
9169       int tmp=1;
9170       for(int j=0;j<val;j++)
9171         tmp*=*ptr;
9172       *ptr=tmp;
9173     }
9174   declareAsNew();
9175 }
9176
9177 /*!
9178  * Modify all elements of \a this array, so that
9179  * an element _x_ becomes \f$ val ^ x \f$.
9180  *  \param [in] val - the value used to apply pow on all array elements.
9181  *  \throw If \a this is not allocated.
9182  *  \throw If there is an element < 0 in \a this array.
9183  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9184  *           array, all elements processed before detection of the zero element remain
9185  *           modified.
9186  */
9187 void DataArrayInt::applyRPow(int val)
9188 {
9189   checkAllocated();
9190   int *ptr=getPointer();
9191   std::size_t nbOfElems=getNbOfElems();
9192   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9193     {
9194       if(*ptr>=0)
9195         {
9196           int tmp=1;
9197           for(int j=0;j<*ptr;j++)
9198             tmp*=val;
9199           *ptr=tmp;
9200         }
9201       else
9202         {
9203           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9204           oss << " !";
9205           throw INTERP_KERNEL::Exception(oss.str().c_str());
9206         }
9207     }
9208   declareAsNew();
9209 }
9210
9211 /*!
9212  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9213  * of components in the result array is a sum of the number of components of given arrays
9214  * and (2) the number of tuples in the result array is same as that of each of given
9215  * arrays. In other words the i-th tuple of result array includes all components of
9216  * i-th tuples of all given arrays.
9217  * Number of tuples in the given arrays must be the same.
9218  *  \param [in] a1 - an array to include in the result array.
9219  *  \param [in] a2 - another array to include in the result array.
9220  *  \return DataArrayInt * - the new instance of DataArrayInt.
9221  *          The caller is to delete this result array using decrRef() as it is no more
9222  *          needed.
9223  *  \throw If both \a a1 and \a a2 are NULL.
9224  *  \throw If any given array is not allocated.
9225  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9226  */
9227 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9228 {
9229   std::vector<const DataArrayInt *> arr(2);
9230   arr[0]=a1; arr[1]=a2;
9231   return Meld(arr);
9232 }
9233
9234 /*!
9235  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9236  * of components in the result array is a sum of the number of components of given arrays
9237  * and (2) the number of tuples in the result array is same as that of each of given
9238  * arrays. In other words the i-th tuple of result array includes all components of
9239  * i-th tuples of all given arrays.
9240  * Number of tuples in the given arrays must be  the same.
9241  *  \param [in] arr - a sequence of arrays to include in the result array.
9242  *  \return DataArrayInt * - the new instance of DataArrayInt.
9243  *          The caller is to delete this result array using decrRef() as it is no more
9244  *          needed.
9245  *  \throw If all arrays within \a arr are NULL.
9246  *  \throw If any given array is not allocated.
9247  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9248  */
9249 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9250 {
9251   std::vector<const DataArrayInt *> a;
9252   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9253     if(*it4)
9254       a.push_back(*it4);
9255   if(a.empty())
9256     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9257   std::vector<const DataArrayInt *>::const_iterator it;
9258   for(it=a.begin();it!=a.end();it++)
9259     (*it)->checkAllocated();
9260   it=a.begin();
9261   int nbOfTuples=(*it)->getNumberOfTuples();
9262   std::vector<int> nbc(a.size());
9263   std::vector<const int *> pts(a.size());
9264   nbc[0]=(*it)->getNumberOfComponents();
9265   pts[0]=(*it++)->getConstPointer();
9266   for(int i=1;it!=a.end();it++,i++)
9267     {
9268       if(nbOfTuples!=(*it)->getNumberOfTuples())
9269         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9270       nbc[i]=(*it)->getNumberOfComponents();
9271       pts[i]=(*it)->getConstPointer();
9272     }
9273   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9274   DataArrayInt *ret=DataArrayInt::New();
9275   ret->alloc(nbOfTuples,totalNbOfComp);
9276   int *retPtr=ret->getPointer();
9277   for(int i=0;i<nbOfTuples;i++)
9278     for(int j=0;j<(int)a.size();j++)
9279       {
9280         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9281         pts[j]+=nbc[j];
9282       }
9283   int k=0;
9284   for(int i=0;i<(int)a.size();i++)
9285     for(int j=0;j<nbc[i];j++,k++)
9286       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9287   return ret;
9288 }
9289
9290 /*!
9291  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9292  * The i-th item of the result array is an ID of a set of elements belonging to a
9293  * unique set of groups, which the i-th element is a part of. This set of elements
9294  * belonging to a unique set of groups is called \a family, so the result array contains
9295  * IDs of families each element belongs to.
9296  *
9297  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9298  * then there are 3 families:
9299  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9300  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9301  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9302  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9303  * stands for the element #3 which is in none of groups.
9304  *
9305  *  \param [in] groups - sequence of groups of element IDs.
9306  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9307  *         in \a groups.
9308  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9309  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9310  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9311  *         delete this array using decrRef() as it is no more needed.
9312  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9313  */
9314 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9315 {
9316   std::vector<const DataArrayInt *> groups2;
9317   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9318     if(*it4)
9319       groups2.push_back(*it4);
9320   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9321   ret->alloc(newNb,1);
9322   int *retPtr=ret->getPointer();
9323   std::fill(retPtr,retPtr+newNb,0);
9324   int fid=1;
9325   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9326     {
9327       const int *ptr=(*iter)->getConstPointer();
9328       std::size_t nbOfElem=(*iter)->getNbOfElems();
9329       int sfid=fid;
9330       for(int j=0;j<sfid;j++)
9331         {
9332           bool found=false;
9333           for(std::size_t i=0;i<nbOfElem;i++)
9334             {
9335               if(ptr[i]>=0 && ptr[i]<newNb)
9336                 {
9337                   if(retPtr[ptr[i]]==j)
9338                     {
9339                       retPtr[ptr[i]]=fid;
9340                       found=true;
9341                     }
9342                 }
9343               else
9344                 {
9345                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9346                   oss << ") !";
9347                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9348                 }
9349             }
9350           if(found)
9351             fid++;
9352         }
9353     }
9354   fidsOfGroups.clear();
9355   fidsOfGroups.resize(groups2.size());
9356   int grId=0;
9357   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9358     {
9359       std::set<int> tmp;
9360       const int *ptr=(*iter)->getConstPointer();
9361       std::size_t nbOfElem=(*iter)->getNbOfElems();
9362       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9363         tmp.insert(retPtr[*p]);
9364       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9365     }
9366   return ret.retn();
9367 }
9368
9369 /*!
9370  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9371  * arrays. The result array does not contain any duplicates and its values
9372  * are sorted in ascending order.
9373  *  \param [in] arr - sequence of DataArrayInt's to unite.
9374  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9375  *         array using decrRef() as it is no more needed.
9376  *  \throw If any \a arr[i] is not allocated.
9377  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9378  */
9379 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9380 {
9381   std::vector<const DataArrayInt *> a;
9382   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9383     if(*it4)
9384       a.push_back(*it4);
9385   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9386     {
9387       (*it)->checkAllocated();
9388       if((*it)->getNumberOfComponents()!=1)
9389         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9390     }
9391   //
9392   std::set<int> r;
9393   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9394     {
9395       const int *pt=(*it)->getConstPointer();
9396       int nbOfTuples=(*it)->getNumberOfTuples();
9397       r.insert(pt,pt+nbOfTuples);
9398     }
9399   DataArrayInt *ret=DataArrayInt::New();
9400   ret->alloc((int)r.size(),1);
9401   std::copy(r.begin(),r.end(),ret->getPointer());
9402   return ret;
9403 }
9404
9405 /*!
9406  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9407  * arrays. The result array does not contain any duplicates and its values
9408  * are sorted in ascending order.
9409  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9410  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9411  *         array using decrRef() as it is no more needed.
9412  *  \throw If any \a arr[i] is not allocated.
9413  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9414  */
9415 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9416 {
9417   std::vector<const DataArrayInt *> a;
9418   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9419     if(*it4)
9420       a.push_back(*it4);
9421   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9422     {
9423       (*it)->checkAllocated();
9424       if((*it)->getNumberOfComponents()!=1)
9425         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9426     }
9427   //
9428   std::set<int> r;
9429   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9430     {
9431       const int *pt=(*it)->getConstPointer();
9432       int nbOfTuples=(*it)->getNumberOfTuples();
9433       std::set<int> s1(pt,pt+nbOfTuples);
9434       if(it!=a.begin())
9435         {
9436           std::set<int> r2;
9437           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9438           r=r2;
9439         }
9440       else
9441         r=s1;
9442     }
9443   DataArrayInt *ret=DataArrayInt::New();
9444   ret->alloc((int)r.size(),1);
9445   std::copy(r.begin(),r.end(),ret->getPointer());
9446   return ret;
9447 }
9448
9449 /*!
9450  * Returns a new DataArrayInt which contains a complement of elements of \a this
9451  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9452  * \a nbOfElement) not present in \a this array.
9453  *  \param [in] nbOfElement - maximal size of the result array.
9454  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9455  *         array using decrRef() as it is no more needed.
9456  *  \throw If \a this is not allocated.
9457  *  \throw If \a this->getNumberOfComponents() != 1.
9458  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9459  *         nbOfElement ).
9460  */
9461 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9462 {
9463    checkAllocated();
9464    if(getNumberOfComponents()!=1)
9465      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9466    std::vector<bool> tmp(nbOfElement);
9467    const int *pt=getConstPointer();
9468    int nbOfTuples=getNumberOfTuples();
9469    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9470      if(*w>=0 && *w<nbOfElement)
9471        tmp[*w]=true;
9472      else
9473        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9474    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9475    DataArrayInt *ret=DataArrayInt::New();
9476    ret->alloc(nbOfRetVal,1);
9477    int j=0;
9478    int *retPtr=ret->getPointer();
9479    for(int i=0;i<nbOfElement;i++)
9480      if(!tmp[i])
9481        retPtr[j++]=i;
9482    return ret;
9483 }
9484
9485 /*!
9486  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9487  * from an \a other one-dimensional array.
9488  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9489  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9490  *         caller is to delete this array using decrRef() as it is no more needed.
9491  *  \throw If \a other is NULL.
9492  *  \throw If \a other is not allocated.
9493  *  \throw If \a other->getNumberOfComponents() != 1.
9494  *  \throw If \a this is not allocated.
9495  *  \throw If \a this->getNumberOfComponents() != 1.
9496  *  \sa DataArrayInt::buildSubstractionOptimized()
9497  */
9498 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9499 {
9500   if(!other)
9501     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9502   checkAllocated();
9503   other->checkAllocated();
9504   if(getNumberOfComponents()!=1)
9505      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9506   if(other->getNumberOfComponents()!=1)
9507      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9508   const int *pt=getConstPointer();
9509   int nbOfTuples=getNumberOfTuples();
9510   std::set<int> s1(pt,pt+nbOfTuples);
9511   pt=other->getConstPointer();
9512   nbOfTuples=other->getNumberOfTuples();
9513   std::set<int> s2(pt,pt+nbOfTuples);
9514   std::vector<int> r;
9515   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9516   DataArrayInt *ret=DataArrayInt::New();
9517   ret->alloc((int)r.size(),1);
9518   std::copy(r.begin(),r.end(),ret->getPointer());
9519   return ret;
9520 }
9521
9522 /*!
9523  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9524  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9525  * 
9526  * \param [in] other an array with one component and expected to be sorted ascendingly.
9527  * \ret list of ids in \a this but not in \a other.
9528  * \sa DataArrayInt::buildSubstraction
9529  */
9530 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9531 {
9532   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9533   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9534   checkAllocated(); other->checkAllocated();
9535   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9536   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9537   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9538   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9539   for(;work1!=pt1End;work1++)
9540     {
9541       if(work2!=pt2End && *work1==*work2)
9542         work2++;
9543       else
9544         ret->pushBackSilent(*work1);
9545     }
9546   return ret.retn();
9547 }
9548
9549
9550 /*!
9551  * Returns a new DataArrayInt which contains all elements of \a this and a given
9552  * one-dimensional arrays. The result array does not contain any duplicates
9553  * and its values are sorted in ascending order.
9554  *  \param [in] other - an array to unite with \a this one.
9555  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9556  *         array using decrRef() as it is no more needed.
9557  *  \throw If \a this or \a other is not allocated.
9558  *  \throw If \a this->getNumberOfComponents() != 1.
9559  *  \throw If \a other->getNumberOfComponents() != 1.
9560  */
9561 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9562 {
9563   std::vector<const DataArrayInt *>arrs(2);
9564   arrs[0]=this; arrs[1]=other;
9565   return BuildUnion(arrs);
9566 }
9567
9568
9569 /*!
9570  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9571  * one-dimensional arrays. The result array does not contain any duplicates
9572  * and its values are sorted in ascending order.
9573  *  \param [in] other - an array to intersect with \a this one.
9574  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9575  *         array using decrRef() as it is no more needed.
9576  *  \throw If \a this or \a other is not allocated.
9577  *  \throw If \a this->getNumberOfComponents() != 1.
9578  *  \throw If \a other->getNumberOfComponents() != 1.
9579  */
9580 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9581 {
9582   std::vector<const DataArrayInt *>arrs(2);
9583   arrs[0]=this; arrs[1]=other;
9584   return BuildIntersection(arrs);
9585 }
9586
9587 /*!
9588  * This method can be applied on allocated with one component DataArrayInt instance.
9589  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9590  * 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]
9591  * 
9592  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9593  * \throw if \a this is not allocated or if \a this has not exactly one component.
9594  */
9595 DataArrayInt *DataArrayInt::buildUnique() const
9596 {
9597   checkAllocated();
9598   if(getNumberOfComponents()!=1)
9599      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9600   int nbOfTuples=getNumberOfTuples();
9601   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9602   int *data=tmp->getPointer();
9603   int *last=std::unique(data,data+nbOfTuples);
9604   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9605   ret->alloc(std::distance(data,last),1);
9606   std::copy(data,last,ret->getPointer());
9607   return ret.retn();
9608 }
9609
9610 /*!
9611  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9612  * "index" array. Such "index" array is returned for example by 
9613  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9614  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9615  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9616  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9617  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9618  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9619  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9620  *          The caller is to delete this array using decrRef() as it is no more needed. 
9621  *  \throw If \a this is not allocated.
9622  *  \throw If \a this->getNumberOfComponents() != 1.
9623  *  \throw If \a this->getNumberOfTuples() < 2.
9624  *
9625  *  \b Example: <br> 
9626  *         - this contains [1,3,6,7,7,9,15]
9627  *         - result array contains [2,3,1,0,2,6],
9628  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9629  *
9630  * \sa DataArrayInt::computeOffsets2
9631  */
9632 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9633 {
9634   checkAllocated();
9635   if(getNumberOfComponents()!=1)
9636      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9637   int nbOfTuples=getNumberOfTuples();
9638   if(nbOfTuples<2)
9639     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9640   const int *ptr=getConstPointer();
9641   DataArrayInt *ret=DataArrayInt::New();
9642   ret->alloc(nbOfTuples-1,1);
9643   int *out=ret->getPointer();
9644   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9645   return ret;
9646 }
9647
9648 /*!
9649  * Modifies \a this one-dimensional array so that value of each element \a x
9650  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9651  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9652  * and components remains the same.<br>
9653  * This method is useful for allToAllV in MPI with contiguous policy. This method
9654  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9655  * this one.
9656  *  \throw If \a this is not allocated.
9657  *  \throw If \a this->getNumberOfComponents() != 1.
9658  *
9659  *  \b Example: <br>
9660  *          - Before \a this contains [3,5,1,2,0,8]
9661  *          - After \a this contains  [0,3,8,9,11,11]<br>
9662  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9663  *          array is retained and thus there is no space to store the last element.
9664  */
9665 void DataArrayInt::computeOffsets()
9666 {
9667   checkAllocated();
9668   if(getNumberOfComponents()!=1)
9669      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9670   int nbOfTuples=getNumberOfTuples();
9671   if(nbOfTuples==0)
9672     return ;
9673   int *work=getPointer();
9674   int tmp=work[0];
9675   work[0]=0;
9676   for(int i=1;i<nbOfTuples;i++)
9677     {
9678       int tmp2=work[i];
9679       work[i]=work[i-1]+tmp;
9680       tmp=tmp2;
9681     }
9682   declareAsNew();
9683 }
9684
9685
9686 /*!
9687  * Modifies \a this one-dimensional array so that value of each element \a x
9688  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9689  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9690  * components remains the same and number of tuples is inceamented by one.<br>
9691  * This method is useful for allToAllV in MPI with contiguous policy. This method
9692  * differs from computeOffsets() in that the number of tuples is changed by this one.
9693  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9694  *  \throw If \a this is not allocated.
9695  *  \throw If \a this->getNumberOfComponents() != 1.
9696  *
9697  *  \b Example: <br>
9698  *          - Before \a this contains [3,5,1,2,0,8]
9699  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9700  * \sa DataArrayInt::deltaShiftIndex
9701  */
9702 void DataArrayInt::computeOffsets2()
9703 {
9704   checkAllocated();
9705   if(getNumberOfComponents()!=1)
9706     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9707   int nbOfTuples=getNumberOfTuples();
9708   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9709   if(nbOfTuples==0)
9710     return ;
9711   const int *work=getConstPointer();
9712   ret[0]=0;
9713   for(int i=0;i<nbOfTuples;i++)
9714     ret[i+1]=work[i]+ret[i];
9715   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9716   declareAsNew();
9717 }
9718
9719 /*!
9720  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9721  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9722  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9723  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9724  * filling completely one of the ranges in \a this.
9725  *
9726  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9727  * \param [out] rangeIdsFetched the range ids fetched
9728  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9729  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9730  *
9731  * \sa DataArrayInt::computeOffsets2
9732  *
9733  *  \b Example: <br>
9734  *          - \a this : [0,3,7,9,15,18]
9735  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9736  *          - \a rangeIdsFetched result array: [0,2,4]
9737  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9738  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9739  * <br>
9740  */
9741 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9742 {
9743   if(!listOfIds)
9744     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9745   listOfIds->checkAllocated(); checkAllocated();
9746   if(listOfIds->getNumberOfComponents()!=1)
9747     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9748   if(getNumberOfComponents()!=1)
9749     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9750   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9751   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9752   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9753   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9754   while(tupPtr!=tupEnd && offPtr!=offEnd)
9755     {
9756       if(*tupPtr==*offPtr)
9757         {
9758           int i=offPtr[0];
9759           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9760           if(i==offPtr[1])
9761             {
9762               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9763               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9764               offPtr++;
9765             }
9766         }
9767       else
9768         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9769     }
9770   rangeIdsFetched=ret0.retn();
9771   idsInInputListThatFetch=ret1.retn();
9772 }
9773
9774 /*!
9775  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9776  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9777  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9778  * beginning within the "iota" array. And \a this is a one-dimensional array
9779  * considered as a selector of groups described by \a offsets to include into the result array.
9780  *  \throw If \a offsets is NULL.
9781  *  \throw If \a offsets is not allocated.
9782  *  \throw If \a offsets->getNumberOfComponents() != 1.
9783  *  \throw If \a offsets is not monotonically increasing.
9784  *  \throw If \a this is not allocated.
9785  *  \throw If \a this->getNumberOfComponents() != 1.
9786  *  \throw If any element of \a this is not a valid index for \a offsets array.
9787  *
9788  *  \b Example: <br>
9789  *          - \a this: [0,2,3]
9790  *          - \a offsets: [0,3,6,10,14,20]
9791  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9792  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9793  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9794  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9795  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9796  */
9797 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
9798 {
9799   if(!offsets)
9800     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9801   checkAllocated();
9802   if(getNumberOfComponents()!=1)
9803      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9804   offsets->checkAllocated();
9805   if(offsets->getNumberOfComponents()!=1)
9806      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9807   int othNbTuples=offsets->getNumberOfTuples()-1;
9808   int nbOfTuples=getNumberOfTuples();
9809   int retNbOftuples=0;
9810   const int *work=getConstPointer();
9811   const int *offPtr=offsets->getConstPointer();
9812   for(int i=0;i<nbOfTuples;i++)
9813     {
9814       int val=work[i];
9815       if(val>=0 && val<othNbTuples)
9816         {
9817           int delta=offPtr[val+1]-offPtr[val];
9818           if(delta>=0)
9819             retNbOftuples+=delta;
9820           else
9821             {
9822               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9823               throw INTERP_KERNEL::Exception(oss.str().c_str());
9824             }
9825         }
9826       else
9827         {
9828           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9829           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9830           throw INTERP_KERNEL::Exception(oss.str().c_str());
9831         }
9832     }
9833   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9834   ret->alloc(retNbOftuples,1);
9835   int *retPtr=ret->getPointer();
9836   for(int i=0;i<nbOfTuples;i++)
9837     {
9838       int val=work[i];
9839       int start=offPtr[val];
9840       int off=offPtr[val+1]-start;
9841       for(int j=0;j<off;j++,retPtr++)
9842         *retPtr=start+j;
9843     }
9844   return ret.retn();
9845 }
9846
9847 /*!
9848  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9849  * scaled array (monotonically increasing).
9850 from that of \a this and \a
9851  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9852  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9853  * beginning within the "iota" array. And \a this is a one-dimensional array
9854  * considered as a selector of groups described by \a offsets to include into the result array.
9855  *  \throw If \a  is NULL.
9856  *  \throw If \a this is not allocated.
9857  *  \throw If \a this->getNumberOfComponents() != 1.
9858  *  \throw If \a this->getNumberOfTuples() == 0.
9859  *  \throw If \a this is not monotonically increasing.
9860  *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
9861  *
9862  *  \b Example: <br>
9863  *          - \a bg , \a end and \a step : (0,5,2)
9864  *          - \a this: [0,3,6,10,14,20]
9865  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9866  */
9867 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const
9868 {
9869   if(!isAllocated())
9870     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9871   if(getNumberOfComponents()!=1)
9872     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9873   int nbOfTuples(getNumberOfTuples());
9874   if(nbOfTuples==0)
9875     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9876   const int *ids(begin());
9877   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9878   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9879     {
9880       if(pos>=0 && pos<nbOfTuples-1)
9881         {
9882           int delta(ids[pos+1]-ids[pos]);
9883           sz+=delta;
9884           if(delta<0)
9885             {
9886               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9887               throw INTERP_KERNEL::Exception(oss.str().c_str());
9888             }          
9889         }
9890       else
9891         {
9892           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9893           throw INTERP_KERNEL::Exception(oss.str().c_str());
9894         }
9895     }
9896   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9897   int *retPtr(ret->getPointer());
9898   pos=bg;
9899   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9900     {
9901       int delta(ids[pos+1]-ids[pos]);
9902       for(int j=0;j<delta;j++,retPtr++)
9903         *retPtr=pos;
9904     }
9905   return ret.retn();
9906 }
9907
9908 /*!
9909  * 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.
9910  * 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
9911  * in tuple **i** of returned DataArrayInt.
9912  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9913  *
9914  * 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)]
9915  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9916  * 
9917  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9918  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9919  * \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
9920  *        is thrown if no ranges in \a ranges contains value in \a this.
9921  * 
9922  * \sa DataArrayInt::findIdInRangeForEachTuple
9923  */
9924 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
9925 {
9926   if(!ranges)
9927     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9928   if(ranges->getNumberOfComponents()!=2)
9929     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9930   checkAllocated();
9931   if(getNumberOfComponents()!=1)
9932     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9933   int nbTuples=getNumberOfTuples();
9934   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9935   int nbOfRanges=ranges->getNumberOfTuples();
9936   const int *rangesPtr=ranges->getConstPointer();
9937   int *retPtr=ret->getPointer();
9938   const int *inPtr=getConstPointer();
9939   for(int i=0;i<nbTuples;i++,retPtr++)
9940     {
9941       int val=inPtr[i];
9942       bool found=false;
9943       for(int j=0;j<nbOfRanges && !found;j++)
9944         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9945           { *retPtr=j; found=true; }
9946       if(found)
9947         continue;
9948       else
9949         {
9950           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9951           throw INTERP_KERNEL::Exception(oss.str().c_str());
9952         }
9953     }
9954   return ret.retn();
9955 }
9956
9957 /*!
9958  * 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.
9959  * 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
9960  * in tuple **i** of returned DataArrayInt.
9961  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9962  *
9963  * 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)]
9964  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9965  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9966  * 
9967  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9968  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9969  * \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
9970  *        is thrown if no ranges in \a ranges contains value in \a this.
9971  * \sa DataArrayInt::findRangeIdForEachTuple
9972  */
9973 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
9974 {
9975   if(!ranges)
9976     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9977   if(ranges->getNumberOfComponents()!=2)
9978     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9979   checkAllocated();
9980   if(getNumberOfComponents()!=1)
9981     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9982   int nbTuples=getNumberOfTuples();
9983   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9984   int nbOfRanges=ranges->getNumberOfTuples();
9985   const int *rangesPtr=ranges->getConstPointer();
9986   int *retPtr=ret->getPointer();
9987   const int *inPtr=getConstPointer();
9988   for(int i=0;i<nbTuples;i++,retPtr++)
9989     {
9990       int val=inPtr[i];
9991       bool found=false;
9992       for(int j=0;j<nbOfRanges && !found;j++)
9993         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9994           { *retPtr=val-rangesPtr[2*j]; found=true; }
9995       if(found)
9996         continue;
9997       else
9998         {
9999           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10000           throw INTERP_KERNEL::Exception(oss.str().c_str());
10001         }
10002     }
10003   return ret.retn();
10004 }
10005
10006 /*!
10007  * 
10008  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10009  *             \a nbTimes  should be at least equal to 1.
10010  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10011  * \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.
10012  */
10013 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10014 {
10015   checkAllocated();
10016   if(getNumberOfComponents()!=1)
10017     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10018   if(nbTimes<1)
10019     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10020   int nbTuples=getNumberOfTuples();
10021   const int *inPtr=getConstPointer();
10022   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10023   int *retPtr=ret->getPointer();
10024   for(int i=0;i<nbTuples;i++,inPtr++)
10025     {
10026       int val=*inPtr;
10027       for(int j=0;j<nbTimes;j++,retPtr++)
10028         *retPtr=val;
10029     }
10030   ret->copyStringInfoFrom(*this);
10031   return ret.retn();
10032 }
10033
10034 /*!
10035  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10036  * But the number of components can be different from one.
10037  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10038  */
10039 DataArrayInt *DataArrayInt::getDifferentValues() const
10040 {
10041   checkAllocated();
10042   std::set<int> ret;
10043   ret.insert(begin(),end());
10044   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10045   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10046   return ret2.retn();
10047 }
10048
10049 /*!
10050  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10051  * them it tells which tuple id have this id.
10052  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10053  * This method returns two arrays having same size.
10054  * 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.
10055  * 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]]
10056  */
10057 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10058 {
10059   checkAllocated();
10060   if(getNumberOfComponents()!=1)
10061     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10062   int id=0;
10063   std::map<int,int> m,m2,m3;
10064   for(const int *w=begin();w!=end();w++)
10065     m[*w]++;
10066   differentIds.resize(m.size());
10067   std::vector<DataArrayInt *> ret(m.size());
10068   std::vector<int *> retPtr(m.size());
10069   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10070     {
10071       m2[(*it).first]=id;
10072       ret[id]=DataArrayInt::New();
10073       ret[id]->alloc((*it).second,1);
10074       retPtr[id]=ret[id]->getPointer();
10075       differentIds[id]=(*it).first;
10076     }
10077   id=0;
10078   for(const int *w=begin();w!=end();w++,id++)
10079     {
10080       retPtr[m2[*w]][m3[*w]++]=id;
10081     }
10082   return ret;
10083 }
10084
10085 /*!
10086  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10087  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10088  *
10089  * \param [in] nbOfSlices - number of slices expected.
10090  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10091  * 
10092  * \sa DataArray::GetSlice
10093  * \throw If \a this is not allocated or not with exactly one component.
10094  * \throw If an element in \a this if < 0.
10095  */
10096 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10097 {
10098   if(!isAllocated() || getNumberOfComponents()!=1)
10099     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10100   if(nbOfSlices<=0)
10101     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10102   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10103   int sumPerSlc(sum/nbOfSlices),pos(0);
10104   const int *w(begin());
10105   std::vector< std::pair<int,int> > ret(nbOfSlices);
10106   for(int i=0;i<nbOfSlices;i++)
10107     {
10108       std::pair<int,int> p(pos,-1);
10109       int locSum(0);
10110       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10111       if(i!=nbOfSlices-1)
10112         p.second=pos;
10113       else
10114         p.second=nbOfTuples;
10115       ret[i]=p;
10116     }
10117   return ret;
10118 }
10119
10120 /*!
10121  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10122  * valid cases.
10123  * 1.  The arrays have same number of tuples and components. Then each value of
10124  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10125  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10126  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10127  *   component. Then
10128  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10129  * 3.  The arrays have same number of components and one array, say _a2_, has one
10130  *   tuple. Then
10131  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10132  *
10133  * Info on components is copied either from the first array (in the first case) or from
10134  * the array with maximal number of elements (getNbOfElems()).
10135  *  \param [in] a1 - an array to sum up.
10136  *  \param [in] a2 - another array to sum up.
10137  *  \return DataArrayInt * - the new instance of DataArrayInt.
10138  *          The caller is to delete this result array using decrRef() as it is no more
10139  *          needed.
10140  *  \throw If either \a a1 or \a a2 is NULL.
10141  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10142  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10143  *         none of them has number of tuples or components equal to 1.
10144  */
10145 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10146 {
10147   if(!a1 || !a2)
10148     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10149   int nbOfTuple=a1->getNumberOfTuples();
10150   int nbOfTuple2=a2->getNumberOfTuples();
10151   int nbOfComp=a1->getNumberOfComponents();
10152   int nbOfComp2=a2->getNumberOfComponents();
10153   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10154   if(nbOfTuple==nbOfTuple2)
10155     {
10156       if(nbOfComp==nbOfComp2)
10157         {
10158           ret=DataArrayInt::New();
10159           ret->alloc(nbOfTuple,nbOfComp);
10160           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10161           ret->copyStringInfoFrom(*a1);
10162         }
10163       else
10164         {
10165           int nbOfCompMin,nbOfCompMax;
10166           const DataArrayInt *aMin, *aMax;
10167           if(nbOfComp>nbOfComp2)
10168             {
10169               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10170               aMin=a2; aMax=a1;
10171             }
10172           else
10173             {
10174               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10175               aMin=a1; aMax=a2;
10176             }
10177           if(nbOfCompMin==1)
10178             {
10179               ret=DataArrayInt::New();
10180               ret->alloc(nbOfTuple,nbOfCompMax);
10181               const int *aMinPtr=aMin->getConstPointer();
10182               const int *aMaxPtr=aMax->getConstPointer();
10183               int *res=ret->getPointer();
10184               for(int i=0;i<nbOfTuple;i++)
10185                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10186               ret->copyStringInfoFrom(*aMax);
10187             }
10188           else
10189             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10190         }
10191     }
10192   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10193     {
10194       if(nbOfComp==nbOfComp2)
10195         {
10196           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10197           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10198           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10199           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10200           ret=DataArrayInt::New();
10201           ret->alloc(nbOfTupleMax,nbOfComp);
10202           int *res=ret->getPointer();
10203           for(int i=0;i<nbOfTupleMax;i++)
10204             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10205           ret->copyStringInfoFrom(*aMax);
10206         }
10207       else
10208         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10209     }
10210   else
10211     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10212   return ret.retn();
10213 }
10214
10215 /*!
10216  * Adds values of another DataArrayInt to values of \a this one. There are 3
10217  * valid cases.
10218  * 1.  The arrays have same number of tuples and components. Then each value of
10219  *   \a other array is added to the corresponding value of \a this array, i.e.:
10220  *   _a_ [ i, j ] += _other_ [ i, j ].
10221  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10222  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10223  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10224  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10225  *
10226  *  \param [in] other - an array to add to \a this one.
10227  *  \throw If \a other is NULL.
10228  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10229  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10230  *         \a other has number of both tuples and components not equal to 1.
10231  */
10232 void DataArrayInt::addEqual(const DataArrayInt *other)
10233 {
10234   if(!other)
10235     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10236   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10237   checkAllocated(); other->checkAllocated();
10238   int nbOfTuple=getNumberOfTuples();
10239   int nbOfTuple2=other->getNumberOfTuples();
10240   int nbOfComp=getNumberOfComponents();
10241   int nbOfComp2=other->getNumberOfComponents();
10242   if(nbOfTuple==nbOfTuple2)
10243     {
10244       if(nbOfComp==nbOfComp2)
10245         {
10246           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10247         }
10248       else if(nbOfComp2==1)
10249         {
10250           int *ptr=getPointer();
10251           const int *ptrc=other->getConstPointer();
10252           for(int i=0;i<nbOfTuple;i++)
10253             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10254         }
10255       else
10256         throw INTERP_KERNEL::Exception(msg);
10257     }
10258   else if(nbOfTuple2==1)
10259     {
10260       if(nbOfComp2==nbOfComp)
10261         {
10262           int *ptr=getPointer();
10263           const int *ptrc=other->getConstPointer();
10264           for(int i=0;i<nbOfTuple;i++)
10265             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10266         }
10267       else
10268         throw INTERP_KERNEL::Exception(msg);
10269     }
10270   else
10271     throw INTERP_KERNEL::Exception(msg);
10272   declareAsNew();
10273 }
10274
10275 /*!
10276  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10277  * valid cases.
10278  * 1.  The arrays have same number of tuples and components. Then each value of
10279  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10280  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10281  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10282  *   component. Then
10283  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10284  * 3.  The arrays have same number of components and one array, say _a2_, has one
10285  *   tuple. Then
10286  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10287  *
10288  * Info on components is copied either from the first array (in the first case) or from
10289  * the array with maximal number of elements (getNbOfElems()).
10290  *  \param [in] a1 - an array to subtract from.
10291  *  \param [in] a2 - an array to subtract.
10292  *  \return DataArrayInt * - the new instance of DataArrayInt.
10293  *          The caller is to delete this result array using decrRef() as it is no more
10294  *          needed.
10295  *  \throw If either \a a1 or \a a2 is NULL.
10296  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10297  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10298  *         none of them has number of tuples or components equal to 1.
10299  */
10300 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10301 {
10302   if(!a1 || !a2)
10303     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10304   int nbOfTuple1=a1->getNumberOfTuples();
10305   int nbOfTuple2=a2->getNumberOfTuples();
10306   int nbOfComp1=a1->getNumberOfComponents();
10307   int nbOfComp2=a2->getNumberOfComponents();
10308   if(nbOfTuple2==nbOfTuple1)
10309     {
10310       if(nbOfComp1==nbOfComp2)
10311         {
10312           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10313           ret->alloc(nbOfTuple2,nbOfComp1);
10314           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10315           ret->copyStringInfoFrom(*a1);
10316           return ret.retn();
10317         }
10318       else if(nbOfComp2==1)
10319         {
10320           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10321           ret->alloc(nbOfTuple1,nbOfComp1);
10322           const int *a2Ptr=a2->getConstPointer();
10323           const int *a1Ptr=a1->getConstPointer();
10324           int *res=ret->getPointer();
10325           for(int i=0;i<nbOfTuple1;i++)
10326             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10327           ret->copyStringInfoFrom(*a1);
10328           return ret.retn();
10329         }
10330       else
10331         {
10332           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10333           return 0;
10334         }
10335     }
10336   else if(nbOfTuple2==1)
10337     {
10338       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10339       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10340       ret->alloc(nbOfTuple1,nbOfComp1);
10341       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10342       int *pt=ret->getPointer();
10343       for(int i=0;i<nbOfTuple1;i++)
10344         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10345       ret->copyStringInfoFrom(*a1);
10346       return ret.retn();
10347     }
10348   else
10349     {
10350       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10351       return 0;
10352     }
10353 }
10354
10355 /*!
10356  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10357  * valid cases.
10358  * 1.  The arrays have same number of tuples and components. Then each value of
10359  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10360  *   _a_ [ i, j ] -= _other_ [ i, j ].
10361  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10362  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10363  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10364  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10365  *
10366  *  \param [in] other - an array to subtract from \a this one.
10367  *  \throw If \a other is NULL.
10368  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10369  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10370  *         \a other has number of both tuples and components not equal to 1.
10371  */
10372 void DataArrayInt::substractEqual(const DataArrayInt *other)
10373 {
10374   if(!other)
10375     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10376   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10377   checkAllocated(); other->checkAllocated();
10378   int nbOfTuple=getNumberOfTuples();
10379   int nbOfTuple2=other->getNumberOfTuples();
10380   int nbOfComp=getNumberOfComponents();
10381   int nbOfComp2=other->getNumberOfComponents();
10382   if(nbOfTuple==nbOfTuple2)
10383     {
10384       if(nbOfComp==nbOfComp2)
10385         {
10386           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10387         }
10388       else if(nbOfComp2==1)
10389         {
10390           int *ptr=getPointer();
10391           const int *ptrc=other->getConstPointer();
10392           for(int i=0;i<nbOfTuple;i++)
10393             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10394         }
10395       else
10396         throw INTERP_KERNEL::Exception(msg);
10397     }
10398   else if(nbOfTuple2==1)
10399     {
10400       int *ptr=getPointer();
10401       const int *ptrc=other->getConstPointer();
10402       for(int i=0;i<nbOfTuple;i++)
10403         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10404     }
10405   else
10406     throw INTERP_KERNEL::Exception(msg);
10407   declareAsNew();
10408 }
10409
10410 /*!
10411  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10412  * valid cases.
10413  * 1.  The arrays have same number of tuples and components. Then each value of
10414  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10415  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10416  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10417  *   component. Then
10418  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10419  * 3.  The arrays have same number of components and one array, say _a2_, has one
10420  *   tuple. Then
10421  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10422  *
10423  * Info on components is copied either from the first array (in the first case) or from
10424  * the array with maximal number of elements (getNbOfElems()).
10425  *  \param [in] a1 - a factor array.
10426  *  \param [in] a2 - another factor array.
10427  *  \return DataArrayInt * - the new instance of DataArrayInt.
10428  *          The caller is to delete this result array using decrRef() as it is no more
10429  *          needed.
10430  *  \throw If either \a a1 or \a a2 is NULL.
10431  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10432  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10433  *         none of them has number of tuples or components equal to 1.
10434  */
10435 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10436 {
10437   if(!a1 || !a2)
10438     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10439   int nbOfTuple=a1->getNumberOfTuples();
10440   int nbOfTuple2=a2->getNumberOfTuples();
10441   int nbOfComp=a1->getNumberOfComponents();
10442   int nbOfComp2=a2->getNumberOfComponents();
10443   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10444   if(nbOfTuple==nbOfTuple2)
10445     {
10446       if(nbOfComp==nbOfComp2)
10447         {
10448           ret=DataArrayInt::New();
10449           ret->alloc(nbOfTuple,nbOfComp);
10450           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10451           ret->copyStringInfoFrom(*a1);
10452         }
10453       else
10454         {
10455           int nbOfCompMin,nbOfCompMax;
10456           const DataArrayInt *aMin, *aMax;
10457           if(nbOfComp>nbOfComp2)
10458             {
10459               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10460               aMin=a2; aMax=a1;
10461             }
10462           else
10463             {
10464               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10465               aMin=a1; aMax=a2;
10466             }
10467           if(nbOfCompMin==1)
10468             {
10469               ret=DataArrayInt::New();
10470               ret->alloc(nbOfTuple,nbOfCompMax);
10471               const int *aMinPtr=aMin->getConstPointer();
10472               const int *aMaxPtr=aMax->getConstPointer();
10473               int *res=ret->getPointer();
10474               for(int i=0;i<nbOfTuple;i++)
10475                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10476               ret->copyStringInfoFrom(*aMax);
10477             }
10478           else
10479             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10480         }
10481     }
10482   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10483     {
10484       if(nbOfComp==nbOfComp2)
10485         {
10486           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10487           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10488           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10489           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10490           ret=DataArrayInt::New();
10491           ret->alloc(nbOfTupleMax,nbOfComp);
10492           int *res=ret->getPointer();
10493           for(int i=0;i<nbOfTupleMax;i++)
10494             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10495           ret->copyStringInfoFrom(*aMax);
10496         }
10497       else
10498         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10499     }
10500   else
10501     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10502   return ret.retn();
10503 }
10504
10505
10506 /*!
10507  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10508  * valid cases.
10509  * 1.  The arrays have same number of tuples and components. Then each value of
10510  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10511  *   _a_ [ i, j ] *= _other_ [ i, j ].
10512  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10513  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10514  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10515  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10516  *
10517  *  \param [in] other - an array to multiply to \a this one.
10518  *  \throw If \a other is NULL.
10519  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10520  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10521  *         \a other has number of both tuples and components not equal to 1.
10522  */
10523 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10524 {
10525   if(!other)
10526     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10527   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10528   checkAllocated(); other->checkAllocated();
10529   int nbOfTuple=getNumberOfTuples();
10530   int nbOfTuple2=other->getNumberOfTuples();
10531   int nbOfComp=getNumberOfComponents();
10532   int nbOfComp2=other->getNumberOfComponents();
10533   if(nbOfTuple==nbOfTuple2)
10534     {
10535       if(nbOfComp==nbOfComp2)
10536         {
10537           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10538         }
10539       else if(nbOfComp2==1)
10540         {
10541           int *ptr=getPointer();
10542           const int *ptrc=other->getConstPointer();
10543           for(int i=0;i<nbOfTuple;i++)
10544             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10545         }
10546       else
10547         throw INTERP_KERNEL::Exception(msg);
10548     }
10549   else if(nbOfTuple2==1)
10550     {
10551       if(nbOfComp2==nbOfComp)
10552         {
10553           int *ptr=getPointer();
10554           const int *ptrc=other->getConstPointer();
10555           for(int i=0;i<nbOfTuple;i++)
10556             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10557         }
10558       else
10559         throw INTERP_KERNEL::Exception(msg);
10560     }
10561   else
10562     throw INTERP_KERNEL::Exception(msg);
10563   declareAsNew();
10564 }
10565
10566
10567 /*!
10568  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10569  * valid cases.
10570  * 1.  The arrays have same number of tuples and components. Then each value of
10571  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10572  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10573  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10574  *   component. Then
10575  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10576  * 3.  The arrays have same number of components and one array, say _a2_, has one
10577  *   tuple. Then
10578  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10579  *
10580  * Info on components is copied either from the first array (in the first case) or from
10581  * the array with maximal number of elements (getNbOfElems()).
10582  *  \warning No check of division by zero is performed!
10583  *  \param [in] a1 - a numerator array.
10584  *  \param [in] a2 - a denominator array.
10585  *  \return DataArrayInt * - the new instance of DataArrayInt.
10586  *          The caller is to delete this result array using decrRef() as it is no more
10587  *          needed.
10588  *  \throw If either \a a1 or \a a2 is NULL.
10589  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10590  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10591  *         none of them has number of tuples or components equal to 1.
10592  */
10593 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10594 {
10595   if(!a1 || !a2)
10596     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10597   int nbOfTuple1=a1->getNumberOfTuples();
10598   int nbOfTuple2=a2->getNumberOfTuples();
10599   int nbOfComp1=a1->getNumberOfComponents();
10600   int nbOfComp2=a2->getNumberOfComponents();
10601   if(nbOfTuple2==nbOfTuple1)
10602     {
10603       if(nbOfComp1==nbOfComp2)
10604         {
10605           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10606           ret->alloc(nbOfTuple2,nbOfComp1);
10607           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10608           ret->copyStringInfoFrom(*a1);
10609           return ret.retn();
10610         }
10611       else if(nbOfComp2==1)
10612         {
10613           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10614           ret->alloc(nbOfTuple1,nbOfComp1);
10615           const int *a2Ptr=a2->getConstPointer();
10616           const int *a1Ptr=a1->getConstPointer();
10617           int *res=ret->getPointer();
10618           for(int i=0;i<nbOfTuple1;i++)
10619             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10620           ret->copyStringInfoFrom(*a1);
10621           return ret.retn();
10622         }
10623       else
10624         {
10625           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10626           return 0;
10627         }
10628     }
10629   else if(nbOfTuple2==1)
10630     {
10631       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10632       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10633       ret->alloc(nbOfTuple1,nbOfComp1);
10634       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10635       int *pt=ret->getPointer();
10636       for(int i=0;i<nbOfTuple1;i++)
10637         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10638       ret->copyStringInfoFrom(*a1);
10639       return ret.retn();
10640     }
10641   else
10642     {
10643       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10644       return 0;
10645     }
10646 }
10647
10648 /*!
10649  * Divide values of \a this array by values of another DataArrayInt. There are 3
10650  * valid cases.
10651  * 1.  The arrays have same number of tuples and components. Then each value of
10652  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10653  *   _a_ [ i, j ] /= _other_ [ i, j ].
10654  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10655  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10656  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10657  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10658  *
10659  *  \warning No check of division by zero is performed!
10660  *  \param [in] other - an array to divide \a this one by.
10661  *  \throw If \a other is NULL.
10662  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10663  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10664  *         \a other has number of both tuples and components not equal to 1.
10665  */
10666 void DataArrayInt::divideEqual(const DataArrayInt *other)
10667 {
10668   if(!other)
10669     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10670   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10671   checkAllocated(); other->checkAllocated();
10672   int nbOfTuple=getNumberOfTuples();
10673   int nbOfTuple2=other->getNumberOfTuples();
10674   int nbOfComp=getNumberOfComponents();
10675   int nbOfComp2=other->getNumberOfComponents();
10676   if(nbOfTuple==nbOfTuple2)
10677     {
10678       if(nbOfComp==nbOfComp2)
10679         {
10680           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10681         }
10682       else if(nbOfComp2==1)
10683         {
10684           int *ptr=getPointer();
10685           const int *ptrc=other->getConstPointer();
10686           for(int i=0;i<nbOfTuple;i++)
10687             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10688         }
10689       else
10690         throw INTERP_KERNEL::Exception(msg);
10691     }
10692   else if(nbOfTuple2==1)
10693     {
10694       if(nbOfComp2==nbOfComp)
10695         {
10696           int *ptr=getPointer();
10697           const int *ptrc=other->getConstPointer();
10698           for(int i=0;i<nbOfTuple;i++)
10699             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10700         }
10701       else
10702         throw INTERP_KERNEL::Exception(msg);
10703     }
10704   else
10705     throw INTERP_KERNEL::Exception(msg);
10706   declareAsNew();
10707 }
10708
10709
10710 /*!
10711  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10712  * valid cases.
10713  * 1.  The arrays have same number of tuples and components. Then each value of
10714  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10715  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10716  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10717  *   component. Then
10718  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10719  * 3.  The arrays have same number of components and one array, say _a2_, has one
10720  *   tuple. Then
10721  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10722  *
10723  * Info on components is copied either from the first array (in the first case) or from
10724  * the array with maximal number of elements (getNbOfElems()).
10725  *  \warning No check of division by zero is performed!
10726  *  \param [in] a1 - a dividend array.
10727  *  \param [in] a2 - a divisor array.
10728  *  \return DataArrayInt * - the new instance of DataArrayInt.
10729  *          The caller is to delete this result array using decrRef() as it is no more
10730  *          needed.
10731  *  \throw If either \a a1 or \a a2 is NULL.
10732  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10733  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10734  *         none of them has number of tuples or components equal to 1.
10735  */
10736 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10737 {
10738     if(!a1 || !a2)
10739     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10740   int nbOfTuple1=a1->getNumberOfTuples();
10741   int nbOfTuple2=a2->getNumberOfTuples();
10742   int nbOfComp1=a1->getNumberOfComponents();
10743   int nbOfComp2=a2->getNumberOfComponents();
10744   if(nbOfTuple2==nbOfTuple1)
10745     {
10746       if(nbOfComp1==nbOfComp2)
10747         {
10748           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10749           ret->alloc(nbOfTuple2,nbOfComp1);
10750           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10751           ret->copyStringInfoFrom(*a1);
10752           return ret.retn();
10753         }
10754       else if(nbOfComp2==1)
10755         {
10756           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10757           ret->alloc(nbOfTuple1,nbOfComp1);
10758           const int *a2Ptr=a2->getConstPointer();
10759           const int *a1Ptr=a1->getConstPointer();
10760           int *res=ret->getPointer();
10761           for(int i=0;i<nbOfTuple1;i++)
10762             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10763           ret->copyStringInfoFrom(*a1);
10764           return ret.retn();
10765         }
10766       else
10767         {
10768           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10769           return 0;
10770         }
10771     }
10772   else if(nbOfTuple2==1)
10773     {
10774       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10775       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10776       ret->alloc(nbOfTuple1,nbOfComp1);
10777       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10778       int *pt=ret->getPointer();
10779       for(int i=0;i<nbOfTuple1;i++)
10780         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10781       ret->copyStringInfoFrom(*a1);
10782       return ret.retn();
10783     }
10784   else
10785     {
10786       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10787       return 0;
10788     }
10789 }
10790
10791 /*!
10792  * Modify \a this array so that each value becomes a modulus of division of this value by
10793  * a value of another DataArrayInt. There are 3 valid cases.
10794  * 1.  The arrays have same number of tuples and components. Then each value of
10795  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10796  *   _a_ [ i, j ] %= _other_ [ i, j ].
10797  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10798  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10799  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10800  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10801  *
10802  *  \warning No check of division by zero is performed!
10803  *  \param [in] other - a divisor array.
10804  *  \throw If \a other is NULL.
10805  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10806  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10807  *         \a other has number of both tuples and components not equal to 1.
10808  */
10809 void DataArrayInt::modulusEqual(const DataArrayInt *other)
10810 {
10811   if(!other)
10812     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10813   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10814   checkAllocated(); other->checkAllocated();
10815   int nbOfTuple=getNumberOfTuples();
10816   int nbOfTuple2=other->getNumberOfTuples();
10817   int nbOfComp=getNumberOfComponents();
10818   int nbOfComp2=other->getNumberOfComponents();
10819   if(nbOfTuple==nbOfTuple2)
10820     {
10821       if(nbOfComp==nbOfComp2)
10822         {
10823           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10824         }
10825       else if(nbOfComp2==1)
10826         {
10827           if(nbOfComp2==nbOfComp)
10828             {
10829               int *ptr=getPointer();
10830               const int *ptrc=other->getConstPointer();
10831               for(int i=0;i<nbOfTuple;i++)
10832                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10833             }
10834           else
10835             throw INTERP_KERNEL::Exception(msg);
10836         }
10837       else
10838         throw INTERP_KERNEL::Exception(msg);
10839     }
10840   else if(nbOfTuple2==1)
10841     {
10842       int *ptr=getPointer();
10843       const int *ptrc=other->getConstPointer();
10844       for(int i=0;i<nbOfTuple;i++)
10845         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10846     }
10847   else
10848     throw INTERP_KERNEL::Exception(msg);
10849   declareAsNew();
10850 }
10851
10852 /*!
10853  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10854  * valid cases.
10855  *
10856  *  \param [in] a1 - an array to pow up.
10857  *  \param [in] a2 - another array to sum up.
10858  *  \return DataArrayInt * - the new instance of DataArrayInt.
10859  *          The caller is to delete this result array using decrRef() as it is no more
10860  *          needed.
10861  *  \throw If either \a a1 or \a a2 is NULL.
10862  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10863  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10864  *  \throw If there is a negative value in \a a2.
10865  */
10866 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
10867 {
10868   if(!a1 || !a2)
10869     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10870   int nbOfTuple=a1->getNumberOfTuples();
10871   int nbOfTuple2=a2->getNumberOfTuples();
10872   int nbOfComp=a1->getNumberOfComponents();
10873   int nbOfComp2=a2->getNumberOfComponents();
10874   if(nbOfTuple!=nbOfTuple2)
10875     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10876   if(nbOfComp!=1 || nbOfComp2!=1)
10877     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10878   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10879   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10880   int *ptr=ret->getPointer();
10881   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10882     {
10883       if(*ptr2>=0)
10884         {
10885           int tmp=1;
10886           for(int j=0;j<*ptr2;j++)
10887             tmp*=*ptr1;
10888           *ptr=tmp;
10889         }
10890       else
10891         {
10892           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10893           throw INTERP_KERNEL::Exception(oss.str().c_str());
10894         }
10895     }
10896   return ret.retn();
10897 }
10898
10899 /*!
10900  * Apply pow on values of another DataArrayInt to values of \a this one.
10901  *
10902  *  \param [in] other - an array to pow to \a this one.
10903  *  \throw If \a other is NULL.
10904  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10905  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10906  *  \throw If there is a negative value in \a other.
10907  */
10908 void DataArrayInt::powEqual(const DataArrayInt *other)
10909 {
10910   if(!other)
10911     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10912   int nbOfTuple=getNumberOfTuples();
10913   int nbOfTuple2=other->getNumberOfTuples();
10914   int nbOfComp=getNumberOfComponents();
10915   int nbOfComp2=other->getNumberOfComponents();
10916   if(nbOfTuple!=nbOfTuple2)
10917     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10918   if(nbOfComp!=1 || nbOfComp2!=1)
10919     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10920   int *ptr=getPointer();
10921   const int *ptrc=other->begin();
10922   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10923     {
10924       if(*ptrc>=0)
10925         {
10926           int tmp=1;
10927           for(int j=0;j<*ptrc;j++)
10928             tmp*=*ptr;
10929           *ptr=tmp;
10930         }
10931       else
10932         {
10933           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10934           throw INTERP_KERNEL::Exception(oss.str().c_str());
10935         }
10936     }
10937   declareAsNew();
10938 }
10939
10940 /*!
10941  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10942  * This map, if applied to \a start array, would make it sorted. For example, if
10943  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10944  * [5,6,0,3,2,7,1,4].
10945  *  \param [in] start - pointer to the first element of the array for which the
10946  *         permutation map is computed.
10947  *  \param [in] end - pointer specifying the end of the array \a start, so that
10948  *         the last value of \a start is \a end[ -1 ].
10949  *  \return int * - the result permutation array that the caller is to delete as it is no
10950  *         more needed.
10951  *  \throw If there are equal values in the input array.
10952  */
10953 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10954 {
10955   std::size_t sz=std::distance(start,end);
10956   int *ret=(int *)malloc(sz*sizeof(int));
10957   int *work=new int[sz];
10958   std::copy(start,end,work);
10959   std::sort(work,work+sz);
10960   if(std::unique(work,work+sz)!=work+sz)
10961     {
10962       delete [] work;
10963       free(ret);
10964       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10965     }
10966   std::map<int,int> m;
10967   for(int *workPt=work;workPt!=work+sz;workPt++)
10968     m[*workPt]=(int)std::distance(work,workPt);
10969   int *iter2=ret;
10970   for(const int *iter=start;iter!=end;iter++,iter2++)
10971     *iter2=m[*iter];
10972   delete [] work;
10973   return ret;
10974 }
10975
10976 /*!
10977  * Returns a new DataArrayInt containing an arithmetic progression
10978  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10979  * function.
10980  *  \param [in] begin - the start value of the result sequence.
10981  *  \param [in] end - limiting value, so that every value of the result array is less than
10982  *              \a end.
10983  *  \param [in] step - specifies the increment or decrement.
10984  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10985  *          array using decrRef() as it is no more needed.
10986  *  \throw If \a step == 0.
10987  *  \throw If \a end < \a begin && \a step > 0.
10988  *  \throw If \a end > \a begin && \a step < 0.
10989  */
10990 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
10991 {
10992   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10993   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10994   ret->alloc(nbOfTuples,1);
10995   int *ptr=ret->getPointer();
10996   if(step>0)
10997     {
10998       for(int i=begin;i<end;i+=step,ptr++)
10999         *ptr=i;
11000     }
11001   else
11002     {
11003       for(int i=begin;i>end;i+=step,ptr++)
11004         *ptr=i;
11005     }
11006   return ret.retn();
11007 }
11008
11009 /*!
11010  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11011  * Server side.
11012  */
11013 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11014 {
11015   tinyInfo.resize(2);
11016   if(isAllocated())
11017     {
11018       tinyInfo[0]=getNumberOfTuples();
11019       tinyInfo[1]=getNumberOfComponents();
11020     }
11021   else
11022     {
11023       tinyInfo[0]=-1;
11024       tinyInfo[1]=-1;
11025     }
11026 }
11027
11028 /*!
11029  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11030  * Server side.
11031  */
11032 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11033 {
11034   if(isAllocated())
11035     {
11036       int nbOfCompo=getNumberOfComponents();
11037       tinyInfo.resize(nbOfCompo+1);
11038       tinyInfo[0]=getName();
11039       for(int i=0;i<nbOfCompo;i++)
11040         tinyInfo[i+1]=getInfoOnComponent(i);
11041     }
11042   else
11043     {
11044       tinyInfo.resize(1);
11045       tinyInfo[0]=getName();
11046     }
11047 }
11048
11049 /*!
11050  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11051  * This method returns if a feeding is needed.
11052  */
11053 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11054 {
11055   int nbOfTuple=tinyInfoI[0];
11056   int nbOfComp=tinyInfoI[1];
11057   if(nbOfTuple!=-1 || nbOfComp!=-1)
11058     {
11059       alloc(nbOfTuple,nbOfComp);
11060       return true;
11061     }
11062   return false;
11063 }
11064
11065 /*!
11066  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11067  * This method returns if a feeding is needed.
11068  */
11069 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11070 {
11071   setName(tinyInfoS[0].c_str());
11072   if(isAllocated())
11073     {
11074       int nbOfCompo=tinyInfoI[1];
11075       for(int i=0;i<nbOfCompo;i++)
11076         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
11077     }
11078 }
11079
11080 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11081 {
11082   if(_da)
11083     {
11084       _da->incrRef();
11085       if(_da->isAllocated())
11086         {
11087           _nb_comp=da->getNumberOfComponents();
11088           _nb_tuple=da->getNumberOfTuples();
11089           _pt=da->getPointer();
11090         }
11091     }
11092 }
11093
11094 DataArrayIntIterator::~DataArrayIntIterator()
11095 {
11096   if(_da)
11097     _da->decrRef();
11098 }
11099
11100 DataArrayIntTuple *DataArrayIntIterator::nextt()
11101 {
11102   if(_tuple_id<_nb_tuple)
11103     {
11104       _tuple_id++;
11105       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11106       _pt+=_nb_comp;
11107       return ret;
11108     }
11109   else
11110     return 0;
11111 }
11112
11113 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11114 {
11115 }
11116
11117 std::string DataArrayIntTuple::repr() const
11118 {
11119   std::ostringstream oss; oss << "(";
11120   for(int i=0;i<_nb_of_compo-1;i++)
11121     oss << _pt[i] << ", ";
11122   oss << _pt[_nb_of_compo-1] << ")";
11123   return oss.str();
11124 }
11125
11126 int DataArrayIntTuple::intValue() const
11127 {
11128   if(_nb_of_compo==1)
11129     return *_pt;
11130   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11131 }
11132
11133 /*!
11134  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11135  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11136  * 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
11137  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11138  */
11139 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11140 {
11141   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11142     {
11143       DataArrayInt *ret=DataArrayInt::New();
11144       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11145       return ret;
11146     }
11147   else
11148     {
11149       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11150       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11151       throw INTERP_KERNEL::Exception(oss.str().c_str());
11152     }
11153 }