Salome HOME
4th dimension of DataArrayDouble::findCommonTuples
[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   int *dest=ret->getPointer();
1352   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1353   for(const double *src=begin();src!=end();src++,dest++)
1354     *dest=(int)*src;
1355   ret->copyStringInfoFrom(*this);
1356   return ret;
1357 }
1358
1359 /*!
1360  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1361  * arranged in memory. If \a this array holds 2 components of 3 values:
1362  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1363  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1364  *  \warning Do not confuse this method with transpose()!
1365  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1366  *          is to delete using decrRef() as it is no more needed.
1367  *  \throw If \a this is not allocated.
1368  */
1369 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1370 {
1371   if(_mem.isNull())
1372     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1373   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1374   DataArrayDouble *ret=DataArrayDouble::New();
1375   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1376   return ret;
1377 }
1378
1379 /*!
1380  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1381  * arranged in memory. If \a this array holds 2 components of 3 values:
1382  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1383  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1384  *  \warning Do not confuse this method with transpose()!
1385  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1386  *          is to delete using decrRef() as it is no more needed.
1387  *  \throw If \a this is not allocated.
1388  */
1389 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1390 {
1391   if(_mem.isNull())
1392     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1393   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1394   DataArrayDouble *ret=DataArrayDouble::New();
1395   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1396   return ret;
1397 }
1398
1399 /*!
1400  * Permutes values of \a this array as required by \a old2New array. The values are
1401  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1402  * the same as in \this one.
1403  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1404  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1405  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1406  *     giving a new position for i-th old value.
1407  */
1408 void DataArrayDouble::renumberInPlace(const int *old2New)
1409 {
1410   checkAllocated();
1411   int nbTuples=getNumberOfTuples();
1412   int nbOfCompo=getNumberOfComponents();
1413   double *tmp=new double[nbTuples*nbOfCompo];
1414   const double *iptr=getConstPointer();
1415   for(int i=0;i<nbTuples;i++)
1416     {
1417       int v=old2New[i];
1418       if(v>=0 && v<nbTuples)
1419         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1420       else
1421         {
1422           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1423           throw INTERP_KERNEL::Exception(oss.str().c_str());
1424         }
1425     }
1426   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1427   delete [] tmp;
1428   declareAsNew();
1429 }
1430
1431 /*!
1432  * Permutes values of \a this array as required by \a new2Old array. The values are
1433  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1434  * the same as in \this one.
1435  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1436  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1437  *     giving a previous position of i-th new value.
1438  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1439  *          is to delete using decrRef() as it is no more needed.
1440  */
1441 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1442 {
1443   checkAllocated();
1444   int nbTuples=getNumberOfTuples();
1445   int nbOfCompo=getNumberOfComponents();
1446   double *tmp=new double[nbTuples*nbOfCompo];
1447   const double *iptr=getConstPointer();
1448   for(int i=0;i<nbTuples;i++)
1449     {
1450       int v=new2Old[i];
1451       if(v>=0 && v<nbTuples)
1452         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1453       else
1454         {
1455           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1456           throw INTERP_KERNEL::Exception(oss.str().c_str());
1457         }
1458     }
1459   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1460   delete [] tmp;
1461   declareAsNew();
1462 }
1463
1464 /*!
1465  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1466  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1467  * Number of tuples in the result array remains the same as in \this one.
1468  * If a permutation reduction is needed, renumberAndReduce() should be used.
1469  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1470  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1471  *          giving a new position for i-th old value.
1472  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1473  *          is to delete using decrRef() as it is no more needed.
1474  *  \throw If \a this is not allocated.
1475  */
1476 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1477 {
1478   checkAllocated();
1479   int nbTuples=getNumberOfTuples();
1480   int nbOfCompo=getNumberOfComponents();
1481   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1482   ret->alloc(nbTuples,nbOfCompo);
1483   ret->copyStringInfoFrom(*this);
1484   const double *iptr=getConstPointer();
1485   double *optr=ret->getPointer();
1486   for(int i=0;i<nbTuples;i++)
1487     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1488   ret->copyStringInfoFrom(*this);
1489   return ret.retn();
1490 }
1491
1492 /*!
1493  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1494  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1495  * tuples in the result array remains the same as in \this one.
1496  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1497  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1498  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1499  *     giving a previous position of i-th new value.
1500  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1501  *          is to delete using decrRef() as it is no more needed.
1502  */
1503 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1504 {
1505   checkAllocated();
1506   int nbTuples=getNumberOfTuples();
1507   int nbOfCompo=getNumberOfComponents();
1508   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1509   ret->alloc(nbTuples,nbOfCompo);
1510   ret->copyStringInfoFrom(*this);
1511   const double *iptr=getConstPointer();
1512   double *optr=ret->getPointer();
1513   for(int i=0;i<nbTuples;i++)
1514     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1515   ret->copyStringInfoFrom(*this);
1516   return ret.retn();
1517 }
1518
1519 /*!
1520  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1521  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1522  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1523  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1524  * \a old2New[ i ] is negative, is missing from the result array.
1525  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1526  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1527  *     giving a new position for i-th old tuple and giving negative position for
1528  *     for i-th old tuple that should be omitted.
1529  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1530  *          is to delete using decrRef() as it is no more needed.
1531  */
1532 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1533 {
1534   checkAllocated();
1535   int nbTuples=getNumberOfTuples();
1536   int nbOfCompo=getNumberOfComponents();
1537   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1538   ret->alloc(newNbOfTuple,nbOfCompo);
1539   const double *iptr=getConstPointer();
1540   double *optr=ret->getPointer();
1541   for(int i=0;i<nbTuples;i++)
1542     {
1543       int w=old2New[i];
1544       if(w>=0)
1545         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1546     }
1547   ret->copyStringInfoFrom(*this);
1548   return ret.retn();
1549 }
1550
1551 /*!
1552  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1553  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1554  * \a new2OldBg array.
1555  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1556  * This method is equivalent to renumberAndReduce() except that convention in input is
1557  * \c new2old and \b not \c old2new.
1558  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1559  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1560  *              tuple index in \a this array to fill the i-th tuple in the new array.
1561  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1562  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1563  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1564  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1565  *          is to delete using decrRef() as it is no more needed.
1566  */
1567 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1568 {
1569   checkAllocated();
1570   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1571   int nbComp=getNumberOfComponents();
1572   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1573   ret->copyStringInfoFrom(*this);
1574   double *pt=ret->getPointer();
1575   const double *srcPt=getConstPointer();
1576   int i=0;
1577   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1578     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1579   ret->copyStringInfoFrom(*this);
1580   return ret.retn();
1581 }
1582
1583 /*!
1584  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1585  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1586  * \a new2OldBg array.
1587  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1588  * This method is equivalent to renumberAndReduce() except that convention in input is
1589  * \c new2old and \b not \c old2new.
1590  * This method is equivalent to selectByTupleId() except that it prevents coping data
1591  * from behind the end of \a this array.
1592  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1593  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1594  *              tuple index in \a this array to fill the i-th tuple in the new array.
1595  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1596  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1597  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1598  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1599  *          is to delete using decrRef() as it is no more needed.
1600  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1601  */
1602 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1603 {
1604   checkAllocated();
1605   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1606   int nbComp=getNumberOfComponents();
1607   int oldNbOfTuples=getNumberOfTuples();
1608   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1609   ret->copyStringInfoFrom(*this);
1610   double *pt=ret->getPointer();
1611   const double *srcPt=getConstPointer();
1612   int i=0;
1613   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1614     if(*w>=0 && *w<oldNbOfTuples)
1615       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1616     else
1617       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1618   ret->copyStringInfoFrom(*this);
1619   return ret.retn();
1620 }
1621
1622 /*!
1623  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1624  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1625  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1626  * command \c range( \a bg, \a end2, \a step ).
1627  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1628  * not constructed explicitly.
1629  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1630  *  \param [in] bg - index of the first tuple to copy from \a this array.
1631  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1632  *  \param [in] step - index increment to get index of the next tuple to copy.
1633  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1634  *          is to delete using decrRef() as it is no more needed.
1635  *  \sa DataArrayDouble::substr.
1636  */
1637 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1638 {
1639   checkAllocated();
1640   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1641   int nbComp=getNumberOfComponents();
1642   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1643   ret->alloc(newNbOfTuples,nbComp);
1644   double *pt=ret->getPointer();
1645   const double *srcPt=getConstPointer()+bg*nbComp;
1646   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1647     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1648   ret->copyStringInfoFrom(*this);
1649   return ret.retn();
1650 }
1651
1652 /*!
1653  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1654  * of tuples specified by \a ranges parameter.
1655  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1656  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1657  *              of tuples in [\c begin,\c end) format.
1658  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1659  *          is to delete using decrRef() as it is no more needed.
1660  *  \throw If \a end < \a begin.
1661  *  \throw If \a end > \a this->getNumberOfTuples().
1662  *  \throw If \a this is not allocated.
1663  */
1664 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1665 {
1666   checkAllocated();
1667   int nbOfComp=getNumberOfComponents();
1668   int nbOfTuplesThis=getNumberOfTuples();
1669   if(ranges.empty())
1670     {
1671       DataArrayDouble *ret=DataArrayDouble::New();
1672       ret->alloc(0,nbOfComp);
1673       ret->copyStringInfoFrom(*this);
1674       return ret;
1675     }
1676   int ref=ranges.front().first;
1677   int nbOfTuples=0;
1678   bool isIncreasing=true;
1679   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1680     {
1681       if((*it).first<=(*it).second)
1682         {
1683           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1684             {
1685               nbOfTuples+=(*it).second-(*it).first;
1686               if(isIncreasing)
1687                 isIncreasing=ref<=(*it).first;
1688               ref=(*it).second;
1689             }
1690           else
1691             {
1692               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1693               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1694               throw INTERP_KERNEL::Exception(oss.str().c_str());
1695             }
1696         }
1697       else
1698         {
1699           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1700           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1701           throw INTERP_KERNEL::Exception(oss.str().c_str());
1702         }
1703     }
1704   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1705     return deepCpy();
1706   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1707   ret->alloc(nbOfTuples,nbOfComp);
1708   ret->copyStringInfoFrom(*this);
1709   const double *src=getConstPointer();
1710   double *work=ret->getPointer();
1711   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1712     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1713   return ret.retn();
1714 }
1715
1716 /*!
1717  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1718  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1719  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1720  * This method is a specialization of selectByTupleId2().
1721  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1722  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1723  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1724  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1725  *          is to delete using decrRef() as it is no more needed.
1726  *  \throw If \a tupleIdBg < 0.
1727  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1728     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1729  *  \sa DataArrayDouble::selectByTupleId2
1730  */
1731 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1732 {
1733   checkAllocated();
1734   int nbt=getNumberOfTuples();
1735   if(tupleIdBg<0)
1736     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1737   if(tupleIdBg>nbt)
1738     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1739   int trueEnd=tupleIdEnd;
1740   if(tupleIdEnd!=-1)
1741     {
1742       if(tupleIdEnd>nbt)
1743         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1744     }
1745   else
1746     trueEnd=nbt;
1747   int nbComp=getNumberOfComponents();
1748   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1749   ret->alloc(trueEnd-tupleIdBg,nbComp);
1750   ret->copyStringInfoFrom(*this);
1751   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1752   return ret.retn();
1753 }
1754
1755 /*!
1756  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1757  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1758  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1759  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1760  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1761  * components.  
1762  *  \param [in] newNbOfComp - number of components for the new array to have.
1763  *  \param [in] dftValue - value assigned to new values added to the new array.
1764  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1765  *          is to delete using decrRef() as it is no more needed.
1766  *  \throw If \a this is not allocated.
1767  */
1768 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1769 {
1770   checkAllocated();
1771   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1772   ret->alloc(getNumberOfTuples(),newNbOfComp);
1773   const double *oldc=getConstPointer();
1774   double *nc=ret->getPointer();
1775   int nbOfTuples=getNumberOfTuples();
1776   int oldNbOfComp=getNumberOfComponents();
1777   int dim=std::min(oldNbOfComp,newNbOfComp);
1778   for(int i=0;i<nbOfTuples;i++)
1779     {
1780       int j=0;
1781       for(;j<dim;j++)
1782         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1783       for(;j<newNbOfComp;j++)
1784         nc[newNbOfComp*i+j]=dftValue;
1785     }
1786   ret->setName(getName().c_str());
1787   for(int i=0;i<dim;i++)
1788     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1789   ret->setName(getName().c_str());
1790   return ret.retn();
1791 }
1792
1793 /*!
1794  * Changes the number of components within \a this array so that its raw data **does
1795  * not** change, instead splitting this data into tuples changes.
1796  *  \warning This method erases all (name and unit) component info set before!
1797  *  \param [in] newNbOfComp - number of components for \a this array to have.
1798  *  \throw If \a this is not allocated
1799  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1800  *  \throw If \a newNbOfCompo is lower than 1.
1801  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1802  *  \warning This method erases all (name and unit) component info set before!
1803  */
1804 void DataArrayDouble::rearrange(int newNbOfCompo)
1805 {
1806   checkAllocated();
1807   if(newNbOfCompo<1)
1808     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1809   std::size_t nbOfElems=getNbOfElems();
1810   if(nbOfElems%newNbOfCompo!=0)
1811     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1812   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1813     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1814   _info_on_compo.clear();
1815   _info_on_compo.resize(newNbOfCompo);
1816   declareAsNew();
1817 }
1818
1819 /*!
1820  * Changes the number of components within \a this array to be equal to its number
1821  * of tuples, and inversely its number of tuples to become equal to its number of 
1822  * components. So that its raw data **does not** change, instead splitting this
1823  * data into tuples changes.
1824  *  \warning This method erases all (name and unit) component info set before!
1825  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1826  *  \throw If \a this is not allocated.
1827  *  \sa rearrange()
1828  */
1829 void DataArrayDouble::transpose()
1830 {
1831   checkAllocated();
1832   int nbOfTuples=getNumberOfTuples();
1833   rearrange(nbOfTuples);
1834 }
1835
1836 /*!
1837  * Returns a copy of \a this array composed of selected components.
1838  * The new DataArrayDouble has the same number of tuples but includes components
1839  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1840  * can be either less, same or more than \a this->getNbOfElems().
1841  *  \param [in] compoIds - sequence of zero based indices of components to include
1842  *              into the new array.
1843  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1844  *          is to delete using decrRef() as it is no more needed.
1845  *  \throw If \a this is not allocated.
1846  *  \throw If a component index (\a i) is not valid: 
1847  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1848  *
1849  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1850  */
1851 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1852 {
1853   checkAllocated();
1854   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1855   std::size_t newNbOfCompo=compoIds.size();
1856   int oldNbOfCompo=getNumberOfComponents();
1857   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1858     if((*it)<0 || (*it)>=oldNbOfCompo)
1859       {
1860         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1861         throw INTERP_KERNEL::Exception(oss.str().c_str());
1862       }
1863   int nbOfTuples=getNumberOfTuples();
1864   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1865   ret->copyPartOfStringInfoFrom(*this,compoIds);
1866   const double *oldc=getConstPointer();
1867   double *nc=ret->getPointer();
1868   for(int i=0;i<nbOfTuples;i++)
1869     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1870       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1871   return ret.retn();
1872 }
1873
1874 /*!
1875  * Appends components of another array to components of \a this one, tuple by tuple.
1876  * So that the number of tuples of \a this array remains the same and the number of 
1877  * components increases.
1878  *  \param [in] other - the DataArrayDouble to append to \a this one.
1879  *  \throw If \a this is not allocated.
1880  *  \throw If \a this and \a other arrays have different number of tuples.
1881  *
1882  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1883  *
1884  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1885  */
1886 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1887 {
1888   checkAllocated();
1889   other->checkAllocated();
1890   int nbOfTuples=getNumberOfTuples();
1891   if(nbOfTuples!=other->getNumberOfTuples())
1892     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1893   int nbOfComp1=getNumberOfComponents();
1894   int nbOfComp2=other->getNumberOfComponents();
1895   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1896   double *w=newArr;
1897   const double *inp1=getConstPointer();
1898   const double *inp2=other->getConstPointer();
1899   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1900     {
1901       w=std::copy(inp1,inp1+nbOfComp1,w);
1902       w=std::copy(inp2,inp2+nbOfComp2,w);
1903     }
1904   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1905   std::vector<int> compIds(nbOfComp2);
1906   for(int i=0;i<nbOfComp2;i++)
1907     compIds[i]=nbOfComp1+i;
1908   copyPartOfStringInfoFrom2(compIds,*other);
1909 }
1910
1911 /*!
1912  * This method checks that all tuples in \a other are in \a this.
1913  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1914  * 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.
1915  *
1916  * \param [in] other - the array having the same number of components than \a this.
1917  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1918  * \sa DataArrayDouble::findCommonTuples
1919  */
1920 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1921 {
1922   if(!other)
1923     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1924   checkAllocated(); other->checkAllocated();
1925   if(getNumberOfComponents()!=other->getNumberOfComponents())
1926     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1927   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1928   DataArrayInt *c=0,*ci=0;
1929   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1930   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1931   int newNbOfTuples=-1;
1932   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1934   tupleIds=ret1.retn();
1935   return newNbOfTuples==getNumberOfTuples();
1936 }
1937
1938 /*!
1939  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1940  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1941  * distance separating two points is computed with the infinite norm.
1942  *
1943  * Indices of coincident tuples are stored in output arrays.
1944  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1945  *
1946  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1947  * MEDCouplingUMesh::mergeNodes().
1948  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1949  *              considered not coincident.
1950  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1951  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1952  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1953  *               \a comm->getNumberOfComponents() == 1. 
1954  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1955  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1956  *               groups of (indices of) coincident tuples. Its every value is a tuple
1957  *               index where a next group of tuples begins. For example the second
1958  *               group of tuples in \a comm is described by following range of indices:
1959  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1960  *               gives the number of groups of coincident tuples.
1961  *  \throw If \a this is not allocated.
1962  *  \throw If the number of components is not in [1,2,3,4].
1963  *
1964  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1965  *
1966  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1967  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1968  */
1969 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1970 {
1971   checkAllocated();
1972   int nbOfCompo=getNumberOfComponents();
1973   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1974     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1975   
1976   int nbOfTuples=getNumberOfTuples();
1977   //
1978   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1979   switch(nbOfCompo)
1980     {
1981     case 4:
1982       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1983       break;
1984     case 3:
1985       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1986       break;
1987     case 2:
1988       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1989       break;
1990     case 1:
1991       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1992       break;
1993     default:
1994       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1995     }
1996   comm=c.retn();
1997   commIndex=cI.retn();
1998 }
1999
2000 /*!
2001  * 
2002  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2003  *             \a nbTimes  should be at least equal to 1.
2004  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2005  * \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.
2006  */
2007 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2008 {
2009   checkAllocated();
2010   if(getNumberOfComponents()!=1)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2012   if(nbTimes<1)
2013     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2014   int nbTuples=getNumberOfTuples();
2015   const double *inPtr=getConstPointer();
2016   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2017   double *retPtr=ret->getPointer();
2018   for(int i=0;i<nbTuples;i++,inPtr++)
2019     {
2020       double val=*inPtr;
2021       for(int j=0;j<nbTimes;j++,retPtr++)
2022         *retPtr=val;
2023     }
2024   ret->copyStringInfoFrom(*this);
2025   return ret.retn();
2026 }
2027
2028 /*!
2029  * This methods returns the minimal distance between the two set of points \a this and \a other.
2030  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2031  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2032  *
2033  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2034  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2035  * \return the minimal distance between the two set of points \a this and \a other.
2036  * \sa DataArrayDouble::findClosestTupleId
2037  */
2038 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2039 {
2040   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2041   int nbOfCompo(getNumberOfComponents());
2042   int otherNbTuples(other->getNumberOfTuples());
2043   const double *thisPt(begin()),*otherPt(other->begin());
2044   const int *part1Pt(part1->begin());
2045   double ret=std::numeric_limits<double>::max();
2046   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2047     {
2048       double tmp(0.);
2049       for(int j=0;j<nbOfCompo;j++)
2050         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2051       if(tmp<ret)
2052         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2053     }
2054   return sqrt(ret);
2055 }
2056
2057 /*!
2058  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2059  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2060  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2061  *
2062  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2063  * \sa DataArrayDouble::minimalDistanceTo
2064  */
2065 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2066 {
2067   if(!other)
2068     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2069   checkAllocated(); other->checkAllocated();
2070   int nbOfCompo=getNumberOfComponents();
2071   if(nbOfCompo!=other->getNumberOfComponents())
2072     {
2073       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2074       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2075       throw INTERP_KERNEL::Exception(oss.str().c_str());
2076     }
2077   int nbOfTuples=other->getNumberOfTuples();
2078   int thisNbOfTuples=getNumberOfTuples();
2079   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2080   double bounds[6];
2081   getMinMaxPerComponent(bounds);
2082   switch(nbOfCompo)
2083     {
2084     case 3:
2085       {
2086         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2087         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2088         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2089         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2090         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2091         break;
2092       }
2093     case 2:
2094       {
2095         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2096         double delta=std::max(xDelta,yDelta);
2097         double characSize=sqrt(delta/(double)thisNbOfTuples);
2098         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2099         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2100         break;
2101       }
2102     case 1:
2103       {
2104         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2105         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2106         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2107         break;
2108       }
2109     default:
2110       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2111     }
2112   return ret.retn();
2113 }
2114
2115 /*!
2116  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2117  * 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
2118  * how many bounding boxes in \a otherBBoxFrmt.
2119  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2120  *
2121  * \param [in] otherBBoxFrmt - It is an array .
2122  * \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.
2123  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2124  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2125  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2126  */
2127 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2128 {
2129   if(!otherBBoxFrmt)
2130     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2131   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2132     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2133   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2134   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2135     {
2136       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2137       throw INTERP_KERNEL::Exception(oss.str().c_str());
2138     }
2139   if(nbOfComp%2!=0)
2140     {
2141       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2142       throw INTERP_KERNEL::Exception(oss.str().c_str());
2143     }
2144   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2145   const double *thisBBPtr(begin());
2146   int *retPtr(ret->getPointer());
2147   switch(nbOfComp/2)
2148     {
2149     case 3:
2150       {
2151         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2152         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2153           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2154         break;
2155       }
2156     case 2:
2157       {
2158         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2159         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2160           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2161         break;
2162       }
2163     case 1:
2164       {
2165         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2166         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2167           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2168         break;
2169       }
2170     default:
2171       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2172     }
2173   
2174   return ret.retn();
2175 }
2176
2177 /*!
2178  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2179  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2180  * space. The distance between tuples is computed using norm2. If several tuples are
2181  * not far each from other than \a prec, only one of them remains in the result
2182  * array. The order of tuples in the result array is same as in \a this one except
2183  * that coincident tuples are excluded.
2184  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2185  *              considered not coincident.
2186  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2187  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2188  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2189  *          is to delete using decrRef() as it is no more needed.
2190  *  \throw If \a this is not allocated.
2191  *  \throw If the number of components is not in [1,2,3,4].
2192  *
2193  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2194  */
2195 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2196 {
2197   checkAllocated();
2198   DataArrayInt *c0=0,*cI0=0;
2199   findCommonTuples(prec,limitTupleId,c0,cI0);
2200   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2201   int newNbOfTuples=-1;
2202   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2203   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2204 }
2205
2206 /*!
2207  * Copy all components in a specified order from another DataArrayDouble.
2208  * Both numerical and textual data is copied. The number of tuples in \a this and
2209  * the other array can be different.
2210  *  \param [in] a - the array to copy data from.
2211  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2212  *              to be copied.
2213  *  \throw If \a a is NULL.
2214  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2215  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2216  *
2217  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2218  */
2219 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2220 {
2221   if(!a)
2222     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2223   checkAllocated();
2224   copyPartOfStringInfoFrom2(compoIds,*a);
2225   std::size_t partOfCompoSz=compoIds.size();
2226   int nbOfCompo=getNumberOfComponents();
2227   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2228   const double *ac=a->getConstPointer();
2229   double *nc=getPointer();
2230   for(int i=0;i<nbOfTuples;i++)
2231     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2232       nc[nbOfCompo*i+compoIds[j]]=*ac;
2233 }
2234
2235 /*!
2236  * Copy all values from another DataArrayDouble into specified tuples and components
2237  * of \a this array. Textual data is not copied.
2238  * The tree parameters defining set of indices of tuples and components are similar to
2239  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2240  *  \param [in] a - the array to copy values from.
2241  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2242  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2243  *              are located.
2244  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2245  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2246  *  \param [in] endComp - index of the component before which the components to assign
2247  *              to are located.
2248  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2249  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2250  *              must be equal to the number of columns to assign to, else an
2251  *              exception is thrown; if \a false, then it is only required that \a
2252  *              a->getNbOfElems() equals to number of values to assign to (this condition
2253  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2254  *              values to assign to is given by following Python expression:
2255  *              \a nbTargetValues = 
2256  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2257  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2258  *  \throw If \a a is NULL.
2259  *  \throw If \a a is not allocated.
2260  *  \throw If \a this is not allocated.
2261  *  \throw If parameters specifying tuples and components to assign to do not give a
2262  *            non-empty range of increasing indices.
2263  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2264  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2265  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2266  *
2267  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2268  */
2269 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2270 {
2271   if(!a)
2272     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2273   const char msg[]="DataArrayDouble::setPartOfValues1";
2274   checkAllocated();
2275   a->checkAllocated();
2276   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2277   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2278   int nbComp=getNumberOfComponents();
2279   int nbOfTuples=getNumberOfTuples();
2280   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2281   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2282   bool assignTech=true;
2283   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2284     {
2285       if(strictCompoCompare)
2286         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2287     }
2288   else
2289     {
2290       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2291       assignTech=false;
2292     }
2293   const double *srcPt=a->getConstPointer();
2294   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2295   if(assignTech)
2296     {
2297       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2298         for(int j=0;j<newNbOfComp;j++,srcPt++)
2299           pt[j*stepComp]=*srcPt;
2300     }
2301   else
2302     {
2303       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2304         {
2305           const double *srcPt2=srcPt;
2306           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2307             pt[j*stepComp]=*srcPt2;
2308         }
2309     }
2310 }
2311
2312 /*!
2313  * Assign a given value to values at specified tuples and components of \a this array.
2314  * The tree parameters defining set of indices of tuples and components are similar to
2315  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2316  *  \param [in] a - the value to assign.
2317  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2318  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2319  *              are located.
2320  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2321  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2322  *  \param [in] endComp - index of the component before which the components to assign
2323  *              to are located.
2324  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2325  *  \throw If \a this is not allocated.
2326  *  \throw If parameters specifying tuples and components to assign to, do not give a
2327  *            non-empty range of increasing indices or indices are out of a valid range
2328  *            for \this array.
2329  *
2330  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2331  */
2332 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2333 {
2334   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2335   checkAllocated();
2336   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2337   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2338   int nbComp=getNumberOfComponents();
2339   int nbOfTuples=getNumberOfTuples();
2340   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2341   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2342   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2343   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2344     for(int j=0;j<newNbOfComp;j++)
2345       pt[j*stepComp]=a;
2346 }
2347
2348 /*!
2349  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2350  * components of \a this array. Textual data is not copied.
2351  * The tuples and components to assign to are defined by C arrays of indices.
2352  * There are two *modes of usage*:
2353  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2354  *   of \a a is assigned to its own location within \a this array. 
2355  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2356  *   components of every specified tuple of \a this array. In this mode it is required
2357  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2358  *
2359  *  \param [in] a - the array to copy values from.
2360  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2361  *              assign values of \a a to.
2362  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2363  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2364  *              \a bgTuples <= \a pi < \a endTuples.
2365  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2366  *              assign values of \a a to.
2367  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2368  *              pointer to a component index <em>(pi)</em> varies as this: 
2369  *              \a bgComp <= \a pi < \a endComp.
2370  *  \param [in] strictCompoCompare - this parameter is checked only if the
2371  *               *mode of usage* is the first; if it is \a true (default), 
2372  *               then \a a->getNumberOfComponents() must be equal 
2373  *               to the number of specified columns, else this is not required.
2374  *  \throw If \a a is NULL.
2375  *  \throw If \a a is not allocated.
2376  *  \throw If \a this is not allocated.
2377  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2378  *         out of a valid range for \a this array.
2379  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2380  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2381  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2382  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2383  *
2384  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2385  */
2386 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2387 {
2388   if(!a)
2389     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2390   const char msg[]="DataArrayDouble::setPartOfValues2";
2391   checkAllocated();
2392   a->checkAllocated();
2393   int nbComp=getNumberOfComponents();
2394   int nbOfTuples=getNumberOfTuples();
2395   for(const int *z=bgComp;z!=endComp;z++)
2396     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2397   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2398   int newNbOfComp=(int)std::distance(bgComp,endComp);
2399   bool assignTech=true;
2400   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2401     {
2402       if(strictCompoCompare)
2403         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2404     }
2405   else
2406     {
2407       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2408       assignTech=false;
2409     }
2410   double *pt=getPointer();
2411   const double *srcPt=a->getConstPointer();
2412   if(assignTech)
2413     {    
2414       for(const int *w=bgTuples;w!=endTuples;w++)
2415         {
2416           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2417           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2418             {    
2419               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2420             }
2421         }
2422     }
2423   else
2424     {
2425       for(const int *w=bgTuples;w!=endTuples;w++)
2426         {
2427           const double *srcPt2=srcPt;
2428           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2429           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2430             {    
2431               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2432             }
2433         }
2434     }
2435 }
2436
2437 /*!
2438  * Assign a given value to values at specified tuples and components of \a this array.
2439  * The tuples and components to assign to are defined by C arrays of indices.
2440  *  \param [in] a - the value to assign.
2441  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2442  *              assign \a a to.
2443  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2444  *              pointer to a tuple index (\a pi) varies as this: 
2445  *              \a bgTuples <= \a pi < \a endTuples.
2446  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2447  *              assign \a a to.
2448  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2449  *              pointer to a component index (\a pi) varies as this: 
2450  *              \a bgComp <= \a pi < \a endComp.
2451  *  \throw If \a this is not allocated.
2452  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2453  *         out of a valid range for \a this array.
2454  *
2455  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2456  */
2457 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2458 {
2459   checkAllocated();
2460   int nbComp=getNumberOfComponents();
2461   int nbOfTuples=getNumberOfTuples();
2462   for(const int *z=bgComp;z!=endComp;z++)
2463     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2464   double *pt=getPointer();
2465   for(const int *w=bgTuples;w!=endTuples;w++)
2466     for(const int *z=bgComp;z!=endComp;z++)
2467       {
2468         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2469         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2470       }
2471 }
2472
2473 /*!
2474  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2475  * components of \a this array. Textual data is not copied.
2476  * The tuples to assign to are defined by a C array of indices.
2477  * The components to assign to are defined by three values similar to parameters of
2478  * the Python function \c range(\c start,\c stop,\c step).
2479  * There are two *modes of usage*:
2480  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2481  *   of \a a is assigned to its own location within \a this array. 
2482  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2483  *   components of every specified tuple of \a this array. In this mode it is required
2484  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2485  *
2486  *  \param [in] a - the array to copy values from.
2487  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2488  *              assign values of \a a to.
2489  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2490  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2491  *              \a bgTuples <= \a pi < \a endTuples.
2492  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2493  *  \param [in] endComp - index of the component before which the components to assign
2494  *              to are located.
2495  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2496  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2497  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2498  *               then \a a->getNumberOfComponents() must be equal 
2499  *               to the number of specified columns, else this is not required.
2500  *  \throw If \a a is NULL.
2501  *  \throw If \a a is not allocated.
2502  *  \throw If \a this is not allocated.
2503  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2504  *         \a this array.
2505  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2506  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2507  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2508  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2509  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2510  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2511  *  \throw If parameters specifying components to assign to, do not give a
2512  *            non-empty range of increasing indices or indices are out of a valid range
2513  *            for \this array.
2514  *
2515  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2516  */
2517 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2518 {
2519   if(!a)
2520     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2521   const char msg[]="DataArrayDouble::setPartOfValues3";
2522   checkAllocated();
2523   a->checkAllocated();
2524   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2525   int nbComp=getNumberOfComponents();
2526   int nbOfTuples=getNumberOfTuples();
2527   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2528   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2529   bool assignTech=true;
2530   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2531     {
2532       if(strictCompoCompare)
2533         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2534     }
2535   else
2536     {
2537       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2538       assignTech=false;
2539     }
2540   double *pt=getPointer()+bgComp;
2541   const double *srcPt=a->getConstPointer();
2542   if(assignTech)
2543     {
2544       for(const int *w=bgTuples;w!=endTuples;w++)
2545         for(int j=0;j<newNbOfComp;j++,srcPt++)
2546           {
2547             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2548             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2549           }
2550     }
2551   else
2552     {
2553       for(const int *w=bgTuples;w!=endTuples;w++)
2554         {
2555           const double *srcPt2=srcPt;
2556           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2557             {
2558               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2559               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2560             }
2561         }
2562     }
2563 }
2564
2565 /*!
2566  * Assign a given value to values at specified tuples and components of \a this array.
2567  * The tuples to assign to are defined by a C array of indices.
2568  * The components to assign to are defined by three values similar to parameters of
2569  * the Python function \c range(\c start,\c stop,\c step).
2570  *  \param [in] a - the value to assign.
2571  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2572  *              assign \a a to.
2573  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2574  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2575  *              \a bgTuples <= \a pi < \a endTuples.
2576  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2577  *  \param [in] endComp - index of the component before which the components to assign
2578  *              to are located.
2579  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2580  *  \throw If \a this is not allocated.
2581  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2582  *         \a this array.
2583  *  \throw If parameters specifying components to assign to, do not give a
2584  *            non-empty range of increasing indices or indices are out of a valid range
2585  *            for \this array.
2586  *
2587  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2588  */
2589 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2590 {
2591   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2592   checkAllocated();
2593   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2594   int nbComp=getNumberOfComponents();
2595   int nbOfTuples=getNumberOfTuples();
2596   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2597   double *pt=getPointer()+bgComp;
2598   for(const int *w=bgTuples;w!=endTuples;w++)
2599     for(int j=0;j<newNbOfComp;j++)
2600       {
2601         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2602         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2603       }
2604 }
2605
2606 /*!
2607  * Copy all values from another DataArrayDouble into specified tuples and components
2608  * of \a this array. Textual data is not copied.
2609  * The tree parameters defining set of indices of tuples and components are similar to
2610  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2611  *  \param [in] a - the array to copy values from.
2612  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2613  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2614  *              are located.
2615  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2616  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2617  *              assign \a a to.
2618  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2619  *              pointer to a component index (\a pi) varies as this: 
2620  *              \a bgComp <= \a pi < \a endComp.
2621  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2622  *              must be equal to the number of columns to assign to, else an
2623  *              exception is thrown; if \a false, then it is only required that \a
2624  *              a->getNbOfElems() equals to number of values to assign to (this condition
2625  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2626  *              values to assign to is given by following Python expression:
2627  *              \a nbTargetValues = 
2628  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2629  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2630  *  \throw If \a a is NULL.
2631  *  \throw If \a a is not allocated.
2632  *  \throw If \a this is not allocated.
2633  *  \throw If parameters specifying tuples and components to assign to do not give a
2634  *            non-empty range of increasing indices.
2635  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2636  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2637  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2638  *
2639  */
2640 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2641 {
2642   if(!a)
2643     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2644   const char msg[]="DataArrayDouble::setPartOfValues4";
2645   checkAllocated();
2646   a->checkAllocated();
2647   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2648   int newNbOfComp=(int)std::distance(bgComp,endComp);
2649   int nbComp=getNumberOfComponents();
2650   for(const int *z=bgComp;z!=endComp;z++)
2651     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2652   int nbOfTuples=getNumberOfTuples();
2653   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2654   bool assignTech=true;
2655   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2656     {
2657       if(strictCompoCompare)
2658         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2659     }
2660   else
2661     {
2662       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2663       assignTech=false;
2664     }
2665   const double *srcPt=a->getConstPointer();
2666   double *pt=getPointer()+bgTuples*nbComp;
2667   if(assignTech)
2668     {
2669       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2670         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2671           pt[*z]=*srcPt;
2672     }
2673   else
2674     {
2675       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2676         {
2677           const double *srcPt2=srcPt;
2678           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2679             pt[*z]=*srcPt2;
2680         }
2681     }
2682 }
2683
2684 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2685 {
2686   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2687   checkAllocated();
2688   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2689   int nbComp=getNumberOfComponents();
2690   for(const int *z=bgComp;z!=endComp;z++)
2691     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2692   int nbOfTuples=getNumberOfTuples();
2693   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2694   double *pt=getPointer()+bgTuples*nbComp;
2695   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2696     for(const int *z=bgComp;z!=endComp;z++)
2697       pt[*z]=a;
2698 }
2699
2700 /*!
2701  * Copy some tuples from another DataArrayDouble into specified tuples
2702  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2703  * components.
2704  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2705  * All components of selected tuples are copied.
2706  *  \param [in] a - the array to copy values from.
2707  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2708  *              target tuples of \a this. \a tuplesSelec has two components, and the
2709  *              first component specifies index of the source tuple and the second
2710  *              one specifies index of the target tuple.
2711  *  \throw If \a this is not allocated.
2712  *  \throw If \a a is NULL.
2713  *  \throw If \a a is not allocated.
2714  *  \throw If \a tuplesSelec is NULL.
2715  *  \throw If \a tuplesSelec is not allocated.
2716  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2717  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2718  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2719  *         the corresponding (\a this or \a a) array.
2720  */
2721 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2722 {
2723   if(!a || !tuplesSelec)
2724     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2725   checkAllocated();
2726   a->checkAllocated();
2727   tuplesSelec->checkAllocated();
2728   int nbOfComp=getNumberOfComponents();
2729   if(nbOfComp!=a->getNumberOfComponents())
2730     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2731   if(tuplesSelec->getNumberOfComponents()!=2)
2732     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2733   int thisNt=getNumberOfTuples();
2734   int aNt=a->getNumberOfTuples();
2735   double *valsToSet=getPointer();
2736   const double *valsSrc=a->getConstPointer();
2737   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2738     {
2739       if(tuple[1]>=0 && tuple[1]<aNt)
2740         {
2741           if(tuple[0]>=0 && tuple[0]<thisNt)
2742             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2743           else
2744             {
2745               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2746               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2747               throw INTERP_KERNEL::Exception(oss.str().c_str());
2748             }
2749         }
2750       else
2751         {
2752           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2753           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2754           throw INTERP_KERNEL::Exception(oss.str().c_str());
2755         }
2756     }
2757 }
2758
2759 /*!
2760  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2761  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2762  * components.
2763  * The tuples to assign to are defined by index of the first tuple, and
2764  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2765  * The tuples to copy are defined by values of a DataArrayInt.
2766  * All components of selected tuples are copied.
2767  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2768  *              values to.
2769  *  \param [in] aBase - the array to copy values from.
2770  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2771  *  \throw If \a this is not allocated.
2772  *  \throw If \a aBase is NULL.
2773  *  \throw If \a aBase is not allocated.
2774  *  \throw If \a tuplesSelec is NULL.
2775  *  \throw If \a tuplesSelec is not allocated.
2776  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2777  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2778  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2779  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2780  *         \a aBase array.
2781  */
2782 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2783 {
2784   if(!aBase || !tuplesSelec)
2785     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2786   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2787   if(!a)
2788     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2789   checkAllocated();
2790   a->checkAllocated();
2791   tuplesSelec->checkAllocated();
2792   int nbOfComp=getNumberOfComponents();
2793   if(nbOfComp!=a->getNumberOfComponents())
2794     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2795   if(tuplesSelec->getNumberOfComponents()!=1)
2796     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2797   int thisNt=getNumberOfTuples();
2798   int aNt=a->getNumberOfTuples();
2799   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2800   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2801   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2802     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2803   const double *valsSrc=a->getConstPointer();
2804   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2805     {
2806       if(*tuple>=0 && *tuple<aNt)
2807         {
2808           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2809         }
2810       else
2811         {
2812           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2813           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2814           throw INTERP_KERNEL::Exception(oss.str().c_str());
2815         }
2816     }
2817 }
2818
2819 /*!
2820  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2821  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2822  * components.
2823  * The tuples to copy are defined by three values similar to parameters of
2824  * the Python function \c range(\c start,\c stop,\c step).
2825  * The tuples to assign to are defined by index of the first tuple, and
2826  * their number is defined by number of tuples to copy.
2827  * All components of selected tuples are copied.
2828  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2829  *              values to.
2830  *  \param [in] aBase - the array to copy values from.
2831  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2832  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2833  *              are located.
2834  *  \param [in] step - index increment to get index of the next tuple to copy.
2835  *  \throw If \a this is not allocated.
2836  *  \throw If \a aBase is NULL.
2837  *  \throw If \a aBase is not allocated.
2838  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2839  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2840  *  \throw If parameters specifying tuples to copy, do not give a
2841  *            non-empty range of increasing indices or indices are out of a valid range
2842  *            for the array \a aBase.
2843  */
2844 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2845 {
2846   if(!aBase)
2847     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2848   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2849   if(!a)
2850     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2851   checkAllocated();
2852   a->checkAllocated();
2853   int nbOfComp=getNumberOfComponents();
2854   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2855   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2856   if(nbOfComp!=a->getNumberOfComponents())
2857     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2858   int thisNt=getNumberOfTuples();
2859   int aNt=a->getNumberOfTuples();
2860   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2861   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2862     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2863   if(end2>aNt)
2864     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2865   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2866   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2867     {
2868       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2869     }
2870 }
2871
2872 /*!
2873  * Returns a value located at specified tuple and component.
2874  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2875  * parameters is checked. So this method is safe but expensive if used to go through
2876  * all values of \a this.
2877  *  \param [in] tupleId - index of tuple of interest.
2878  *  \param [in] compoId - index of component of interest.
2879  *  \return double - value located by \a tupleId and \a compoId.
2880  *  \throw If \a this is not allocated.
2881  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2882  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2883  */
2884 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2885 {
2886   checkAllocated();
2887   if(tupleId<0 || tupleId>=getNumberOfTuples())
2888     {
2889       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2890       throw INTERP_KERNEL::Exception(oss.str().c_str());
2891     }
2892   if(compoId<0 || compoId>=getNumberOfComponents())
2893     {
2894       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2895       throw INTERP_KERNEL::Exception(oss.str().c_str());
2896     }
2897   return _mem[tupleId*_info_on_compo.size()+compoId];
2898 }
2899
2900 /*!
2901  * Returns the first value of \a this. 
2902  *  \return double - the last value of \a this array.
2903  *  \throw If \a this is not allocated.
2904  *  \throw If \a this->getNumberOfComponents() != 1.
2905  *  \throw If \a this->getNumberOfTuples() < 1.
2906  */
2907 double DataArrayDouble::front() const
2908 {
2909   checkAllocated();
2910   if(getNumberOfComponents()!=1)
2911     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2912   int nbOfTuples=getNumberOfTuples();
2913   if(nbOfTuples<1)
2914     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2915   return *(getConstPointer());
2916 }
2917
2918 /*!
2919  * Returns the last value of \a this. 
2920  *  \return double - the last value of \a this array.
2921  *  \throw If \a this is not allocated.
2922  *  \throw If \a this->getNumberOfComponents() != 1.
2923  *  \throw If \a this->getNumberOfTuples() < 1.
2924  */
2925 double DataArrayDouble::back() const
2926 {
2927   checkAllocated();
2928   if(getNumberOfComponents()!=1)
2929     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2930   int nbOfTuples=getNumberOfTuples();
2931   if(nbOfTuples<1)
2932     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2933   return *(getConstPointer()+nbOfTuples-1);
2934 }
2935
2936 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2937 {
2938   if(newArray!=arrayToSet)
2939     {
2940       if(arrayToSet)
2941         arrayToSet->decrRef();
2942       arrayToSet=newArray;
2943       if(arrayToSet)
2944         arrayToSet->incrRef();
2945     }
2946 }
2947
2948 /*!
2949  * Sets a C array to be used as raw data of \a this. The previously set info
2950  *  of components is retained and re-sized. 
2951  * For more info see \ref MEDCouplingArraySteps1.
2952  *  \param [in] array - the C array to be used as raw data of \a this.
2953  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2954  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2955  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2956  *                     \c free(\c array ) will be called.
2957  *  \param [in] nbOfTuple - new number of tuples in \a this.
2958  *  \param [in] nbOfCompo - new number of components in \a this.
2959  */
2960 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2961 {
2962   _info_on_compo.resize(nbOfCompo);
2963   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2964   declareAsNew();
2965 }
2966
2967 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
2968 {
2969   _info_on_compo.resize(nbOfCompo);
2970   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2971   declareAsNew();
2972 }
2973
2974 /*!
2975  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2976  * is thrown.
2977  * \throw If zero is found in \a this array.
2978  */
2979 void DataArrayDouble::checkNoNullValues() const
2980 {
2981   const double *tmp=getConstPointer();
2982   std::size_t nbOfElems=getNbOfElems();
2983   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2984   if(where!=tmp+nbOfElems)
2985     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2986 }
2987
2988 /*!
2989  * Computes minimal and maximal value in each component. An output array is filled
2990  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2991  * enough memory before calling this method.
2992  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2993  *               It is filled as follows:<br>
2994  *               \a bounds[0] = \c min_of_component_0 <br>
2995  *               \a bounds[1] = \c max_of_component_0 <br>
2996  *               \a bounds[2] = \c min_of_component_1 <br>
2997  *               \a bounds[3] = \c max_of_component_1 <br>
2998  *               ...
2999  */
3000 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3001 {
3002   checkAllocated();
3003   int dim=getNumberOfComponents();
3004   for (int idim=0; idim<dim; idim++)
3005     {
3006       bounds[idim*2]=std::numeric_limits<double>::max();
3007       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3008     } 
3009   const double *ptr=getConstPointer();
3010   int nbOfTuples=getNumberOfTuples();
3011   for(int i=0;i<nbOfTuples;i++)
3012     {
3013       for(int idim=0;idim<dim;idim++)
3014         {
3015           if(bounds[idim*2]>ptr[i*dim+idim])
3016             {
3017               bounds[idim*2]=ptr[i*dim+idim];
3018             }
3019           if(bounds[idim*2+1]<ptr[i*dim+idim])
3020             {
3021               bounds[idim*2+1]=ptr[i*dim+idim];
3022             }
3023         }
3024     }
3025 }
3026
3027 /*!
3028  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3029  * to store both the min and max per component of each tuples. 
3030  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3031  *
3032  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3033  *
3034  * \throw If \a this is not allocated yet.
3035  */
3036 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3037 {
3038   checkAllocated();
3039   const double *dataPtr=getConstPointer();
3040   int nbOfCompo=getNumberOfComponents();
3041   int nbTuples=getNumberOfTuples();
3042   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3043   bbox->alloc(nbTuples,2*nbOfCompo);
3044   double *bboxPtr=bbox->getPointer();
3045   for(int i=0;i<nbTuples;i++)
3046     {
3047       for(int j=0;j<nbOfCompo;j++)
3048         {
3049           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3050           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3051         }
3052     }
3053   return bbox.retn();
3054 }
3055
3056 /*!
3057  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3058  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3059  * 
3060  * \param [in] other a DataArrayDouble having same number of components than \a this.
3061  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3062  * \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.
3063  *             \a cI allows to extract information in \a c.
3064  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3065  *
3066  * \throw In case of:
3067  *  - \a this is not allocated
3068  *  - \a other is not allocated or null
3069  *  - \a this and \a other do not have the same number of components
3070  *  - if number of components of \a this is not in [1,2,3]
3071  *
3072  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3073  */
3074 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3075 {
3076   if(!other)
3077     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3078   checkAllocated();
3079   other->checkAllocated();
3080   int nbOfCompo=getNumberOfComponents();
3081   int otherNbOfCompo=other->getNumberOfComponents();
3082   if(nbOfCompo!=otherNbOfCompo)
3083     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3084   int nbOfTuplesOther=other->getNumberOfTuples();
3085   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3086   switch(nbOfCompo)
3087     {
3088     case 3:
3089       {
3090         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3091         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3092         break;
3093       }
3094     case 2:
3095       {
3096         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3097         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3098         break;
3099       }
3100     case 1:
3101       {
3102         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3103         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3104         break;
3105       }
3106     default:
3107       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3108     }
3109   c=cArr.retn(); cI=cIArr.retn();
3110 }
3111
3112 /*!
3113  * 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
3114  * around origin of 'radius' 1.
3115  * 
3116  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3117  */
3118 void DataArrayDouble::recenterForMaxPrecision(double eps)
3119 {
3120   checkAllocated();
3121   int dim=getNumberOfComponents();
3122   std::vector<double> bounds(2*dim);
3123   getMinMaxPerComponent(&bounds[0]);
3124   for(int i=0;i<dim;i++)
3125     {
3126       double delta=bounds[2*i+1]-bounds[2*i];
3127       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3128       if(delta>eps)
3129         applyLin(1./delta,-offset/delta,i);
3130       else
3131         applyLin(1.,-offset,i);
3132     }
3133 }
3134
3135 /*!
3136  * Returns the maximal value and its location within \a this one-dimensional array.
3137  *  \param [out] tupleId - index of the tuple holding the maximal value.
3138  *  \return double - the maximal value among all values of \a this array.
3139  *  \throw If \a this->getNumberOfComponents() != 1
3140  *  \throw If \a this->getNumberOfTuples() < 1
3141  */
3142 double DataArrayDouble::getMaxValue(int& tupleId) const
3143 {
3144   checkAllocated();
3145   if(getNumberOfComponents()!=1)
3146     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 !");
3147   int nbOfTuples=getNumberOfTuples();
3148   if(nbOfTuples<=0)
3149     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3150   const double *vals=getConstPointer();
3151   const double *loc=std::max_element(vals,vals+nbOfTuples);
3152   tupleId=(int)std::distance(vals,loc);
3153   return *loc;
3154 }
3155
3156 /*!
3157  * Returns the maximal value within \a this array that is allowed to have more than
3158  *  one component.
3159  *  \return double - the maximal value among all values of \a this array.
3160  *  \throw If \a this is not allocated.
3161  */
3162 double DataArrayDouble::getMaxValueInArray() const
3163 {
3164   checkAllocated();
3165   const double *loc=std::max_element(begin(),end());
3166   return *loc;
3167 }
3168
3169 /*!
3170  * Returns the maximal value and all its locations within \a this one-dimensional array.
3171  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3172  *               tuples holding the maximal value. The caller is to delete it using
3173  *               decrRef() as it is no more needed.
3174  *  \return double - the maximal value among all values of \a this array.
3175  *  \throw If \a this->getNumberOfComponents() != 1
3176  *  \throw If \a this->getNumberOfTuples() < 1
3177  */
3178 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3179 {
3180   int tmp;
3181   tupleIds=0;
3182   double ret=getMaxValue(tmp);
3183   tupleIds=getIdsInRange(ret,ret);
3184   return ret;
3185 }
3186
3187 /*!
3188  * Returns the minimal value and its location within \a this one-dimensional array.
3189  *  \param [out] tupleId - index of the tuple holding the minimal value.
3190  *  \return double - the minimal value among all values of \a this array.
3191  *  \throw If \a this->getNumberOfComponents() != 1
3192  *  \throw If \a this->getNumberOfTuples() < 1
3193  */
3194 double DataArrayDouble::getMinValue(int& tupleId) const
3195 {
3196   checkAllocated();
3197   if(getNumberOfComponents()!=1)
3198     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3199   int nbOfTuples=getNumberOfTuples();
3200   if(nbOfTuples<=0)
3201     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3202   const double *vals=getConstPointer();
3203   const double *loc=std::min_element(vals,vals+nbOfTuples);
3204   tupleId=(int)std::distance(vals,loc);
3205   return *loc;
3206 }
3207
3208 /*!
3209  * Returns the minimal value within \a this array that is allowed to have more than
3210  *  one component.
3211  *  \return double - the minimal value among all values of \a this array.
3212  *  \throw If \a this is not allocated.
3213  */
3214 double DataArrayDouble::getMinValueInArray() const
3215 {
3216   checkAllocated();
3217   const double *loc=std::min_element(begin(),end());
3218   return *loc;
3219 }
3220
3221 /*!
3222  * Returns the minimal value and all its locations within \a this one-dimensional array.
3223  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3224  *               tuples holding the minimal value. The caller is to delete it using
3225  *               decrRef() as it is no more needed.
3226  *  \return double - the minimal value among all values of \a this array.
3227  *  \throw If \a this->getNumberOfComponents() != 1
3228  *  \throw If \a this->getNumberOfTuples() < 1
3229  */
3230 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3231 {
3232   int tmp;
3233   tupleIds=0;
3234   double ret=getMinValue(tmp);
3235   tupleIds=getIdsInRange(ret,ret);
3236   return ret;
3237 }
3238
3239 /*!
3240  * 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.
3241  * This method only works for single component array.
3242  *
3243  * \return a value in [ 0, \c this->getNumberOfTuples() )
3244  *
3245  * \throw If \a this is not allocated
3246  *
3247  */
3248 int DataArrayDouble::count(double value, double eps) const
3249 {
3250   int ret=0;
3251   checkAllocated();
3252   if(getNumberOfComponents()!=1)
3253     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3254   const double *vals=begin();
3255   int nbOfTuples=getNumberOfTuples();
3256   for(int i=0;i<nbOfTuples;i++,vals++)
3257     if(fabs(*vals-value)<=eps)
3258       ret++;
3259   return ret;
3260 }
3261
3262 /*!
3263  * Returns the average value of \a this one-dimensional array.
3264  *  \return double - the average value over all values of \a this array.
3265  *  \throw If \a this->getNumberOfComponents() != 1
3266  *  \throw If \a this->getNumberOfTuples() < 1
3267  */
3268 double DataArrayDouble::getAverageValue() const
3269 {
3270   if(getNumberOfComponents()!=1)
3271     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3272   int nbOfTuples=getNumberOfTuples();
3273   if(nbOfTuples<=0)
3274     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3275   const double *vals=getConstPointer();
3276   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3277   return ret/nbOfTuples;
3278 }
3279
3280 /*!
3281  * Returns the Euclidean norm of the vector defined by \a this array.
3282  *  \return double - the value of the Euclidean norm, i.e.
3283  *          the square root of the inner product of vector.
3284  *  \throw If \a this is not allocated.
3285  */
3286 double DataArrayDouble::norm2() const
3287 {
3288   checkAllocated();
3289   double ret=0.;
3290   std::size_t nbOfElems=getNbOfElems();
3291   const double *pt=getConstPointer();
3292   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3293     ret+=(*pt)*(*pt);
3294   return sqrt(ret);
3295 }
3296
3297 /*!
3298  * Returns the maximum norm of the vector defined by \a this array.
3299  *  \return double - the value of the maximum norm, i.e.
3300  *          the maximal absolute value among values of \a this array.
3301  *  \throw If \a this is not allocated.
3302  */
3303 double DataArrayDouble::normMax() const
3304 {
3305   checkAllocated();
3306   double ret=-1.;
3307   std::size_t nbOfElems=getNbOfElems();
3308   const double *pt=getConstPointer();
3309   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3310     {
3311       double val=std::abs(*pt);
3312       if(val>ret)
3313         ret=val;
3314     }
3315   return ret;
3316 }
3317
3318 /*!
3319  * Accumulates values of each component of \a this array.
3320  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3321  *         by the caller, that is filled by this method with sum value for each
3322  *         component.
3323  *  \throw If \a this is not allocated.
3324  */
3325 void DataArrayDouble::accumulate(double *res) const
3326 {
3327   checkAllocated();
3328   const double *ptr=getConstPointer();
3329   int nbTuple=getNumberOfTuples();
3330   int nbComps=getNumberOfComponents();
3331   std::fill(res,res+nbComps,0.);
3332   for(int i=0;i<nbTuple;i++)
3333     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3334 }
3335
3336 /*!
3337  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3338  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3339  *
3340  *
3341  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3342  * \a tupleEnd. If not an exception will be thrown.
3343  *
3344  * \param [in] tupleBg start pointer (included) of input external tuple
3345  * \param [in] tupleEnd end pointer (not included) of input external tuple
3346  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3347  * \return the min distance.
3348  * \sa MEDCouplingUMesh::distanceToPoint
3349  */
3350 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3351 {
3352   checkAllocated();
3353   int nbTuple=getNumberOfTuples();
3354   int nbComps=getNumberOfComponents();
3355   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3356     { 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()); }
3357   if(nbTuple==0)
3358     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3359   double ret0=std::numeric_limits<double>::max();
3360   tupleId=-1;
3361   const double *work=getConstPointer();
3362   for(int i=0;i<nbTuple;i++)
3363     {
3364       double val=0.;
3365       for(int j=0;j<nbComps;j++,work++) 
3366         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3367       if(val>=ret0)
3368         continue;
3369       else
3370         { ret0=val; tupleId=i; }
3371     }
3372   return sqrt(ret0);
3373 }
3374
3375 /*!
3376  * Accumulate values of the given component of \a this array.
3377  *  \param [in] compId - the index of the component of interest.
3378  *  \return double - a sum value of \a compId-th component.
3379  *  \throw If \a this is not allocated.
3380  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3381  *         not respected.
3382  */
3383 double DataArrayDouble::accumulate(int compId) const
3384 {
3385   checkAllocated();
3386   const double *ptr=getConstPointer();
3387   int nbTuple=getNumberOfTuples();
3388   int nbComps=getNumberOfComponents();
3389   if(compId<0 || compId>=nbComps)
3390     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3391   double ret=0.;
3392   for(int i=0;i<nbTuple;i++)
3393     ret+=ptr[i*nbComps+compId];
3394   return ret;
3395 }
3396
3397 /*!
3398  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3399  * The returned array will have same number of components than \a this and number of tuples equal to
3400  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3401  *
3402  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3403  * 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.
3404  *
3405  * \param [in] bgOfIndex - begin (included) of the input index array.
3406  * \param [in] endOfIndex - end (excluded) of the input index array.
3407  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3408  * 
3409  * \throw If bgOfIndex or end is NULL.
3410  * \throw If input index array is not ascendingly sorted.
3411  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3412  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3413  */
3414 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3415 {
3416   if(!bgOfIndex || !endOfIndex)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3418   checkAllocated();
3419   int nbCompo=getNumberOfComponents();
3420   int nbOfTuples=getNumberOfTuples();
3421   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3422   if(sz<1)
3423     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3424   sz--;
3425   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3426   const int *w=bgOfIndex;
3427   if(*w<0 || *w>=nbOfTuples)
3428     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3429   const double *srcPt=begin()+(*w)*nbCompo;
3430   double *tmp=ret->getPointer();
3431   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3432     {
3433       std::fill(tmp,tmp+nbCompo,0.);
3434       if(w[1]>=w[0])
3435         {
3436           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3437             {
3438               if(j>=0 && j<nbOfTuples)
3439                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3440               else
3441                 {
3442                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3443                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3444                 }
3445             }
3446         }
3447       else
3448         {
3449           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3450           throw INTERP_KERNEL::Exception(oss.str().c_str());
3451         }
3452     }
3453   ret->copyStringInfoFrom(*this);
3454   return ret.retn();
3455 }
3456
3457 /*!
3458  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3459  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3460  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3461  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3462  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3463  *          is to delete this array using decrRef() as it is no more needed. The array
3464  *          does not contain any textual info on components.
3465  *  \throw If \a this->getNumberOfComponents() != 2.
3466  */
3467 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3468 {
3469   checkAllocated();
3470   int nbOfComp=getNumberOfComponents();
3471   if(nbOfComp!=2)
3472     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3473   int nbOfTuple=getNumberOfTuples();
3474   DataArrayDouble *ret=DataArrayDouble::New();
3475   ret->alloc(nbOfTuple,2);
3476   double *w=ret->getPointer();
3477   const double *wIn=getConstPointer();
3478   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3479     {
3480       w[0]=wIn[0]*cos(wIn[1]);
3481       w[1]=wIn[0]*sin(wIn[1]);
3482     }
3483   return ret;
3484 }
3485
3486 /*!
3487  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3488  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3489  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3490  * the Cylindrical CS.
3491  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3492  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3493  *          on the third component is copied from \a this array. The caller
3494  *          is to delete this array using decrRef() as it is no more needed. 
3495  *  \throw If \a this->getNumberOfComponents() != 3.
3496  */
3497 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3498 {
3499   checkAllocated();
3500   int nbOfComp=getNumberOfComponents();
3501   if(nbOfComp!=3)
3502     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3503   int nbOfTuple=getNumberOfTuples();
3504   DataArrayDouble *ret=DataArrayDouble::New();
3505   ret->alloc(getNumberOfTuples(),3);
3506   double *w=ret->getPointer();
3507   const double *wIn=getConstPointer();
3508   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3509     {
3510       w[0]=wIn[0]*cos(wIn[1]);
3511       w[1]=wIn[0]*sin(wIn[1]);
3512       w[2]=wIn[2];
3513     }
3514   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3515   return ret;
3516 }
3517
3518 /*!
3519  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3520  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3521  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3522  * point in the Cylindrical CS.
3523  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3524  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3525  *          on the third component is copied from \a this array. The caller
3526  *          is to delete this array using decrRef() as it is no more needed.
3527  *  \throw If \a this->getNumberOfComponents() != 3.
3528  */
3529 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3530 {
3531   checkAllocated();
3532   int nbOfComp=getNumberOfComponents();
3533   if(nbOfComp!=3)
3534     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3535   int nbOfTuple=getNumberOfTuples();
3536   DataArrayDouble *ret=DataArrayDouble::New();
3537   ret->alloc(getNumberOfTuples(),3);
3538   double *w=ret->getPointer();
3539   const double *wIn=getConstPointer();
3540   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3541     {
3542       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3543       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3544       w[2]=wIn[0]*cos(wIn[1]);
3545     }
3546   return ret;
3547 }
3548
3549 /*!
3550  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3551  * array contating 6 components.
3552  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3553  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3554  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3555  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3556  *  \throw If \a this->getNumberOfComponents() != 6.
3557  */
3558 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3559 {
3560   checkAllocated();
3561   int nbOfComp=getNumberOfComponents();
3562   if(nbOfComp!=6)
3563     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3564   DataArrayDouble *ret=DataArrayDouble::New();
3565   int nbOfTuple=getNumberOfTuples();
3566   ret->alloc(nbOfTuple,1);
3567   const double *src=getConstPointer();
3568   double *dest=ret->getPointer();
3569   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3570     *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];
3571   return ret;
3572 }
3573
3574 /*!
3575  * Computes the determinant of every square matrix defined by the tuple of \a this
3576  * array, which contains either 4, 6 or 9 components. The case of 6 components
3577  * corresponds to that of the upper triangular matrix.
3578  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3579  *          is the determinant of matrix of the corresponding tuple of \a this array.
3580  *          The caller is to delete this result array using decrRef() as it is no more
3581  *          needed. 
3582  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3583  */
3584 DataArrayDouble *DataArrayDouble::determinant() const
3585 {
3586   checkAllocated();
3587   DataArrayDouble *ret=DataArrayDouble::New();
3588   int nbOfTuple=getNumberOfTuples();
3589   ret->alloc(nbOfTuple,1);
3590   const double *src=getConstPointer();
3591   double *dest=ret->getPointer();
3592   switch(getNumberOfComponents())
3593     {
3594     case 6:
3595       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3596         *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];
3597       return ret;
3598     case 4:
3599       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3600         *dest=src[0]*src[3]-src[1]*src[2];
3601       return ret;
3602     case 9:
3603       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3604         *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];
3605       return ret;
3606     default:
3607       ret->decrRef();
3608       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3609     }
3610 }
3611
3612 /*!
3613  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3614  * \a this array, which contains 6 components.
3615  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3616  *          components, whose each tuple contains the eigenvalues of the matrix of
3617  *          corresponding tuple of \a this array. 
3618  *          The caller is to delete this result array using decrRef() as it is no more
3619  *          needed. 
3620  *  \throw If \a this->getNumberOfComponents() != 6.
3621  */
3622 DataArrayDouble *DataArrayDouble::eigenValues() const
3623 {
3624   checkAllocated();
3625   int nbOfComp=getNumberOfComponents();
3626   if(nbOfComp!=6)
3627     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3628   DataArrayDouble *ret=DataArrayDouble::New();
3629   int nbOfTuple=getNumberOfTuples();
3630   ret->alloc(nbOfTuple,3);
3631   const double *src=getConstPointer();
3632   double *dest=ret->getPointer();
3633   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3634     INTERP_KERNEL::computeEigenValues6(src,dest);
3635   return ret;
3636 }
3637
3638 /*!
3639  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3640  * \a this array, which contains 6 components.
3641  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3642  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3643  *          corresponding tuple of \a this array.
3644  *          The caller is to delete this result array using decrRef() as it is no more
3645  *          needed.
3646  *  \throw If \a this->getNumberOfComponents() != 6.
3647  */
3648 DataArrayDouble *DataArrayDouble::eigenVectors() const
3649 {
3650   checkAllocated();
3651   int nbOfComp=getNumberOfComponents();
3652   if(nbOfComp!=6)
3653     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3654   DataArrayDouble *ret=DataArrayDouble::New();
3655   int nbOfTuple=getNumberOfTuples();
3656   ret->alloc(nbOfTuple,9);
3657   const double *src=getConstPointer();
3658   double *dest=ret->getPointer();
3659   for(int i=0;i<nbOfTuple;i++,src+=6)
3660     {
3661       double tmp[3];
3662       INTERP_KERNEL::computeEigenValues6(src,tmp);
3663       for(int j=0;j<3;j++,dest+=3)
3664         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3665     }
3666   return ret;
3667 }
3668
3669 /*!
3670  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3671  * array, which contains either 4, 6 or 9 components. The case of 6 components
3672  * corresponds to that of the upper triangular matrix.
3673  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3674  *          same number of components as \a this one, whose each tuple is the inverse
3675  *          matrix of the matrix of corresponding tuple of \a this array. 
3676  *          The caller is to delete this result array using decrRef() as it is no more
3677  *          needed. 
3678  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3679  */
3680 DataArrayDouble *DataArrayDouble::inverse() const
3681 {
3682   checkAllocated();
3683   int nbOfComp=getNumberOfComponents();
3684   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3685     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3686   DataArrayDouble *ret=DataArrayDouble::New();
3687   int nbOfTuple=getNumberOfTuples();
3688   ret->alloc(nbOfTuple,nbOfComp);
3689   const double *src=getConstPointer();
3690   double *dest=ret->getPointer();
3691 if(nbOfComp==6)
3692     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3693       {
3694         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];
3695         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3696         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3697         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3698         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3699         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3700         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3701       }
3702   else if(nbOfComp==4)
3703     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3704       {
3705         double det=src[0]*src[3]-src[1]*src[2];
3706         dest[0]=src[3]/det;
3707         dest[1]=-src[1]/det;
3708         dest[2]=-src[2]/det;
3709         dest[3]=src[0]/det;
3710       }
3711   else
3712     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3713       {
3714         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];
3715         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3716         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3717         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3718         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3719         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3720         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3721         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3722         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3723         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3724       }
3725   return ret;
3726 }
3727
3728 /*!
3729  * Computes the trace of every matrix defined by the tuple of \a this
3730  * array, which contains either 4, 6 or 9 components. The case of 6 components
3731  * corresponds to that of the upper triangular matrix.
3732  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3733  *          1 component, whose each tuple is the trace of
3734  *          the matrix of corresponding tuple of \a this array. 
3735  *          The caller is to delete this result array using decrRef() as it is no more
3736  *          needed. 
3737  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3738  */
3739 DataArrayDouble *DataArrayDouble::trace() const
3740 {
3741   checkAllocated();
3742   int nbOfComp=getNumberOfComponents();
3743   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3744     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3745   DataArrayDouble *ret=DataArrayDouble::New();
3746   int nbOfTuple=getNumberOfTuples();
3747   ret->alloc(nbOfTuple,1);
3748   const double *src=getConstPointer();
3749   double *dest=ret->getPointer();
3750   if(nbOfComp==6)
3751     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3752       *dest=src[0]+src[1]+src[2];
3753   else if(nbOfComp==4)
3754     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3755       *dest=src[0]+src[3];
3756   else
3757     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3758       *dest=src[0]+src[4]+src[8];
3759   return ret;
3760 }
3761
3762 /*!
3763  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3764  * \a this array, which contains 6 components.
3765  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3766  *          same number of components and tuples as \a this array.
3767  *          The caller is to delete this result array using decrRef() as it is no more
3768  *          needed.
3769  *  \throw If \a this->getNumberOfComponents() != 6.
3770  */
3771 DataArrayDouble *DataArrayDouble::deviator() const
3772 {
3773   checkAllocated();
3774   int nbOfComp=getNumberOfComponents();
3775   if(nbOfComp!=6)
3776     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3777   DataArrayDouble *ret=DataArrayDouble::New();
3778   int nbOfTuple=getNumberOfTuples();
3779   ret->alloc(nbOfTuple,6);
3780   const double *src=getConstPointer();
3781   double *dest=ret->getPointer();
3782   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3783     {
3784       double tr=(src[0]+src[1]+src[2])/3.;
3785       dest[0]=src[0]-tr;
3786       dest[1]=src[1]-tr;
3787       dest[2]=src[2]-tr;
3788       dest[3]=src[3];
3789       dest[4]=src[4];
3790       dest[5]=src[5];
3791     }
3792   return ret;
3793 }
3794
3795 /*!
3796  * Computes the magnitude of every vector defined by the tuple of
3797  * \a this array.
3798  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3799  *          same number of tuples as \a this array and one component.
3800  *          The caller is to delete this result array using decrRef() as it is no more
3801  *          needed.
3802  *  \throw If \a this is not allocated.
3803  */
3804 DataArrayDouble *DataArrayDouble::magnitude() const
3805 {
3806   checkAllocated();
3807   int nbOfComp=getNumberOfComponents();
3808   DataArrayDouble *ret=DataArrayDouble::New();
3809   int nbOfTuple=getNumberOfTuples();
3810   ret->alloc(nbOfTuple,1);
3811   const double *src=getConstPointer();
3812   double *dest=ret->getPointer();
3813   for(int i=0;i<nbOfTuple;i++,dest++)
3814     {
3815       double sum=0.;
3816       for(int j=0;j<nbOfComp;j++,src++)
3817         sum+=(*src)*(*src);
3818       *dest=sqrt(sum);
3819     }
3820   return ret;
3821 }
3822
3823 /*!
3824  * Computes for each tuple the sum of number of components values in the tuple and return it.
3825  * 
3826  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3827  *          same number of tuples as \a this array and one component.
3828  *          The caller is to delete this result array using decrRef() as it is no more
3829  *          needed.
3830  *  \throw If \a this is not allocated.
3831  */
3832 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3833 {
3834   checkAllocated();
3835   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3836   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3837   ret->alloc(nbOfTuple,1);
3838   const double *src(getConstPointer());
3839   double *dest(ret->getPointer());
3840   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3841     *dest=std::accumulate(src,src+nbOfComp,0.);
3842   return ret.retn();
3843 }
3844
3845 /*!
3846  * Computes the maximal value within every tuple of \a this array.
3847  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3848  *          same number of tuples as \a this array and one component.
3849  *          The caller is to delete this result array using decrRef() as it is no more
3850  *          needed.
3851  *  \throw If \a this is not allocated.
3852  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3853  */
3854 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3855 {
3856   checkAllocated();
3857   int nbOfComp=getNumberOfComponents();
3858   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3859   int nbOfTuple=getNumberOfTuples();
3860   ret->alloc(nbOfTuple,1);
3861   const double *src=getConstPointer();
3862   double *dest=ret->getPointer();
3863   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3864     *dest=*std::max_element(src,src+nbOfComp);
3865   return ret.retn();
3866 }
3867
3868 /*!
3869  * Computes the maximal value within every tuple of \a this array and it returns the first component
3870  * id for each tuple that corresponds to the maximal value within the tuple.
3871  * 
3872  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3873  *          same number of tuples and only one component.
3874  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3875  *          same number of tuples as \a this array and one component.
3876  *          The caller is to delete this result array using decrRef() as it is no more
3877  *          needed.
3878  *  \throw If \a this is not allocated.
3879  *  \sa DataArrayDouble::maxPerTuple
3880  */
3881 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3882 {
3883   checkAllocated();
3884   int nbOfComp=getNumberOfComponents();
3885   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3886   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3887   int nbOfTuple=getNumberOfTuples();
3888   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3889   const double *src=getConstPointer();
3890   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3891   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3892     {
3893       const double *loc=std::max_element(src,src+nbOfComp);
3894       *dest=*loc;
3895       *dest1=(int)std::distance(src,loc);
3896     }
3897   compoIdOfMaxPerTuple=ret1.retn();
3898   return ret0.retn();
3899 }
3900
3901 /*!
3902  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3903  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3904  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3905  * \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)
3906  *
3907  * \warning use this method with care because it can leads to big amount of consumed memory !
3908  * 
3909  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3910  *
3911  * \throw If \a this is not allocated.
3912  *
3913  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3914  */
3915 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3916 {
3917   checkAllocated();
3918   int nbOfComp=getNumberOfComponents();
3919   int nbOfTuples=getNumberOfTuples();
3920   const double *inData=getConstPointer();
3921   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3922   ret->alloc(nbOfTuples*nbOfTuples,1);
3923   double *outData=ret->getPointer();
3924   for(int i=0;i<nbOfTuples;i++)
3925     {
3926       outData[i*nbOfTuples+i]=0.;
3927       for(int j=i+1;j<nbOfTuples;j++)
3928         {
3929           double dist=0.;
3930           for(int k=0;k<nbOfComp;k++)
3931             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3932           dist=sqrt(dist);
3933           outData[i*nbOfTuples+j]=dist;
3934           outData[j*nbOfTuples+i]=dist;
3935         }
3936     }
3937   return ret.retn();
3938 }
3939
3940 /*!
3941  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3942  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3943  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3944  * \n Output rectangular matrix is sorted along rows.
3945  * \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)
3946  *
3947  * \warning use this method with care because it can leads to big amount of consumed memory !
3948  * 
3949  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3950  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3951  *
3952  * \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.
3953  *
3954  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3955  */
3956 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
3957 {
3958   if(!other)
3959     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3960   checkAllocated();
3961   other->checkAllocated();
3962   int nbOfComp=getNumberOfComponents();
3963   int otherNbOfComp=other->getNumberOfComponents();
3964   if(nbOfComp!=otherNbOfComp)
3965     {
3966       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3967       throw INTERP_KERNEL::Exception(oss.str().c_str());
3968     }
3969   int nbOfTuples=getNumberOfTuples();
3970   int otherNbOfTuples=other->getNumberOfTuples();
3971   const double *inData=getConstPointer();
3972   const double *inDataOther=other->getConstPointer();
3973   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3974   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3975   double *outData=ret->getPointer();
3976   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3977     {
3978       for(int j=0;j<nbOfTuples;j++)
3979         {
3980           double dist=0.;
3981           for(int k=0;k<nbOfComp;k++)
3982             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3983           dist=sqrt(dist);
3984           outData[i*nbOfTuples+j]=dist;
3985         }
3986     }
3987   return ret.retn();
3988 }
3989
3990 /*!
3991  * Sorts value within every tuple of \a this array.
3992  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3993  *              in descending order.
3994  *  \throw If \a this is not allocated.
3995  */
3996 void DataArrayDouble::sortPerTuple(bool asc)
3997 {
3998   checkAllocated();
3999   double *pt=getPointer();
4000   int nbOfTuple=getNumberOfTuples();
4001   int nbOfComp=getNumberOfComponents();
4002   if(asc)
4003     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4004       std::sort(pt,pt+nbOfComp);
4005   else
4006     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4007       std::sort(pt,pt+nbOfComp,std::greater<double>());
4008   declareAsNew();
4009 }
4010
4011 /*!
4012  * Converts every value of \a this array to its absolute value.
4013  *  \throw If \a this is not allocated.
4014  */
4015 void DataArrayDouble::abs()
4016 {
4017   checkAllocated();
4018   double *ptr=getPointer();
4019   std::size_t nbOfElems=getNbOfElems();
4020   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4021   declareAsNew();
4022 }
4023
4024 /*!
4025  * Apply a liner function to a given component of \a this array, so that
4026  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4027  *  \param [in] a - the first coefficient of the function.
4028  *  \param [in] b - the second coefficient of the function.
4029  *  \param [in] compoId - the index of component to modify.
4030  *  \throw If \a this is not allocated.
4031  */
4032 void DataArrayDouble::applyLin(double a, double b, int compoId)
4033 {
4034   checkAllocated();
4035   double *ptr=getPointer()+compoId;
4036   int nbOfComp=getNumberOfComponents();
4037   int nbOfTuple=getNumberOfTuples();
4038   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4039     *ptr=a*(*ptr)+b;
4040   declareAsNew();
4041 }
4042
4043 /*!
4044  * Apply a liner function to all elements of \a this array, so that
4045  * an element _x_ becomes \f$ a * x + b \f$.
4046  *  \param [in] a - the first coefficient of the function.
4047  *  \param [in] b - the second coefficient of the function.
4048  *  \throw If \a this is not allocated.
4049  */
4050 void DataArrayDouble::applyLin(double a, double b)
4051 {
4052   checkAllocated();
4053   double *ptr=getPointer();
4054   std::size_t nbOfElems=getNbOfElems();
4055   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4056     *ptr=a*(*ptr)+b;
4057   declareAsNew();
4058 }
4059
4060 /*!
4061  * Modify all elements of \a this array, so that
4062  * an element _x_ becomes \f$ numerator / x \f$.
4063  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4064  *           array, all elements processed before detection of the zero element remain
4065  *           modified.
4066  *  \param [in] numerator - the numerator used to modify array elements.
4067  *  \throw If \a this is not allocated.
4068  *  \throw If there is an element equal to 0.0 in \a this array.
4069  */
4070 void DataArrayDouble::applyInv(double numerator)
4071 {
4072   checkAllocated();
4073   double *ptr=getPointer();
4074   std::size_t nbOfElems=getNbOfElems();
4075   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4076     {
4077       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4078         {
4079           *ptr=numerator/(*ptr);
4080         }
4081       else
4082         {
4083           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4084           oss << " !";
4085           throw INTERP_KERNEL::Exception(oss.str().c_str());
4086         }
4087     }
4088   declareAsNew();
4089 }
4090
4091 /*!
4092  * Returns a full copy of \a this array except that sign of all elements is reversed.
4093  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4094  *          same number of tuples and component as \a this array.
4095  *          The caller is to delete this result array using decrRef() as it is no more
4096  *          needed.
4097  *  \throw If \a this is not allocated.
4098  */
4099 DataArrayDouble *DataArrayDouble::negate() const
4100 {
4101   checkAllocated();
4102   DataArrayDouble *newArr=DataArrayDouble::New();
4103   int nbOfTuples=getNumberOfTuples();
4104   int nbOfComp=getNumberOfComponents();
4105   newArr->alloc(nbOfTuples,nbOfComp);
4106   const double *cptr=getConstPointer();
4107   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4108   newArr->copyStringInfoFrom(*this);
4109   return newArr;
4110 }
4111
4112 /*!
4113  * Modify all elements of \a this array, so that
4114  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4115  * all values in \a this have to be >= 0 if val is \b not integer.
4116  *  \param [in] val - the value used to apply pow on all array elements.
4117  *  \throw If \a this is not allocated.
4118  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4119  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4120  *           modified.
4121  */
4122 void DataArrayDouble::applyPow(double val)
4123 {
4124   checkAllocated();
4125   double *ptr=getPointer();
4126   std::size_t nbOfElems=getNbOfElems();
4127   int val2=(int)val;
4128   bool isInt=((double)val2)==val;
4129   if(!isInt)
4130     {
4131       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4132         {
4133           if(*ptr>=0)
4134             *ptr=pow(*ptr,val);
4135           else
4136             {
4137               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4138               throw INTERP_KERNEL::Exception(oss.str().c_str());
4139             }
4140         }
4141     }
4142   else
4143     {
4144       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4145         *ptr=pow(*ptr,val2);
4146     }
4147   declareAsNew();
4148 }
4149
4150 /*!
4151  * Modify all elements of \a this array, so that
4152  * an element _x_ becomes \f$ val ^ x \f$.
4153  *  \param [in] val - the value used to apply pow on all array elements.
4154  *  \throw If \a this is not allocated.
4155  *  \throw If \a val < 0.
4156  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4157  *           array, all elements processed before detection of the zero element remain
4158  *           modified.
4159  */
4160 void DataArrayDouble::applyRPow(double val)
4161 {
4162   checkAllocated();
4163   if(val<0.)
4164     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4165   double *ptr=getPointer();
4166   std::size_t nbOfElems=getNbOfElems();
4167   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4168     *ptr=pow(val,*ptr);
4169   declareAsNew();
4170 }
4171
4172 /*!
4173  * Returns a new DataArrayDouble created from \a this one by applying \a
4174  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4175  * For more info see \ref MEDCouplingArrayApplyFunc
4176  *  \param [in] nbOfComp - number of components in the result array.
4177  *  \param [in] func - the \a FunctionToEvaluate declared as 
4178  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4179  *              where \a pos points to the first component of a tuple of \a this array
4180  *              and \a res points to the first component of a tuple of the result array.
4181  *              Note that length (number of components) of \a pos can differ from
4182  *              that of \a res.
4183  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4184  *          same number of tuples as \a this array.
4185  *          The caller is to delete this result array using decrRef() as it is no more
4186  *          needed.
4187  *  \throw If \a this is not allocated.
4188  *  \throw If \a func returns \a false.
4189  */
4190 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4191 {
4192   checkAllocated();
4193   DataArrayDouble *newArr=DataArrayDouble::New();
4194   int nbOfTuples=getNumberOfTuples();
4195   int oldNbOfComp=getNumberOfComponents();
4196   newArr->alloc(nbOfTuples,nbOfComp);
4197   const double *ptr=getConstPointer();
4198   double *ptrToFill=newArr->getPointer();
4199   for(int i=0;i<nbOfTuples;i++)
4200     {
4201       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4202         {
4203           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4204           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4205           oss << ") : Evaluation of function failed !";
4206           newArr->decrRef();
4207           throw INTERP_KERNEL::Exception(oss.str().c_str());
4208         }
4209     }
4210   return newArr;
4211 }
4212
4213 /*!
4214  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4215  * tuple of \a this array. Textual data is not copied.
4216  * For more info see \ref MEDCouplingArrayApplyFunc1.
4217  *  \param [in] nbOfComp - number of components in the result array.
4218  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4219  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4220  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4221  *          same number of tuples as \a this array and \a nbOfComp components.
4222  *          The caller is to delete this result array using decrRef() as it is no more
4223  *          needed.
4224  *  \throw If \a this is not allocated.
4225  *  \throw If computing \a func fails.
4226  */
4227 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const
4228 {
4229   checkAllocated();
4230   INTERP_KERNEL::ExprParser expr(func);
4231   expr.parse();
4232   std::set<std::string> vars;
4233   expr.getTrueSetOfVars(vars);
4234   int oldNbOfComp=getNumberOfComponents();
4235   if((int)vars.size()>oldNbOfComp)
4236     {
4237       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4238       oss << vars.size() << " variables : ";
4239       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4240       throw INTERP_KERNEL::Exception(oss.str().c_str());
4241     }
4242   std::vector<std::string> varsV(vars.begin(),vars.end());
4243   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4244   //
4245   DataArrayDouble *newArr=DataArrayDouble::New();
4246   int nbOfTuples=getNumberOfTuples();
4247   newArr->alloc(nbOfTuples,nbOfComp);
4248   const double *ptr=getConstPointer();
4249   double *ptrToFill=newArr->getPointer();
4250   for(int i=0;i<nbOfTuples;i++)
4251     {
4252       try
4253         {
4254           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4255         }
4256       catch(INTERP_KERNEL::Exception& e)
4257         {
4258           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4259           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4260           oss << ") : Evaluation of function failed !" << e.what();
4261           newArr->decrRef();
4262           throw INTERP_KERNEL::Exception(oss.str().c_str());
4263         }
4264     }
4265   return newArr;
4266 }
4267
4268 /*!
4269  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4270  * tuple of \a this array. Textual data is not copied.
4271  * For more info see \ref MEDCouplingArrayApplyFunc0.
4272  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4273  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4274  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4275  *          same number of tuples and components as \a this array.
4276  *          The caller is to delete this result array using decrRef() as it is no more
4277  *          needed.
4278  *  \throw If \a this is not allocated.
4279  *  \throw If computing \a func fails.
4280  */
4281 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const
4282 {
4283   checkAllocated();
4284   INTERP_KERNEL::ExprParser expr(func);
4285   expr.parse();
4286   expr.prepareExprEvaluationVec();
4287   //
4288   DataArrayDouble *newArr=DataArrayDouble::New();
4289   int nbOfTuples=getNumberOfTuples();
4290   int nbOfComp=getNumberOfComponents();
4291   newArr->alloc(nbOfTuples,nbOfComp);
4292   const double *ptr=getConstPointer();
4293   double *ptrToFill=newArr->getPointer();
4294   for(int i=0;i<nbOfTuples;i++)
4295     {
4296       try
4297         {
4298           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4299         }
4300       catch(INTERP_KERNEL::Exception& e)
4301         {
4302           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4303           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4304           oss << ") : Evaluation of function failed ! " << e.what();
4305           newArr->decrRef();
4306           throw INTERP_KERNEL::Exception(oss.str().c_str());
4307         }
4308     }
4309   return newArr;
4310 }
4311
4312 /*!
4313  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4314  * tuple of \a this array. Textual data is not copied.
4315  * For more info see \ref MEDCouplingArrayApplyFunc2.
4316  *  \param [in] nbOfComp - number of components in the result array.
4317  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4318  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4319  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4320  *          same number of tuples as \a this array.
4321  *          The caller is to delete this result array using decrRef() as it is no more
4322  *          needed.
4323  *  \throw If \a this is not allocated.
4324  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4325  *  \throw If computing \a func fails.
4326  */
4327 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const
4328 {
4329   checkAllocated();
4330   INTERP_KERNEL::ExprParser expr(func);
4331   expr.parse();
4332   std::set<std::string> vars;
4333   expr.getTrueSetOfVars(vars);
4334   int oldNbOfComp=getNumberOfComponents();
4335   if((int)vars.size()>oldNbOfComp)
4336     {
4337       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4338       oss << vars.size() << " variables : ";
4339       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4340       throw INTERP_KERNEL::Exception(oss.str().c_str());
4341     }
4342   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4343   //
4344   DataArrayDouble *newArr=DataArrayDouble::New();
4345   int nbOfTuples=getNumberOfTuples();
4346   newArr->alloc(nbOfTuples,nbOfComp);
4347   const double *ptr=getConstPointer();
4348   double *ptrToFill=newArr->getPointer();
4349   for(int i=0;i<nbOfTuples;i++)
4350     {
4351       try
4352         {
4353           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4354         }
4355       catch(INTERP_KERNEL::Exception& e)
4356         {
4357           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4358           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4359           oss << ") : Evaluation of function failed !" << e.what();
4360           newArr->decrRef();
4361           throw INTERP_KERNEL::Exception(oss.str().c_str());
4362         }
4363     }
4364   return newArr;
4365 }
4366
4367 /*!
4368  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4369  * tuple of \a this array. Textual data is not copied.
4370  * For more info see \ref MEDCouplingArrayApplyFunc3.
4371  *  \param [in] nbOfComp - number of components in the result array.
4372  *  \param [in] varsOrder - sequence of vars defining their order.
4373  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4374  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4375  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4376  *          same number of tuples as \a this array.
4377  *          The caller is to delete this result array using decrRef() as it is no more
4378  *          needed.
4379  *  \throw If \a this is not allocated.
4380  *  \throw If \a func contains vars not in \a varsOrder.
4381  *  \throw If computing \a func fails.
4382  */
4383 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
4384 {
4385   checkAllocated();
4386   INTERP_KERNEL::ExprParser expr(func);
4387   expr.parse();
4388   std::set<std::string> vars;
4389   expr.getTrueSetOfVars(vars);
4390   int oldNbOfComp=getNumberOfComponents();
4391   if((int)vars.size()>oldNbOfComp)
4392     {
4393       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4394       oss << vars.size() << " variables : ";
4395       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4396       throw INTERP_KERNEL::Exception(oss.str().c_str());
4397     }
4398   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4399   //
4400   DataArrayDouble *newArr=DataArrayDouble::New();
4401   int nbOfTuples=getNumberOfTuples();
4402   newArr->alloc(nbOfTuples,nbOfComp);
4403   const double *ptr=getConstPointer();
4404   double *ptrToFill=newArr->getPointer();
4405   for(int i=0;i<nbOfTuples;i++)
4406     {
4407       try
4408         {
4409           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4410         }
4411       catch(INTERP_KERNEL::Exception& e)
4412         {
4413           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4414           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4415           oss << ") : Evaluation of function failed !" << e.what();
4416           newArr->decrRef();
4417           throw INTERP_KERNEL::Exception(oss.str().c_str());
4418         }
4419     }
4420   return newArr;
4421 }
4422
4423 void DataArrayDouble::applyFuncFast32(const char *func)
4424 {
4425   checkAllocated();
4426   INTERP_KERNEL::ExprParser expr(func);
4427   expr.parse();
4428   char *funcStr=expr.compileX86();
4429   MYFUNCPTR funcPtr;
4430   *((void **)&funcPtr)=funcStr;//he he...
4431   //
4432   double *ptr=getPointer();
4433   int nbOfComp=getNumberOfComponents();
4434   int nbOfTuples=getNumberOfTuples();
4435   int nbOfElems=nbOfTuples*nbOfComp;
4436   for(int i=0;i<nbOfElems;i++,ptr++)
4437     *ptr=funcPtr(*ptr);
4438   declareAsNew();
4439 }
4440
4441 void DataArrayDouble::applyFuncFast64(const char *func)
4442 {
4443   checkAllocated();
4444   INTERP_KERNEL::ExprParser expr(func);
4445   expr.parse();
4446   char *funcStr=expr.compileX86_64();
4447   MYFUNCPTR funcPtr;
4448   *((void **)&funcPtr)=funcStr;//he he...
4449   //
4450   double *ptr=getPointer();
4451   int nbOfComp=getNumberOfComponents();
4452   int nbOfTuples=getNumberOfTuples();
4453   int nbOfElems=nbOfTuples*nbOfComp;
4454   for(int i=0;i<nbOfElems;i++,ptr++)
4455     *ptr=funcPtr(*ptr);
4456   declareAsNew();
4457 }
4458
4459 DataArrayDoubleIterator *DataArrayDouble::iterator()
4460 {
4461   return new DataArrayDoubleIterator(this);
4462 }
4463
4464 /*!
4465  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4466  * array whose values are within a given range. Textual data is not copied.
4467  *  \param [in] vmin - a lowest acceptable value (included).
4468  *  \param [in] vmax - a greatest acceptable value (included).
4469  *  \return DataArrayInt * - the new instance of DataArrayInt.
4470  *          The caller is to delete this result array using decrRef() as it is no more
4471  *          needed.
4472  *  \throw If \a this->getNumberOfComponents() != 1.
4473  *
4474  *  \sa DataArrayDouble::getIdsNotInRange
4475  *
4476  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4477  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4478  */
4479 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4480 {
4481   checkAllocated();
4482   if(getNumberOfComponents()!=1)
4483     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4484   const double *cptr(begin());
4485   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4486   int nbOfTuples(getNumberOfTuples());
4487   for(int i=0;i<nbOfTuples;i++,cptr++)
4488     if(*cptr>=vmin && *cptr<=vmax)
4489       ret->pushBackSilent(i);
4490   return ret.retn();
4491 }
4492
4493 /*!
4494  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4495  * array whose values are not within a given range. Textual data is not copied.
4496  *  \param [in] vmin - a lowest not acceptable value (excluded).
4497  *  \param [in] vmax - a greatest not acceptable value (excluded).
4498  *  \return DataArrayInt * - the new instance of DataArrayInt.
4499  *          The caller is to delete this result array using decrRef() as it is no more
4500  *          needed.
4501  *  \throw If \a this->getNumberOfComponents() != 1.
4502  *
4503  *  \sa DataArrayDouble::getIdsInRange
4504  */
4505 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4506 {
4507   checkAllocated();
4508   if(getNumberOfComponents()!=1)
4509     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4510   const double *cptr(begin());
4511   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4512   int nbOfTuples(getNumberOfTuples());
4513   for(int i=0;i<nbOfTuples;i++,cptr++)
4514     if(*cptr<vmin || *cptr>vmax)
4515       ret->pushBackSilent(i);
4516   return ret.retn();
4517 }
4518
4519 /*!
4520  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4521  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4522  * the number of component in the result array is same as that of each of given arrays.
4523  * Info on components is copied from the first of the given arrays. Number of components
4524  * in the given arrays must be  the same.
4525  *  \param [in] a1 - an array to include in the result array.
4526  *  \param [in] a2 - another array to include in the result array.
4527  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4528  *          The caller is to delete this result array using decrRef() as it is no more
4529  *          needed.
4530  *  \throw If both \a a1 and \a a2 are NULL.
4531  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4532  */
4533 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4534 {
4535   std::vector<const DataArrayDouble *> tmp(2);
4536   tmp[0]=a1; tmp[1]=a2;
4537   return Aggregate(tmp);
4538 }
4539
4540 /*!
4541  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4542  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4543  * the number of component in the result array is same as that of each of given arrays.
4544  * Info on components is copied from the first of the given arrays. Number of components
4545  * in the given arrays must be  the same.
4546  *  \param [in] arr - a sequence of arrays to include in the result array.
4547  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4548  *          The caller is to delete this result array using decrRef() as it is no more
4549  *          needed.
4550  *  \throw If all arrays within \a arr are NULL.
4551  *  \throw If getNumberOfComponents() of arrays within \a arr.
4552  */
4553 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4554 {
4555   std::vector<const DataArrayDouble *> a;
4556   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4557     if(*it4)
4558       a.push_back(*it4);
4559   if(a.empty())
4560     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4561   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4562   int nbOfComp=(*it)->getNumberOfComponents();
4563   int nbt=(*it++)->getNumberOfTuples();
4564   for(int i=1;it!=a.end();it++,i++)
4565     {
4566       if((*it)->getNumberOfComponents()!=nbOfComp)
4567         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4568       nbt+=(*it)->getNumberOfTuples();
4569     }
4570   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4571   ret->alloc(nbt,nbOfComp);
4572   double *pt=ret->getPointer();
4573   for(it=a.begin();it!=a.end();it++)
4574     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4575   ret->copyStringInfoFrom(*(a[0]));
4576   return ret.retn();
4577 }
4578
4579 /*!
4580  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4581  * of components in the result array is a sum of the number of components of given arrays
4582  * and (2) the number of tuples in the result array is same as that of each of given
4583  * arrays. In other words the i-th tuple of result array includes all components of
4584  * i-th tuples of all given arrays.
4585  * Number of tuples in the given arrays must be  the same.
4586  *  \param [in] a1 - an array to include in the result array.
4587  *  \param [in] a2 - another array to include in the result array.
4588  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4589  *          The caller is to delete this result array using decrRef() as it is no more
4590  *          needed.
4591  *  \throw If both \a a1 and \a a2 are NULL.
4592  *  \throw If any given array is not allocated.
4593  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4594  */
4595 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4596 {
4597   std::vector<const DataArrayDouble *> arr(2);
4598   arr[0]=a1; arr[1]=a2;
4599   return Meld(arr);
4600 }
4601
4602 /*!
4603  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4604  * of components in the result array is a sum of the number of components of given arrays
4605  * and (2) the number of tuples in the result array is same as that of each of given
4606  * arrays. In other words the i-th tuple of result array includes all components of
4607  * i-th tuples of all given arrays.
4608  * Number of tuples in the given arrays must be  the same.
4609  *  \param [in] arr - a sequence of arrays to include in the result array.
4610  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4611  *          The caller is to delete this result array using decrRef() as it is no more
4612  *          needed.
4613  *  \throw If all arrays within \a arr are NULL.
4614  *  \throw If any given array is not allocated.
4615  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4616  */
4617 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4618 {
4619   std::vector<const DataArrayDouble *> a;
4620   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4621     if(*it4)
4622       a.push_back(*it4);
4623   if(a.empty())
4624     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4625   std::vector<const DataArrayDouble *>::const_iterator it;
4626   for(it=a.begin();it!=a.end();it++)
4627     (*it)->checkAllocated();
4628   it=a.begin();
4629   int nbOfTuples=(*it)->getNumberOfTuples();
4630   std::vector<int> nbc(a.size());
4631   std::vector<const double *> pts(a.size());
4632   nbc[0]=(*it)->getNumberOfComponents();
4633   pts[0]=(*it++)->getConstPointer();
4634   for(int i=1;it!=a.end();it++,i++)
4635     {
4636       if(nbOfTuples!=(*it)->getNumberOfTuples())
4637         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4638       nbc[i]=(*it)->getNumberOfComponents();
4639       pts[i]=(*it)->getConstPointer();
4640     }
4641   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4642   DataArrayDouble *ret=DataArrayDouble::New();
4643   ret->alloc(nbOfTuples,totalNbOfComp);
4644   double *retPtr=ret->getPointer();
4645   for(int i=0;i<nbOfTuples;i++)
4646     for(int j=0;j<(int)a.size();j++)
4647       {
4648         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4649         pts[j]+=nbc[j];
4650       }
4651   int k=0;
4652   for(int i=0;i<(int)a.size();i++)
4653     for(int j=0;j<nbc[i];j++,k++)
4654       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4655   return ret;
4656 }
4657
4658 /*!
4659  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4660  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4661  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4662  * Info on components and name is copied from the first of the given arrays.
4663  * Number of tuples and components in the given arrays must be the same.
4664  *  \param [in] a1 - a given array.
4665  *  \param [in] a2 - another given array.
4666  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4667  *          The caller is to delete this result array using decrRef() as it is no more
4668  *          needed.
4669  *  \throw If either \a a1 or \a a2 is NULL.
4670  *  \throw If any given array is not allocated.
4671  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4672  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4673  */
4674 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4675 {
4676   if(!a1 || !a2)
4677     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4678   a1->checkAllocated();
4679   a2->checkAllocated();
4680   int nbOfComp=a1->getNumberOfComponents();
4681   if(nbOfComp!=a2->getNumberOfComponents())
4682     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4683   int nbOfTuple=a1->getNumberOfTuples();
4684   if(nbOfTuple!=a2->getNumberOfTuples())
4685     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4686   DataArrayDouble *ret=DataArrayDouble::New();
4687   ret->alloc(nbOfTuple,1);
4688   double *retPtr=ret->getPointer();
4689   const double *a1Ptr=a1->getConstPointer();
4690   const double *a2Ptr=a2->getConstPointer();
4691   for(int i=0;i<nbOfTuple;i++)
4692     {
4693       double sum=0.;
4694       for(int j=0;j<nbOfComp;j++)
4695         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4696       retPtr[i]=sum;
4697     }
4698   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4699   ret->setName(a1->getName().c_str());
4700   return ret;
4701 }
4702
4703 /*!
4704  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4705  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4706  * product of two vectors defined by the i-th tuples of given arrays.
4707  * Info on components is copied from the first of the given arrays.
4708  * Number of tuples in the given arrays must be the same.
4709  * Number of components in the given arrays must be 3.
4710  *  \param [in] a1 - a given array.
4711  *  \param [in] a2 - another given array.
4712  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4713  *          The caller is to delete this result array using decrRef() as it is no more
4714  *          needed.
4715  *  \throw If either \a a1 or \a a2 is NULL.
4716  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4717  *  \throw If \a a1->getNumberOfComponents() != 3
4718  *  \throw If \a a2->getNumberOfComponents() != 3
4719  */
4720 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4721 {
4722   if(!a1 || !a2)
4723     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4724   int nbOfComp=a1->getNumberOfComponents();
4725   if(nbOfComp!=a2->getNumberOfComponents())
4726     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4727   if(nbOfComp!=3)
4728     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4729   int nbOfTuple=a1->getNumberOfTuples();
4730   if(nbOfTuple!=a2->getNumberOfTuples())
4731     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4732   DataArrayDouble *ret=DataArrayDouble::New();
4733   ret->alloc(nbOfTuple,3);
4734   double *retPtr=ret->getPointer();
4735   const double *a1Ptr=a1->getConstPointer();
4736   const double *a2Ptr=a2->getConstPointer();
4737   for(int i=0;i<nbOfTuple;i++)
4738     {
4739       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4740       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4741       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4742     }
4743   ret->copyStringInfoFrom(*a1);
4744   return ret;
4745 }
4746
4747 /*!
4748  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4749  * Info on components is copied from the first of the given arrays.
4750  * Number of tuples and components in the given arrays must be the same.
4751  *  \param [in] a1 - an array to compare values with another one.
4752  *  \param [in] a2 - another array to compare values with the first one.
4753  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4754  *          The caller is to delete this result array using decrRef() as it is no more
4755  *          needed.
4756  *  \throw If either \a a1 or \a a2 is NULL.
4757  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4758  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4759  */
4760 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4761 {
4762   if(!a1 || !a2)
4763     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4764   int nbOfComp=a1->getNumberOfComponents();
4765   if(nbOfComp!=a2->getNumberOfComponents())
4766     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4767   int nbOfTuple=a1->getNumberOfTuples();
4768   if(nbOfTuple!=a2->getNumberOfTuples())
4769     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4770   DataArrayDouble *ret=DataArrayDouble::New();
4771   ret->alloc(nbOfTuple,nbOfComp);
4772   double *retPtr=ret->getPointer();
4773   const double *a1Ptr=a1->getConstPointer();
4774   const double *a2Ptr=a2->getConstPointer();
4775   int nbElem=nbOfTuple*nbOfComp;
4776   for(int i=0;i<nbElem;i++)
4777     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4778   ret->copyStringInfoFrom(*a1);
4779   return ret;
4780 }
4781
4782 /*!
4783  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4784  * Info on components is copied from the first of the given arrays.
4785  * Number of tuples and components in the given arrays must be the same.
4786  *  \param [in] a1 - an array to compare values with another one.
4787  *  \param [in] a2 - another array to compare values with the first one.
4788  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4789  *          The caller is to delete this result array using decrRef() as it is no more
4790  *          needed.
4791  *  \throw If either \a a1 or \a a2 is NULL.
4792  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4793  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4794  */
4795 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4796 {
4797   if(!a1 || !a2)
4798     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4799   int nbOfComp=a1->getNumberOfComponents();
4800   if(nbOfComp!=a2->getNumberOfComponents())
4801     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4802   int nbOfTuple=a1->getNumberOfTuples();
4803   if(nbOfTuple!=a2->getNumberOfTuples())
4804     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4805   DataArrayDouble *ret=DataArrayDouble::New();
4806   ret->alloc(nbOfTuple,nbOfComp);
4807   double *retPtr=ret->getPointer();
4808   const double *a1Ptr=a1->getConstPointer();
4809   const double *a2Ptr=a2->getConstPointer();
4810   int nbElem=nbOfTuple*nbOfComp;
4811   for(int i=0;i<nbElem;i++)
4812     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4813   ret->copyStringInfoFrom(*a1);
4814   return ret;
4815 }
4816
4817 /*!
4818  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4819  * valid cases.
4820  * 1.  The arrays have same number of tuples and components. Then each value of
4821  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4822  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4823  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4824  *   component. Then
4825  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4826  * 3.  The arrays have same number of components and one array, say _a2_, has one
4827  *   tuple. Then
4828  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4829  *
4830  * Info on components is copied either from the first array (in the first case) or from
4831  * the array with maximal number of elements (getNbOfElems()).
4832  *  \param [in] a1 - an array to sum up.
4833  *  \param [in] a2 - another array to sum up.
4834  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4835  *          The caller is to delete this result array using decrRef() as it is no more
4836  *          needed.
4837  *  \throw If either \a a1 or \a a2 is NULL.
4838  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4839  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4840  *         none of them has number of tuples or components equal to 1.
4841  */
4842 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4843 {
4844   if(!a1 || !a2)
4845     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4846   int nbOfTuple=a1->getNumberOfTuples();
4847   int nbOfTuple2=a2->getNumberOfTuples();
4848   int nbOfComp=a1->getNumberOfComponents();
4849   int nbOfComp2=a2->getNumberOfComponents();
4850   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4851   if(nbOfTuple==nbOfTuple2)
4852     {
4853       if(nbOfComp==nbOfComp2)
4854         {
4855           ret=DataArrayDouble::New();
4856           ret->alloc(nbOfTuple,nbOfComp);
4857           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4858           ret->copyStringInfoFrom(*a1);
4859         }
4860       else
4861         {
4862           int nbOfCompMin,nbOfCompMax;
4863           const DataArrayDouble *aMin, *aMax;
4864           if(nbOfComp>nbOfComp2)
4865             {
4866               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4867               aMin=a2; aMax=a1;
4868             }
4869           else
4870             {
4871               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4872               aMin=a1; aMax=a2;
4873             }
4874           if(nbOfCompMin==1)
4875             {
4876               ret=DataArrayDouble::New();
4877               ret->alloc(nbOfTuple,nbOfCompMax);
4878               const double *aMinPtr=aMin->getConstPointer();
4879               const double *aMaxPtr=aMax->getConstPointer();
4880               double *res=ret->getPointer();
4881               for(int i=0;i<nbOfTuple;i++)
4882                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4883               ret->copyStringInfoFrom(*aMax);
4884             }
4885           else
4886             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4887         }
4888     }
4889   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4890     {
4891       if(nbOfComp==nbOfComp2)
4892         {
4893           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4894           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4895           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4896           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4897           ret=DataArrayDouble::New();
4898           ret->alloc(nbOfTupleMax,nbOfComp);
4899           double *res=ret->getPointer();
4900           for(int i=0;i<nbOfTupleMax;i++)
4901             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4902           ret->copyStringInfoFrom(*aMax);
4903         }
4904       else
4905         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4906     }
4907   else
4908     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4909   return ret.retn();
4910 }
4911
4912 /*!
4913  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4914  * valid cases.
4915  * 1.  The arrays have same number of tuples and components. Then each value of
4916  *   \a other array is added to the corresponding value of \a this array, i.e.:
4917  *   _a_ [ i, j ] += _other_ [ i, j ].
4918  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4919  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4920  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4921  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4922  *
4923  *  \param [in] other - an array to add to \a this one.
4924  *  \throw If \a other is NULL.
4925  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4926  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4927  *         \a other has number of both tuples and components not equal to 1.
4928  */
4929 void DataArrayDouble::addEqual(const DataArrayDouble *other)
4930 {
4931   if(!other)
4932     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4933   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4934   checkAllocated();
4935   other->checkAllocated();
4936   int nbOfTuple=getNumberOfTuples();
4937   int nbOfTuple2=other->getNumberOfTuples();
4938   int nbOfComp=getNumberOfComponents();
4939   int nbOfComp2=other->getNumberOfComponents();
4940   if(nbOfTuple==nbOfTuple2)
4941     {
4942       if(nbOfComp==nbOfComp2)
4943         {
4944           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4945         }
4946       else if(nbOfComp2==1)
4947         {
4948           double *ptr=getPointer();
4949           const double *ptrc=other->getConstPointer();
4950           for(int i=0;i<nbOfTuple;i++)
4951             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4952         }
4953       else
4954         throw INTERP_KERNEL::Exception(msg);
4955     }
4956   else if(nbOfTuple2==1)
4957     {
4958       if(nbOfComp2==nbOfComp)
4959         {
4960           double *ptr=getPointer();
4961           const double *ptrc=other->getConstPointer();
4962           for(int i=0;i<nbOfTuple;i++)
4963             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4964         }
4965       else
4966         throw INTERP_KERNEL::Exception(msg);
4967     }
4968   else
4969     throw INTERP_KERNEL::Exception(msg);
4970   declareAsNew();
4971 }
4972
4973 /*!
4974  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4975  * valid cases.
4976  * 1.  The arrays have same number of tuples and components. Then each value of
4977  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4978  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4979  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4980  *   component. Then
4981  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4982  * 3.  The arrays have same number of components and one array, say _a2_, has one
4983  *   tuple. Then
4984  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4985  *
4986  * Info on components is copied either from the first array (in the first case) or from
4987  * the array with maximal number of elements (getNbOfElems()).
4988  *  \param [in] a1 - an array to subtract from.
4989  *  \param [in] a2 - an array to subtract.
4990  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4991  *          The caller is to delete this result array using decrRef() as it is no more
4992  *          needed.
4993  *  \throw If either \a a1 or \a a2 is NULL.
4994  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4995  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4996  *         none of them has number of tuples or components equal to 1.
4997  */
4998 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
4999 {
5000   if(!a1 || !a2)
5001     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5002   int nbOfTuple1=a1->getNumberOfTuples();
5003   int nbOfTuple2=a2->getNumberOfTuples();
5004   int nbOfComp1=a1->getNumberOfComponents();
5005   int nbOfComp2=a2->getNumberOfComponents();
5006   if(nbOfTuple2==nbOfTuple1)
5007     {
5008       if(nbOfComp1==nbOfComp2)
5009         {
5010           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5011           ret->alloc(nbOfTuple2,nbOfComp1);
5012           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5013           ret->copyStringInfoFrom(*a1);
5014           return ret.retn();
5015         }
5016       else if(nbOfComp2==1)
5017         {
5018           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5019           ret->alloc(nbOfTuple1,nbOfComp1);
5020           const double *a2Ptr=a2->getConstPointer();
5021           const double *a1Ptr=a1->getConstPointer();
5022           double *res=ret->getPointer();
5023           for(int i=0;i<nbOfTuple1;i++)
5024             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5025           ret->copyStringInfoFrom(*a1);
5026           return ret.retn();
5027         }
5028       else
5029         {
5030           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5031           return 0;
5032         }
5033     }
5034   else if(nbOfTuple2==1)
5035     {
5036       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5037       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5038       ret->alloc(nbOfTuple1,nbOfComp1);
5039       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5040       double *pt=ret->getPointer();
5041       for(int i=0;i<nbOfTuple1;i++)
5042         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5043       ret->copyStringInfoFrom(*a1);
5044       return ret.retn();
5045     }
5046   else
5047     {
5048       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5049       return 0;
5050     }
5051 }
5052
5053 /*!
5054  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5055  * valid cases.
5056  * 1.  The arrays have same number of tuples and components. Then each value of
5057  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5058  *   _a_ [ i, j ] -= _other_ [ i, j ].
5059  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5060  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5061  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5062  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5063  *
5064  *  \param [in] other - an array to subtract from \a this one.
5065  *  \throw If \a other is NULL.
5066  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5067  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5068  *         \a other has number of both tuples and components not equal to 1.
5069  */
5070 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5071 {
5072   if(!other)
5073     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5074   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5075   checkAllocated();
5076   other->checkAllocated();
5077   int nbOfTuple=getNumberOfTuples();
5078   int nbOfTuple2=other->getNumberOfTuples();
5079   int nbOfComp=getNumberOfComponents();
5080   int nbOfComp2=other->getNumberOfComponents();
5081   if(nbOfTuple==nbOfTuple2)
5082     {
5083       if(nbOfComp==nbOfComp2)
5084         {
5085           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5086         }
5087       else if(nbOfComp2==1)
5088         {
5089           double *ptr=getPointer();
5090           const double *ptrc=other->getConstPointer();
5091           for(int i=0;i<nbOfTuple;i++)
5092             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5093         }
5094       else
5095         throw INTERP_KERNEL::Exception(msg);
5096     }
5097   else if(nbOfTuple2==1)
5098     {
5099       if(nbOfComp2==nbOfComp)
5100         {
5101           double *ptr=getPointer();
5102           const double *ptrc=other->getConstPointer();
5103           for(int i=0;i<nbOfTuple;i++)
5104             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5105         }
5106       else
5107         throw INTERP_KERNEL::Exception(msg);
5108     }
5109   else
5110     throw INTERP_KERNEL::Exception(msg);
5111   declareAsNew();
5112 }
5113
5114 /*!
5115  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5116  * valid cases.
5117  * 1.  The arrays have same number of tuples and components. Then each value of
5118  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5119  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5120  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5121  *   component. Then
5122  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5123  * 3.  The arrays have same number of components and one array, say _a2_, has one
5124  *   tuple. Then
5125  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5126  *
5127  * Info on components is copied either from the first array (in the first case) or from
5128  * the array with maximal number of elements (getNbOfElems()).
5129  *  \param [in] a1 - a factor array.
5130  *  \param [in] a2 - another factor array.
5131  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5132  *          The caller is to delete this result array using decrRef() as it is no more
5133  *          needed.
5134  *  \throw If either \a a1 or \a a2 is NULL.
5135  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5136  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5137  *         none of them has number of tuples or components equal to 1.
5138  */
5139 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5140 {
5141   if(!a1 || !a2)
5142     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5143   int nbOfTuple=a1->getNumberOfTuples();
5144   int nbOfTuple2=a2->getNumberOfTuples();
5145   int nbOfComp=a1->getNumberOfComponents();
5146   int nbOfComp2=a2->getNumberOfComponents();
5147   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5148   if(nbOfTuple==nbOfTuple2)
5149     {
5150       if(nbOfComp==nbOfComp2)
5151         {
5152           ret=DataArrayDouble::New();
5153           ret->alloc(nbOfTuple,nbOfComp);
5154           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5155           ret->copyStringInfoFrom(*a1);
5156         }
5157       else
5158         {
5159           int nbOfCompMin,nbOfCompMax;
5160           const DataArrayDouble *aMin, *aMax;
5161           if(nbOfComp>nbOfComp2)
5162             {
5163               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5164               aMin=a2; aMax=a1;
5165             }
5166           else
5167             {
5168               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5169               aMin=a1; aMax=a2;
5170             }
5171           if(nbOfCompMin==1)
5172             {
5173               ret=DataArrayDouble::New();
5174               ret->alloc(nbOfTuple,nbOfCompMax);
5175               const double *aMinPtr=aMin->getConstPointer();
5176               const double *aMaxPtr=aMax->getConstPointer();
5177               double *res=ret->getPointer();
5178               for(int i=0;i<nbOfTuple;i++)
5179                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5180               ret->copyStringInfoFrom(*aMax);
5181             }
5182           else
5183             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5184         }
5185     }
5186   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5187     {
5188       if(nbOfComp==nbOfComp2)
5189         {
5190           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5191           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5192           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5193           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5194           ret=DataArrayDouble::New();
5195           ret->alloc(nbOfTupleMax,nbOfComp);
5196           double *res=ret->getPointer();
5197           for(int i=0;i<nbOfTupleMax;i++)
5198             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5199           ret->copyStringInfoFrom(*aMax);
5200         }
5201       else
5202         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5203     }
5204   else
5205     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5206   return ret.retn();
5207 }
5208
5209 /*!
5210  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5211  * valid cases.
5212  * 1.  The arrays have same number of tuples and components. Then each value of
5213  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5214  *   _this_ [ i, j ] *= _other_ [ i, j ].
5215  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5216  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5217  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5218  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5219  *
5220  *  \param [in] other - an array to multiply to \a this one.
5221  *  \throw If \a other is NULL.
5222  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5223  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5224  *         \a other has number of both tuples and components not equal to 1.
5225  */
5226 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5227 {
5228   if(!other)
5229     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5230   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5231   checkAllocated();
5232   other->checkAllocated();
5233   int nbOfTuple=getNumberOfTuples();
5234   int nbOfTuple2=other->getNumberOfTuples();
5235   int nbOfComp=getNumberOfComponents();
5236   int nbOfComp2=other->getNumberOfComponents();
5237   if(nbOfTuple==nbOfTuple2)
5238     {
5239       if(nbOfComp==nbOfComp2)
5240         {
5241           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5242         }
5243       else if(nbOfComp2==1)
5244         {
5245           double *ptr=getPointer();
5246           const double *ptrc=other->getConstPointer();
5247           for(int i=0;i<nbOfTuple;i++)
5248             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5249         }
5250       else
5251         throw INTERP_KERNEL::Exception(msg);
5252     }
5253   else if(nbOfTuple2==1)
5254     {
5255       if(nbOfComp2==nbOfComp)
5256         {
5257           double *ptr=getPointer();
5258           const double *ptrc=other->getConstPointer();
5259           for(int i=0;i<nbOfTuple;i++)
5260             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5261         }
5262       else
5263         throw INTERP_KERNEL::Exception(msg);
5264     }
5265   else
5266     throw INTERP_KERNEL::Exception(msg);
5267   declareAsNew();
5268 }
5269
5270 /*!
5271  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5272  * valid cases.
5273  * 1.  The arrays have same number of tuples and components. Then each value of
5274  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5275  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5276  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5277  *   component. Then
5278  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5279  * 3.  The arrays have same number of components and one array, say _a2_, has one
5280  *   tuple. Then
5281  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5282  *
5283  * Info on components is copied either from the first array (in the first case) or from
5284  * the array with maximal number of elements (getNbOfElems()).
5285  *  \warning No check of division by zero is performed!
5286  *  \param [in] a1 - a numerator array.
5287  *  \param [in] a2 - a denominator array.
5288  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5289  *          The caller is to delete this result array using decrRef() as it is no more
5290  *          needed.
5291  *  \throw If either \a a1 or \a a2 is NULL.
5292  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5293  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5294  *         none of them has number of tuples or components equal to 1.
5295  */
5296 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5297 {
5298   if(!a1 || !a2)
5299     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5300   int nbOfTuple1=a1->getNumberOfTuples();
5301   int nbOfTuple2=a2->getNumberOfTuples();
5302   int nbOfComp1=a1->getNumberOfComponents();
5303   int nbOfComp2=a2->getNumberOfComponents();
5304   if(nbOfTuple2==nbOfTuple1)
5305     {
5306       if(nbOfComp1==nbOfComp2)
5307         {
5308           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5309           ret->alloc(nbOfTuple2,nbOfComp1);
5310           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5311           ret->copyStringInfoFrom(*a1);
5312           return ret.retn();
5313         }
5314       else if(nbOfComp2==1)
5315         {
5316           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5317           ret->alloc(nbOfTuple1,nbOfComp1);
5318           const double *a2Ptr=a2->getConstPointer();
5319           const double *a1Ptr=a1->getConstPointer();
5320           double *res=ret->getPointer();
5321           for(int i=0;i<nbOfTuple1;i++)
5322             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5323           ret->copyStringInfoFrom(*a1);
5324           return ret.retn();
5325         }
5326       else
5327         {
5328           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5329           return 0;
5330         }
5331     }
5332   else if(nbOfTuple2==1)
5333     {
5334       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5335       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5336       ret->alloc(nbOfTuple1,nbOfComp1);
5337       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5338       double *pt=ret->getPointer();
5339       for(int i=0;i<nbOfTuple1;i++)
5340         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5341       ret->copyStringInfoFrom(*a1);
5342       return ret.retn();
5343     }
5344   else
5345     {
5346       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5347       return 0;
5348     }
5349 }
5350
5351 /*!
5352  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5353  * valid cases.
5354  * 1.  The arrays have same number of tuples and components. Then each value of
5355  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5356  *   _a_ [ i, j ] /= _other_ [ i, j ].
5357  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5358  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5359  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5360  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5361  *
5362  *  \warning No check of division by zero is performed!
5363  *  \param [in] other - an array to divide \a this one by.
5364  *  \throw If \a other is NULL.
5365  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5366  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5367  *         \a other has number of both tuples and components not equal to 1.
5368  */
5369 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5370 {
5371   if(!other)
5372     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5373   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5374   checkAllocated();
5375   other->checkAllocated();
5376   int nbOfTuple=getNumberOfTuples();
5377   int nbOfTuple2=other->getNumberOfTuples();
5378   int nbOfComp=getNumberOfComponents();
5379   int nbOfComp2=other->getNumberOfComponents();
5380   if(nbOfTuple==nbOfTuple2)
5381     {
5382       if(nbOfComp==nbOfComp2)
5383         {
5384           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5385         }
5386       else if(nbOfComp2==1)
5387         {
5388           double *ptr=getPointer();
5389           const double *ptrc=other->getConstPointer();
5390           for(int i=0;i<nbOfTuple;i++)
5391             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5392         }
5393       else
5394         throw INTERP_KERNEL::Exception(msg);
5395     }
5396   else if(nbOfTuple2==1)
5397     {
5398       if(nbOfComp2==nbOfComp)
5399         {
5400           double *ptr=getPointer();
5401           const double *ptrc=other->getConstPointer();
5402           for(int i=0;i<nbOfTuple;i++)
5403             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5404         }
5405       else
5406         throw INTERP_KERNEL::Exception(msg);
5407     }
5408   else
5409     throw INTERP_KERNEL::Exception(msg);
5410   declareAsNew();
5411 }
5412
5413 /*!
5414  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5415  * valid cases.
5416  *
5417  *  \param [in] a1 - an array to pow up.
5418  *  \param [in] a2 - another array to sum up.
5419  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5420  *          The caller is to delete this result array using decrRef() as it is no more
5421  *          needed.
5422  *  \throw If either \a a1 or \a a2 is NULL.
5423  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5424  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5425  *  \throw If there is a negative value in \a a1.
5426  */
5427 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5428 {
5429   if(!a1 || !a2)
5430     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5431   int nbOfTuple=a1->getNumberOfTuples();
5432   int nbOfTuple2=a2->getNumberOfTuples();
5433   int nbOfComp=a1->getNumberOfComponents();
5434   int nbOfComp2=a2->getNumberOfComponents();
5435   if(nbOfTuple!=nbOfTuple2)
5436     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5437   if(nbOfComp!=1 || nbOfComp2!=1)
5438     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5439   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5440   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5441   double *ptr=ret->getPointer();
5442   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5443     {
5444       if(*ptr1>=0)
5445         {
5446           *ptr=pow(*ptr1,*ptr2);
5447         }
5448       else
5449         {
5450           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5451           throw INTERP_KERNEL::Exception(oss.str().c_str());
5452         }
5453     }
5454   return ret.retn();
5455 }
5456
5457 /*!
5458  * Apply pow on values of another DataArrayDouble to values of \a this one.
5459  *
5460  *  \param [in] other - an array to pow to \a this one.
5461  *  \throw If \a other is NULL.
5462  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5463  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5464  *  \throw If there is a negative value in \a this.
5465  */
5466 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5467 {
5468   if(!other)
5469     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5470   int nbOfTuple=getNumberOfTuples();
5471   int nbOfTuple2=other->getNumberOfTuples();
5472   int nbOfComp=getNumberOfComponents();
5473   int nbOfComp2=other->getNumberOfComponents();
5474   if(nbOfTuple!=nbOfTuple2)
5475     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5476   if(nbOfComp!=1 || nbOfComp2!=1)
5477     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5478   double *ptr=getPointer();
5479   const double *ptrc=other->begin();
5480   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5481     {
5482       if(*ptr>=0)
5483         *ptr=pow(*ptr,*ptrc);
5484       else
5485         {
5486           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5487           throw INTERP_KERNEL::Exception(oss.str().c_str());
5488         }
5489     }
5490   declareAsNew();
5491 }
5492
5493 /*!
5494  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5495  * Server side.
5496  */
5497 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5498 {
5499   tinyInfo.resize(2);
5500   if(isAllocated())
5501     {
5502       tinyInfo[0]=getNumberOfTuples();
5503       tinyInfo[1]=getNumberOfComponents();
5504     }
5505   else
5506     {
5507       tinyInfo[0]=-1;
5508       tinyInfo[1]=-1;
5509     }
5510 }
5511
5512 /*!
5513  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5514  * Server side.
5515  */
5516 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5517 {
5518   if(isAllocated())
5519     {
5520       int nbOfCompo=getNumberOfComponents();
5521       tinyInfo.resize(nbOfCompo+1);
5522       tinyInfo[0]=getName();
5523       for(int i=0;i<nbOfCompo;i++)
5524         tinyInfo[i+1]=getInfoOnComponent(i);
5525     }
5526   else
5527     {
5528       tinyInfo.resize(1);
5529       tinyInfo[0]=getName();
5530     }
5531 }
5532
5533 /*!
5534  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5535  * This method returns if a feeding is needed.
5536  */
5537 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5538 {
5539   int nbOfTuple=tinyInfoI[0];
5540   int nbOfComp=tinyInfoI[1];
5541   if(nbOfTuple!=-1 || nbOfComp!=-1)
5542     {
5543       alloc(nbOfTuple,nbOfComp);
5544       return true;
5545     }
5546   return false;
5547 }
5548
5549 /*!
5550  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5551  */
5552 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5553 {
5554   setName(tinyInfoS[0].c_str());
5555   if(isAllocated())
5556     {
5557       int nbOfCompo=getNumberOfComponents();
5558       for(int i=0;i<nbOfCompo;i++)
5559         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5560     }
5561 }
5562
5563 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5564 {
5565   if(_da)
5566     {
5567       _da->incrRef();
5568       if(_da->isAllocated())
5569         {
5570           _nb_comp=da->getNumberOfComponents();
5571           _nb_tuple=da->getNumberOfTuples();
5572           _pt=da->getPointer();
5573         }
5574     }
5575 }
5576
5577 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5578 {
5579   if(_da)
5580     _da->decrRef();
5581 }
5582
5583 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5584 {
5585   if(_tuple_id<_nb_tuple)
5586     {
5587       _tuple_id++;
5588       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5589       _pt+=_nb_comp;
5590       return ret;
5591     }
5592   else
5593     return 0;
5594 }
5595
5596 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5597 {
5598 }
5599
5600
5601 std::string DataArrayDoubleTuple::repr() const
5602 {
5603   std::ostringstream oss; oss.precision(17); oss << "(";
5604   for(int i=0;i<_nb_of_compo-1;i++)
5605     oss << _pt[i] << ", ";
5606   oss << _pt[_nb_of_compo-1] << ")";
5607   return oss.str();
5608 }
5609
5610 double DataArrayDoubleTuple::doubleValue() const
5611 {
5612   if(_nb_of_compo==1)
5613     return *_pt;
5614   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5615 }
5616
5617 /*!
5618  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5619  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5620  * 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
5621  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5622  */
5623 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5624 {
5625   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5626     {
5627       DataArrayDouble *ret=DataArrayDouble::New();
5628       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5629       return ret;
5630     }
5631   else
5632     {
5633       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5634       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5635       throw INTERP_KERNEL::Exception(oss.str().c_str());
5636     }
5637 }
5638
5639 /*!
5640  * Returns a new instance of DataArrayInt. The caller is to delete this array
5641  * using decrRef() as it is no more needed. 
5642  */
5643 DataArrayInt *DataArrayInt::New()
5644 {
5645   return new DataArrayInt;
5646 }
5647
5648 /*!
5649  * Checks if raw data is allocated. Read more on the raw data
5650  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5651  *  \return bool - \a true if the raw data is allocated, \a false else.
5652  */
5653 bool DataArrayInt::isAllocated() const
5654 {
5655   return getConstPointer()!=0;
5656 }
5657
5658 /*!
5659  * Checks if raw data is allocated and throws an exception if it is not the case.
5660  *  \throw If the raw data is not allocated.
5661  */
5662 void DataArrayInt::checkAllocated() const
5663 {
5664   if(!isAllocated())
5665     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5666 }
5667
5668 /*!
5669  * This method desallocated \a this without modification of informations relative to the components.
5670  * After call of this method, DataArrayInt::isAllocated will return false.
5671  * If \a this is already not allocated, \a this is let unchanged.
5672  */
5673 void DataArrayInt::desallocate()
5674 {
5675   _mem.destroy();
5676 }
5677
5678 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5679 {
5680   std::size_t sz(_mem.getNbOfElemAllocated());
5681   sz*=sizeof(int);
5682   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5683 }
5684
5685 /*!
5686  * Returns the only one value in \a this, if and only if number of elements
5687  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5688  *  \return double - the sole value stored in \a this array.
5689  *  \throw If at least one of conditions stated above is not fulfilled.
5690  */
5691 int DataArrayInt::intValue() const
5692 {
5693   if(isAllocated())
5694     {
5695       if(getNbOfElems()==1)
5696         {
5697           return *getConstPointer();
5698         }
5699       else
5700         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5701     }
5702   else
5703     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5704 }
5705
5706 /*!
5707  * Returns an integer value characterizing \a this array, which is useful for a quick
5708  * comparison of many instances of DataArrayInt.
5709  *  \return int - the hash value.
5710  *  \throw If \a this is not allocated.
5711  */
5712 int DataArrayInt::getHashCode() const
5713 {
5714   checkAllocated();
5715   std::size_t nbOfElems=getNbOfElems();
5716   int ret=nbOfElems*65536;
5717   int delta=3;
5718   if(nbOfElems>48)
5719     delta=nbOfElems/8;
5720   int ret0=0;
5721   const int *pt=begin();
5722   for(std::size_t i=0;i<nbOfElems;i+=delta)
5723     ret0+=pt[i] & 0x1FFF;
5724   return ret+ret0;
5725 }
5726
5727 /*!
5728  * Checks the number of tuples.
5729  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5730  *  \throw If \a this is not allocated.
5731  */
5732 bool DataArrayInt::empty() const
5733 {
5734   checkAllocated();
5735   return getNumberOfTuples()==0;
5736 }
5737
5738 /*!
5739  * Returns a full copy of \a this. For more info on copying data arrays see
5740  * \ref MEDCouplingArrayBasicsCopyDeep.
5741  *  \return DataArrayInt * - a new instance of DataArrayInt.
5742  */
5743 DataArrayInt *DataArrayInt::deepCpy() const
5744 {
5745   return new DataArrayInt(*this);
5746 }
5747
5748 /*!
5749  * Returns either a \a deep or \a shallow copy of this array. For more info see
5750  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5751  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5752  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5753  *          == \a true) or \a this instance (if \a dCpy == \a false).
5754  */
5755 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5756 {
5757   if(dCpy)
5758     return deepCpy();
5759   else
5760     {
5761       incrRef();
5762       return const_cast<DataArrayInt *>(this);
5763     }
5764 }
5765
5766 /*!
5767  * Copies all the data from another DataArrayInt. For more info see
5768  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5769  *  \param [in] other - another instance of DataArrayInt to copy data from.
5770  *  \throw If the \a other is not allocated.
5771  */
5772 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5773 {
5774   other.checkAllocated();
5775   int nbOfTuples=other.getNumberOfTuples();
5776   int nbOfComp=other.getNumberOfComponents();
5777   allocIfNecessary(nbOfTuples,nbOfComp);
5778   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5779   int *pt=getPointer();
5780   const int *ptI=other.getConstPointer();
5781   for(std::size_t i=0;i<nbOfElems;i++)
5782     pt[i]=ptI[i];
5783   copyStringInfoFrom(other);
5784 }
5785
5786 /*!
5787  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5788  * 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.
5789  * If \a this has not already been allocated, number of components is set to one.
5790  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5791  * 
5792  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5793  */
5794 void DataArrayInt::reserve(std::size_t nbOfElems)
5795 {
5796   int nbCompo=getNumberOfComponents();
5797   if(nbCompo==1)
5798     {
5799       _mem.reserve(nbOfElems);
5800     }
5801   else if(nbCompo==0)
5802     {
5803       _mem.reserve(nbOfElems);
5804       _info_on_compo.resize(1);
5805     }
5806   else
5807     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5808 }
5809
5810 /*!
5811  * 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
5812  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5813  *
5814  * \param [in] val the value to be added in \a this
5815  * \throw If \a this has already been allocated with number of components different from one.
5816  * \sa DataArrayInt::pushBackValsSilent
5817  */
5818 void DataArrayInt::pushBackSilent(int val)
5819 {
5820   int nbCompo=getNumberOfComponents();
5821   if(nbCompo==1)
5822     _mem.pushBack(val);
5823   else if(nbCompo==0)
5824     {
5825       _info_on_compo.resize(1);
5826       _mem.pushBack(val);
5827     }
5828   else
5829     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5830 }
5831
5832 /*!
5833  * 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
5834  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5835  *
5836  *  \param [in] valsBg - an array of values to push at the end of \this.
5837  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5838  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5839  * \throw If \a this has already been allocated with number of components different from one.
5840  * \sa DataArrayInt::pushBackSilent
5841  */
5842 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5843 {
5844   int nbCompo=getNumberOfComponents();
5845   if(nbCompo==1)
5846     _mem.insertAtTheEnd(valsBg,valsEnd);
5847   else if(nbCompo==0)
5848     {
5849       _info_on_compo.resize(1);
5850       _mem.insertAtTheEnd(valsBg,valsEnd);
5851     }
5852   else
5853     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5854 }
5855
5856 /*!
5857  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5858  * \throw If \a this is already empty.
5859  * \throw If \a this has number of components different from one.
5860  */
5861 int DataArrayInt::popBackSilent()
5862 {
5863   if(getNumberOfComponents()==1)
5864     return _mem.popBack();
5865   else
5866     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5867 }
5868
5869 /*!
5870  * 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.
5871  *
5872  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5873  */
5874 void DataArrayInt::pack() const
5875 {
5876   _mem.pack();
5877 }
5878
5879 /*!
5880  * Allocates the raw data in memory. If exactly as same memory as needed already
5881  * allocated, it is not re-allocated.
5882  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5883  *  \param [in] nbOfCompo - number of components of data to allocate.
5884  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5885  */
5886 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5887 {
5888   if(isAllocated())
5889     {
5890       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5891         alloc(nbOfTuple,nbOfCompo);
5892     }
5893   else
5894     alloc(nbOfTuple,nbOfCompo);
5895 }
5896
5897 /*!
5898  * Allocates the raw data in memory. If the memory was already allocated, then it is
5899  * freed and re-allocated. See an example of this method use
5900  * \ref MEDCouplingArraySteps1WC "here".
5901  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5902  *  \param [in] nbOfCompo - number of components of data to allocate.
5903  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5904  */
5905 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
5906 {
5907   if(nbOfTuple<0 || nbOfCompo<0)
5908     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5909   _info_on_compo.resize(nbOfCompo);
5910   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5911   declareAsNew();
5912 }
5913
5914 /*!
5915  * Assign zero to all values in \a this array. To know more on filling arrays see
5916  * \ref MEDCouplingArrayFill.
5917  * \throw If \a this is not allocated.
5918  */
5919 void DataArrayInt::fillWithZero()
5920 {
5921   checkAllocated();
5922   _mem.fillWithValue(0);
5923   declareAsNew();
5924 }
5925
5926 /*!
5927  * Assign \a val to all values in \a this array. To know more on filling arrays see
5928  * \ref MEDCouplingArrayFill.
5929  *  \param [in] val - the value to fill with.
5930  *  \throw If \a this is not allocated.
5931  */
5932 void DataArrayInt::fillWithValue(int val)
5933 {
5934   checkAllocated();
5935   _mem.fillWithValue(val);
5936   declareAsNew();
5937 }
5938
5939 /*!
5940  * Set all values in \a this array so that the i-th element equals to \a init + i
5941  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5942  *  \param [in] init - value to assign to the first element of array.
5943  *  \throw If \a this->getNumberOfComponents() != 1
5944  *  \throw If \a this is not allocated.
5945  */
5946 void DataArrayInt::iota(int init)
5947 {
5948   checkAllocated();
5949   if(getNumberOfComponents()!=1)
5950     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5951   int *ptr=getPointer();
5952   int ntuples=getNumberOfTuples();
5953   for(int i=0;i<ntuples;i++)
5954     ptr[i]=init+i;
5955   declareAsNew();
5956 }
5957
5958 /*!
5959  * Returns a textual and human readable representation of \a this instance of
5960  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5961  *  \return std::string - text describing \a this DataArrayInt.
5962  */
5963 std::string DataArrayInt::repr() const
5964 {
5965   std::ostringstream ret;
5966   reprStream(ret);
5967   return ret.str();
5968 }
5969
5970 std::string DataArrayInt::reprZip() const
5971 {
5972   std::ostringstream ret;
5973   reprZipStream(ret);
5974   return ret.str();
5975 }
5976
5977 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
5978 {
5979   static const char SPACE[4]={' ',' ',' ',' '};
5980   checkAllocated();
5981   std::string idt(indent,' ');
5982   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5983   if(byteArr)
5984     {
5985       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5986       if(std::string(type)=="Int32")
5987         {
5988           const char *data(reinterpret_cast<const char *>(begin()));
5989           std::size_t sz(getNbOfElems()*sizeof(int));
5990           byteArr->insertAtTheEnd(data,data+sz);
5991           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5992         }
5993       else if(std::string(type)=="Int8")
5994         {
5995           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5996           std::copy(begin(),end(),(char *)tmp);
5997           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5998           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5999         }
6000       else if(std::string(type)=="UInt8")
6001         {
6002           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6003           std::copy(begin(),end(),(unsigned char *)tmp);
6004           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6005           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6006         }
6007       else
6008         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6009     }
6010   else
6011     {
6012       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6013       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6014     }
6015   ofs << std::endl << idt << "</DataArray>\n";
6016 }
6017
6018 void DataArrayInt::reprStream(std::ostream& stream) const
6019 {
6020   stream << "Name of int array : \"" << _name << "\"\n";
6021   reprWithoutNameStream(stream);
6022 }
6023
6024 void DataArrayInt::reprZipStream(std::ostream& stream) const
6025 {
6026   stream << "Name of int array : \"" << _name << "\"\n";
6027   reprZipWithoutNameStream(stream);
6028 }
6029
6030 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6031 {
6032   DataArray::reprWithoutNameStream(stream);
6033   _mem.repr(getNumberOfComponents(),stream);
6034 }
6035
6036 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6037 {
6038   DataArray::reprWithoutNameStream(stream);
6039   _mem.reprZip(getNumberOfComponents(),stream);
6040 }
6041
6042 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
6043 {
6044   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6045   const int *data=getConstPointer();
6046   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6047   if(nbTuples*nbComp>=1)
6048     {
6049       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6050       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6051       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6052       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6053     }
6054   else
6055     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6056   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6057 }
6058
6059 /*!
6060  * Method that gives a quick overvien of \a this for python.
6061  */
6062 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6063 {
6064   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6065   stream << "DataArrayInt C++ instance at " << this << ". ";
6066   if(isAllocated())
6067     {
6068       int nbOfCompo=(int)_info_on_compo.size();
6069       if(nbOfCompo>=1)
6070         {
6071           int nbOfTuples=getNumberOfTuples();
6072           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6073           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6074         }
6075       else
6076         stream << "Number of components : 0.";
6077     }
6078   else
6079     stream << "*** No data allocated ****";
6080 }
6081
6082 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6083 {
6084   const int *data=begin();
6085   int nbOfTuples=getNumberOfTuples();
6086   int nbOfCompo=(int)_info_on_compo.size();
6087   std::ostringstream oss2; oss2 << "[";
6088   std::string oss2Str(oss2.str());
6089   bool isFinished=true;
6090   for(int i=0;i<nbOfTuples && isFinished;i++)
6091     {
6092       if(nbOfCompo>1)
6093         {
6094           oss2 << "(";
6095           for(int j=0;j<nbOfCompo;j++,data++)
6096             {
6097               oss2 << *data;
6098               if(j!=nbOfCompo-1) oss2 << ", ";
6099             }
6100           oss2 << ")";
6101         }
6102       else
6103         oss2 << *data++;
6104       if(i!=nbOfTuples-1) oss2 << ", ";
6105       std::string oss3Str(oss2.str());
6106       if(oss3Str.length()<maxNbOfByteInRepr)
6107         oss2Str=oss3Str;
6108       else
6109         isFinished=false;
6110     }
6111   stream << oss2Str;
6112   if(!isFinished)
6113     stream << "... ";
6114   stream << "]";
6115 }
6116
6117 /*!
6118  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6119  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6120  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6121  *         to \a this array.
6122  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6123  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6124  *  \throw If \a this->getNumberOfComponents() != 1
6125  *  \throw If any value of \a this can't be used as a valid index for 
6126  *         [\a indArrBg, \a indArrEnd).
6127  */
6128 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6129 {
6130   checkAllocated();
6131   if(getNumberOfComponents()!=1)
6132     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6133   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6134   int nbOfTuples=getNumberOfTuples();
6135   int *pt=getPointer();
6136   for(int i=0;i<nbOfTuples;i++,pt++)
6137     {
6138       if(*pt>=0 && *pt<nbElemsIn)
6139         *pt=indArrBg[*pt];
6140       else
6141         {
6142           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6143           throw INTERP_KERNEL::Exception(oss.str().c_str());
6144         }
6145     }
6146   declareAsNew();
6147 }
6148
6149 /*!
6150  * Computes distribution of values of \a this one-dimensional array between given value
6151  * ranges (casts). This method is typically useful for entity number spliting by types,
6152  * for example. 
6153  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6154  *           check of this is be done. If not, the result is not warranted. 
6155  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6156  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6157  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6158  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6159  *         should be more than every value in \a this array.
6160  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6161  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6162  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6163  *         (same number of tuples and components), the caller is to delete 
6164  *         using decrRef() as it is no more needed.
6165  *         This array contains indices of ranges for every value of \a this array. I.e.
6166  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6167  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6168  *         this in which cast it holds.
6169  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6170  *         array, the caller is to delete using decrRef() as it is no more needed.
6171  *         This array contains ranks of values of \a this array within ranges
6172  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6173  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6174  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6175  *         for each tuple its rank inside its cast. The rank is computed as difference
6176  *         between the value and the lowest value of range.
6177  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6178  *         ranges (casts) to which at least one value of \a this array belongs.
6179  *         Or, in other words, this param contains the casts that \a this contains.
6180  *         The caller is to delete this array using decrRef() as it is no more needed.
6181  *
6182  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6183  *            the output of this method will be : 
6184  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6185  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6186  * - \a castsPresent  : [0,1]
6187  *
6188  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6189  * range #1 and its rank within this range is 2; etc.
6190  *
6191  *  \throw If \a this->getNumberOfComponents() != 1.
6192  *  \throw If \a arrEnd - arrBg < 2.
6193  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6194  */
6195 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6196                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6197 {
6198   checkAllocated();
6199   if(getNumberOfComponents()!=1)
6200     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6201   int nbOfTuples=getNumberOfTuples();
6202   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6203   if(nbOfCast<2)
6204     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6205   nbOfCast--;
6206   const int *work=getConstPointer();
6207   typedef std::reverse_iterator<const int *> rintstart;
6208   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6209   rintstart end2(arrBg);
6210   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6211   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6212   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6213   ret1->alloc(nbOfTuples,1);
6214   ret2->alloc(nbOfTuples,1);
6215   int *ret1Ptr=ret1->getPointer();
6216   int *ret2Ptr=ret2->getPointer();
6217   std::set<std::size_t> castsDetected;
6218   for(int i=0;i<nbOfTuples;i++)
6219     {
6220       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6221       std::size_t pos=std::distance(bg,res);
6222       std::size_t pos2=nbOfCast-pos;
6223       if(pos2<nbOfCast)
6224         {
6225           ret1Ptr[i]=(int)pos2;
6226           ret2Ptr[i]=work[i]-arrBg[pos2];
6227           castsDetected.insert(pos2);
6228         }
6229       else
6230         {
6231           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6232           throw INTERP_KERNEL::Exception(oss.str().c_str());
6233         }
6234     }
6235   ret3->alloc((int)castsDetected.size(),1);
6236   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6237   castArr=ret1.retn();
6238   rankInsideCast=ret2.retn();
6239   castsPresent=ret3.retn();
6240 }
6241
6242 /*!
6243  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6244  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6245  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6246  * new value in place \a indArr[ \a v ] is i.
6247  *  \param [in] indArrBg - the array holding indices within the result array to assign
6248  *         indices of values of \a this array pointing to values of \a indArrBg.
6249  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6250  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6251  *  \return DataArrayInt * - the new instance of DataArrayInt.
6252  *          The caller is to delete this result array using decrRef() as it is no more
6253  *          needed.
6254  *  \throw If \a this->getNumberOfComponents() != 1.
6255  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6256  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6257  */
6258 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6259 {
6260   checkAllocated();
6261   if(getNumberOfComponents()!=1)
6262     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6263   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6264   int nbOfTuples=getNumberOfTuples();
6265   const int *pt=getConstPointer();
6266   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6267   ret->alloc(nbOfTuples,1);
6268   ret->fillWithValue(-1);
6269   int *tmp=ret->getPointer();
6270   for(int i=0;i<nbOfTuples;i++,pt++)
6271     {
6272       if(*pt>=0 && *pt<nbElemsIn)
6273         {
6274           int pos=indArrBg[*pt];
6275           if(pos>=0 && pos<nbOfTuples)
6276             tmp[pos]=i;
6277           else
6278             {
6279               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6280               throw INTERP_KERNEL::Exception(oss.str().c_str());
6281             }
6282         }
6283       else
6284         {
6285           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6286           throw INTERP_KERNEL::Exception(oss.str().c_str());
6287         }
6288     }
6289   return ret.retn();
6290 }
6291
6292 /*!
6293  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6294  * from values of \a this array, which is supposed to contain a renumbering map in 
6295  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6296  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6297  *  \param [in] newNbOfElem - the number of tuples in the result array.
6298  *  \return DataArrayInt * - the new instance of DataArrayInt.
6299  *          The caller is to delete this result array using decrRef() as it is no more
6300  *          needed.
6301  * 
6302  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6303  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6304  */
6305 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6306 {
6307   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6308   ret->alloc(newNbOfElem,1);
6309   int nbOfOldNodes=getNumberOfTuples();
6310   const int *old2New=getConstPointer();
6311   int *pt=ret->getPointer();
6312   for(int i=0;i!=nbOfOldNodes;i++)
6313     {
6314       int newp(old2New[i]);
6315       if(newp!=-1)
6316         {
6317           if(newp>=0 && newp<newNbOfElem)
6318             pt[newp]=i;
6319           else
6320             {
6321               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6322               throw INTERP_KERNEL::Exception(oss.str().c_str());
6323             }
6324         }
6325     }
6326   return ret.retn();
6327 }
6328
6329 /*!
6330  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6331  * 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]
6332  */
6333 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6334 {
6335   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6336   ret->alloc(newNbOfElem,1);
6337   int nbOfOldNodes=getNumberOfTuples();
6338   const int *old2New=getConstPointer();
6339   int *pt=ret->getPointer();
6340   for(int i=nbOfOldNodes-1;i>=0;i--)
6341     {
6342       int newp(old2New[i]);
6343       if(newp!=-1)
6344         {
6345           if(newp>=0 && newp<newNbOfElem)
6346             pt[newp]=i;
6347           else
6348             {
6349               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6350               throw INTERP_KERNEL::Exception(oss.str().c_str());
6351             }
6352         }
6353     }
6354   return ret.retn();
6355 }
6356
6357 /*!
6358  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6359  * from values of \a this array, which is supposed to contain a renumbering map in 
6360  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6361  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6362  *  \param [in] newNbOfElem - the number of tuples in the result array.
6363  *  \return DataArrayInt * - the new instance of DataArrayInt.
6364  *          The caller is to delete this result array using decrRef() as it is no more
6365  *          needed.
6366  * 
6367  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6368  *
6369  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6370  */
6371 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6372 {
6373   checkAllocated();
6374   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6375   ret->alloc(oldNbOfElem,1);
6376   const int *new2Old=getConstPointer();
6377   int *pt=ret->getPointer();
6378   std::fill(pt,pt+oldNbOfElem,-1);
6379   int nbOfNewElems=getNumberOfTuples();
6380   for(int i=0;i<nbOfNewElems;i++)
6381     {
6382       int v(new2Old[i]);
6383       if(v>=0 && v<oldNbOfElem)
6384          pt[v]=i;
6385       else
6386         {
6387           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6388           throw INTERP_KERNEL::Exception(oss.str().c_str());
6389         }
6390     }
6391   return ret.retn();
6392 }
6393
6394 /*!
6395  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6396  * mismatch is given.
6397  * 
6398  * \param [in] other the instance to be compared with \a this
6399  * \param [out] reason In case of inequality returns the reason.
6400  * \sa DataArrayInt::isEqual
6401  */
6402 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6403 {
6404   if(!areInfoEqualsIfNotWhy(other,reason))
6405     return false;
6406   return _mem.isEqual(other._mem,0,reason);
6407 }
6408
6409 /*!
6410  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6411  * \ref MEDCouplingArrayBasicsCompare.
6412  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6413  *  \return bool - \a true if the two arrays are equal, \a false else.
6414  */
6415 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6416 {
6417   std::string tmp;
6418   return isEqualIfNotWhy(other,tmp);
6419 }
6420
6421 /*!
6422  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6423  * \ref MEDCouplingArrayBasicsCompare.
6424  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6425  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6426  */
6427 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6428 {
6429   std::string tmp;
6430   return _mem.isEqual(other._mem,0,tmp);
6431 }
6432
6433 /*!
6434  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6435  * performed on sorted value sequences.
6436  * For more info see\ref MEDCouplingArrayBasicsCompare.
6437  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6438  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6439  */
6440 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6441 {
6442   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6443   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6444   a->sort();
6445   b->sort();
6446   return a->isEqualWithoutConsideringStr(*b);
6447 }
6448
6449 /*!
6450  * This method compares content of input vector \a v and \a this.
6451  * 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.
6452  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6453  *
6454  * \param [in] v - the vector of 'flags' to be compared with \a this.
6455  *
6456  * \throw If \a this is not sorted ascendingly.
6457  * \throw If \a this has not exactly one component.
6458  * \throw If \a this is not allocated.
6459  */
6460 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6461 {
6462   checkAllocated();
6463   if(getNumberOfComponents()!=1)
6464     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6465   const int *w(begin()),*end2(end());
6466   int refVal=-std::numeric_limits<int>::max();
6467   int i=0;
6468   std::vector<bool>::const_iterator it(v.begin());
6469   for(;it!=v.end();it++,i++)
6470     {
6471       if(*it)
6472         {
6473           if(w!=end2)
6474             {
6475               if(*w++==i)
6476                 {
6477                   if(i>refVal)
6478                     refVal=i;
6479                   else
6480                     {
6481                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6482                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6483                     }
6484                 }
6485               else
6486                 return false;
6487             }
6488           else
6489             return false;
6490         }
6491     }
6492   return w==end2;
6493 }
6494
6495 /*!
6496  * Sorts values of the array.
6497  *  \param [in] asc - \a true means ascending order, \a false, descending.
6498  *  \throw If \a this is not allocated.
6499  *  \throw If \a this->getNumberOfComponents() != 1.
6500  */
6501 void DataArrayInt::sort(bool asc)
6502 {
6503   checkAllocated();
6504   if(getNumberOfComponents()!=1)
6505     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6506   _mem.sort(asc);
6507   declareAsNew();
6508 }
6509
6510 /*!
6511  * Computes for each tuple the sum of number of components values in the tuple and return it.
6512  * 
6513  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6514  *          same number of tuples as \a this array and one component.
6515  *          The caller is to delete this result array using decrRef() as it is no more
6516  *          needed.
6517  *  \throw If \a this is not allocated.
6518  */
6519 DataArrayInt *DataArrayInt::sumPerTuple() const
6520 {
6521   checkAllocated();
6522   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6523   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6524   ret->alloc(nbOfTuple,1);
6525   const int *src(getConstPointer());
6526   int *dest(ret->getPointer());
6527   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6528     *dest=std::accumulate(src,src+nbOfComp,0);
6529   return ret.retn();
6530 }
6531
6532 /*!
6533  * Reverse the array values.
6534  *  \throw If \a this->getNumberOfComponents() < 1.
6535  *  \throw If \a this is not allocated.
6536  */
6537 void DataArrayInt::reverse()
6538 {
6539   checkAllocated();
6540   _mem.reverse(getNumberOfComponents());
6541   declareAsNew();
6542 }
6543
6544 /*!
6545  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6546  * If not an exception is thrown.
6547  *  \param [in] increasing - if \a true, the array values should be increasing.
6548  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6549  *         increasing arg.
6550  *  \throw If \a this->getNumberOfComponents() != 1.
6551  *  \throw If \a this is not allocated.
6552  */
6553 void DataArrayInt::checkMonotonic(bool increasing) const
6554 {
6555   if(!isMonotonic(increasing))
6556     {
6557       if (increasing)
6558         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6559       else
6560         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6561     }
6562 }
6563
6564 /*!
6565  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6566  *  \param [in] increasing - if \a true, array values should be increasing.
6567  *  \return bool - \a true if values change in accordance with \a increasing arg.
6568  *  \throw If \a this->getNumberOfComponents() != 1.
6569  *  \throw If \a this is not allocated.
6570  */
6571 bool DataArrayInt::isMonotonic(bool increasing) const
6572 {
6573   checkAllocated();
6574   if(getNumberOfComponents()!=1)
6575     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6576   int nbOfElements=getNumberOfTuples();
6577   const int *ptr=getConstPointer();
6578   if(nbOfElements==0)
6579     return true;
6580   int ref=ptr[0];
6581   if(increasing)
6582     {
6583       for(int i=1;i<nbOfElements;i++)
6584         {
6585           if(ptr[i]>=ref)
6586             ref=ptr[i];
6587           else
6588             return false;
6589         }
6590     }
6591   else
6592     {
6593       for(int i=1;i<nbOfElements;i++)
6594         {
6595           if(ptr[i]<=ref)
6596             ref=ptr[i];
6597           else
6598             return false;
6599         }
6600     }
6601   return true;
6602 }
6603
6604 /*!
6605  * This method check that array consistently INCREASING or DECREASING in value.
6606  */
6607 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6608 {
6609   checkAllocated();
6610   if(getNumberOfComponents()!=1)
6611     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6612   int nbOfElements=getNumberOfTuples();
6613   const int *ptr=getConstPointer();
6614   if(nbOfElements==0)
6615     return true;
6616   int ref=ptr[0];
6617   if(increasing)
6618     {
6619       for(int i=1;i<nbOfElements;i++)
6620         {
6621           if(ptr[i]>ref)
6622             ref=ptr[i];
6623           else
6624             return false;
6625         }
6626     }
6627   else
6628     {
6629       for(int i=1;i<nbOfElements;i++)
6630         {
6631           if(ptr[i]<ref)
6632             ref=ptr[i];
6633           else
6634             return false;
6635         }
6636     }
6637   return true;
6638 }
6639
6640 /*!
6641  * This method check that array consistently INCREASING or DECREASING in value.
6642  */
6643 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6644 {
6645   if(!isStrictlyMonotonic(increasing))
6646     {
6647       if (increasing)
6648         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6649       else
6650         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6651     }
6652 }
6653
6654 /*!
6655  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6656  * one-dimensional arrays that must be of the same length. The result array describes
6657  * correspondence between \a this and \a other arrays, so that 
6658  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6659  * not possible because some element in \a other is not in \a this, an exception is thrown.
6660  *  \param [in] other - an array to compute permutation to.
6661  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6662  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6663  * no more needed.
6664  *  \throw If \a this->getNumberOfComponents() != 1.
6665  *  \throw If \a other->getNumberOfComponents() != 1.
6666  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6667  *  \throw If \a other includes a value which is not in \a this array.
6668  * 
6669  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6670  *
6671  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6672  */
6673 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6674 {
6675   checkAllocated();
6676   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6677     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6678   int nbTuple=getNumberOfTuples();
6679   other.checkAllocated();
6680   if(nbTuple!=other.getNumberOfTuples())
6681     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6682   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6683   ret->alloc(nbTuple,1);
6684   ret->fillWithValue(-1);
6685   const int *pt=getConstPointer();
6686   std::map<int,int> mm;
6687   for(int i=0;i<nbTuple;i++)
6688     mm[pt[i]]=i;
6689   pt=other.getConstPointer();
6690   int *retToFill=ret->getPointer();
6691   for(int i=0;i<nbTuple;i++)
6692     {
6693       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6694       if(it==mm.end())
6695         {
6696           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6697           throw INTERP_KERNEL::Exception(oss.str().c_str());
6698         }
6699       retToFill[i]=(*it).second;
6700     }
6701   return ret.retn();
6702 }
6703
6704 /*!
6705  * Sets a C array to be used as raw data of \a this. The previously set info
6706  *  of components is retained and re-sized. 
6707  * For more info see \ref MEDCouplingArraySteps1.
6708  *  \param [in] array - the C array to be used as raw data of \a this.
6709  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6710  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6711  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6712  *                     \c free(\c array ) will be called.
6713  *  \param [in] nbOfTuple - new number of tuples in \a this.
6714  *  \param [in] nbOfCompo - new number of components in \a this.
6715  */
6716 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6717 {
6718   _info_on_compo.resize(nbOfCompo);
6719   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6720   declareAsNew();
6721 }
6722
6723 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6724 {
6725   _info_on_compo.resize(nbOfCompo);
6726   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6727   declareAsNew();
6728 }
6729
6730 /*!
6731  * Returns a new DataArrayInt holding the same values as \a this array but differently
6732  * arranged in memory. If \a this array holds 2 components of 3 values:
6733  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6734  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6735  *  \warning Do not confuse this method with transpose()!
6736  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6737  *          is to delete using decrRef() as it is no more needed.
6738  *  \throw If \a this is not allocated.
6739  */
6740 DataArrayInt *DataArrayInt::fromNoInterlace() const
6741 {
6742   checkAllocated();
6743   if(_mem.isNull())
6744     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6745   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6746   DataArrayInt *ret=DataArrayInt::New();
6747   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6748   return ret;
6749 }
6750
6751 /*!
6752  * Returns a new DataArrayInt holding the same values as \a this array but differently
6753  * arranged in memory. If \a this array holds 2 components of 3 values:
6754  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6755  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6756  *  \warning Do not confuse this method with transpose()!
6757  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6758  *          is to delete using decrRef() as it is no more needed.
6759  *  \throw If \a this is not allocated.
6760  */
6761 DataArrayInt *DataArrayInt::toNoInterlace() const
6762 {
6763   checkAllocated();
6764   if(_mem.isNull())
6765     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6766   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6767   DataArrayInt *ret=DataArrayInt::New();
6768   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6769   return ret;
6770 }
6771
6772 /*!
6773  * Permutes values of \a this array as required by \a old2New array. The values are
6774  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6775  * the same as in \this one.
6776  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6777  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6778  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6779  *     giving a new position for i-th old value.
6780  */
6781 void DataArrayInt::renumberInPlace(const int *old2New)
6782 {
6783   checkAllocated();
6784   int nbTuples=getNumberOfTuples();
6785   int nbOfCompo=getNumberOfComponents();
6786   int *tmp=new int[nbTuples*nbOfCompo];
6787   const int *iptr=getConstPointer();
6788   for(int i=0;i<nbTuples;i++)
6789     {
6790       int v=old2New[i];
6791       if(v>=0 && v<nbTuples)
6792         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6793       else
6794         {
6795           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6796           throw INTERP_KERNEL::Exception(oss.str().c_str());
6797         }
6798     }
6799   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6800   delete [] tmp;
6801   declareAsNew();
6802 }
6803
6804 /*!
6805  * Permutes values of \a this array as required by \a new2Old array. The values are
6806  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6807  * the same as in \this one.
6808  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6809  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6810  *     giving a previous position of i-th new value.
6811  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6812  *          is to delete using decrRef() as it is no more needed.
6813  */
6814 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6815 {
6816   checkAllocated();
6817   int nbTuples=getNumberOfTuples();
6818   int nbOfCompo=getNumberOfComponents();
6819   int *tmp=new int[nbTuples*nbOfCompo];
6820   const int *iptr=getConstPointer();
6821   for(int i=0;i<nbTuples;i++)
6822     {
6823       int v=new2Old[i];
6824       if(v>=0 && v<nbTuples)
6825         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6826       else
6827         {
6828           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6829           throw INTERP_KERNEL::Exception(oss.str().c_str());
6830         }
6831     }
6832   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6833   delete [] tmp;
6834   declareAsNew();
6835 }
6836
6837 /*!
6838  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6839  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6840  * Number of tuples in the result array remains the same as in \this one.
6841  * If a permutation reduction is needed, renumberAndReduce() should be used.
6842  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6843  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6844  *          giving a new position for i-th old value.
6845  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6846  *          is to delete using decrRef() as it is no more needed.
6847  *  \throw If \a this is not allocated.
6848  */
6849 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6850 {
6851   checkAllocated();
6852   int nbTuples=getNumberOfTuples();
6853   int nbOfCompo=getNumberOfComponents();
6854   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6855   ret->alloc(nbTuples,nbOfCompo);
6856   ret->copyStringInfoFrom(*this);
6857   const int *iptr=getConstPointer();
6858   int *optr=ret->getPointer();
6859   for(int i=0;i<nbTuples;i++)
6860     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6861   ret->copyStringInfoFrom(*this);
6862   return ret.retn();
6863 }
6864
6865 /*!
6866  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6867  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6868  * tuples in the result array remains the same as in \this one.
6869  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6870  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6871  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6872  *     giving a previous position of i-th new value.
6873  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6874  *          is to delete using decrRef() as it is no more needed.
6875  */
6876 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6877 {
6878   checkAllocated();
6879   int nbTuples=getNumberOfTuples();
6880   int nbOfCompo=getNumberOfComponents();
6881   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6882   ret->alloc(nbTuples,nbOfCompo);
6883   ret->copyStringInfoFrom(*this);
6884   const int *iptr=getConstPointer();
6885   int *optr=ret->getPointer();
6886   for(int i=0;i<nbTuples;i++)
6887     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6888   ret->copyStringInfoFrom(*this);
6889   return ret.retn();
6890 }
6891
6892 /*!
6893  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6894  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6895  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6896  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6897  * \a old2New[ i ] is negative, is missing from the result array.
6898  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6899  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6900  *     giving a new position for i-th old tuple and giving negative position for
6901  *     for i-th old tuple that should be omitted.
6902  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6903  *          is to delete using decrRef() as it is no more needed.
6904  */
6905 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6906 {
6907   checkAllocated();
6908   int nbTuples=getNumberOfTuples();
6909   int nbOfCompo=getNumberOfComponents();
6910   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6911   ret->alloc(newNbOfTuple,nbOfCompo);
6912   const int *iptr=getConstPointer();
6913   int *optr=ret->getPointer();
6914   for(int i=0;i<nbTuples;i++)
6915     {
6916       int w=old2New[i];
6917       if(w>=0)
6918         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6919     }
6920   ret->copyStringInfoFrom(*this);
6921   return ret.retn();
6922 }
6923
6924 /*!
6925  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6926  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6927  * \a new2OldBg array.
6928  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6929  * This method is equivalent to renumberAndReduce() except that convention in input is
6930  * \c new2old and \b not \c old2new.
6931  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6932  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6933  *              tuple index in \a this array to fill the i-th tuple in the new array.
6934  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6935  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6936  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6937  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6938  *          is to delete using decrRef() as it is no more needed.
6939  */
6940 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6941 {
6942   checkAllocated();
6943   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6944   int nbComp=getNumberOfComponents();
6945   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6946   ret->copyStringInfoFrom(*this);
6947   int *pt=ret->getPointer();
6948   const int *srcPt=getConstPointer();
6949   int i=0;
6950   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6951     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6952   ret->copyStringInfoFrom(*this);
6953   return ret.retn();
6954 }
6955
6956 /*!
6957  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6958  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6959  * \a new2OldBg array.
6960  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6961  * This method is equivalent to renumberAndReduce() except that convention in input is
6962  * \c new2old and \b not \c old2new.
6963  * This method is equivalent to selectByTupleId() except that it prevents coping data
6964  * from behind the end of \a this array.
6965  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6966  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6967  *              tuple index in \a this array to fill the i-th tuple in the new array.
6968  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6969  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6970  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6971  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6972  *          is to delete using decrRef() as it is no more needed.
6973  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6974  */
6975 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
6976 {
6977   checkAllocated();
6978   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6979   int nbComp=getNumberOfComponents();
6980   int oldNbOfTuples=getNumberOfTuples();
6981   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6982   ret->copyStringInfoFrom(*this);
6983   int *pt=ret->getPointer();
6984   const int *srcPt=getConstPointer();
6985   int i=0;
6986   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6987     if(*w>=0 && *w<oldNbOfTuples)
6988       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6989     else
6990       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6991   ret->copyStringInfoFrom(*this);
6992   return ret.retn();
6993 }
6994
6995 /*!
6996  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6997  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6998  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6999  * command \c range( \a bg, \a end2, \a step ).
7000  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7001  * not constructed explicitly.
7002  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7003  *  \param [in] bg - index of the first tuple to copy from \a this array.
7004  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7005  *  \param [in] step - index increment to get index of the next tuple to copy.
7006  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7007  *          is to delete using decrRef() as it is no more needed.
7008  *  \sa DataArrayInt::substr.
7009  */
7010 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7011 {
7012   checkAllocated();
7013   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7014   int nbComp=getNumberOfComponents();
7015   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7016   ret->alloc(newNbOfTuples,nbComp);
7017   int *pt=ret->getPointer();
7018   const int *srcPt=getConstPointer()+bg*nbComp;
7019   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7020     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7021   ret->copyStringInfoFrom(*this);
7022   return ret.retn();
7023 }
7024
7025 /*!
7026  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7027  * of tuples specified by \a ranges parameter.
7028  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7029  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7030  *              of tuples in [\c begin,\c end) format.
7031  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7032  *          is to delete using decrRef() as it is no more needed.
7033  *  \throw If \a end < \a begin.
7034  *  \throw If \a end > \a this->getNumberOfTuples().
7035  *  \throw If \a this is not allocated.
7036  */
7037 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7038 {
7039   checkAllocated();
7040   int nbOfComp=getNumberOfComponents();
7041   int nbOfTuplesThis=getNumberOfTuples();
7042   if(ranges.empty())
7043     {
7044       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7045       ret->alloc(0,nbOfComp);
7046       ret->copyStringInfoFrom(*this);
7047       return ret.retn();
7048     }
7049   int ref=ranges.front().first;
7050   int nbOfTuples=0;
7051   bool isIncreasing=true;
7052   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7053     {
7054       if((*it).first<=(*it).second)
7055         {
7056           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7057             {
7058               nbOfTuples+=(*it).second-(*it).first;
7059               if(isIncreasing)
7060                 isIncreasing=ref<=(*it).first;
7061               ref=(*it).second;
7062             }
7063           else
7064             {
7065               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7066               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7067               throw INTERP_KERNEL::Exception(oss.str().c_str());
7068             }
7069         }
7070       else
7071         {
7072           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7073           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7074           throw INTERP_KERNEL::Exception(oss.str().c_str());
7075         }
7076     }
7077   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7078     return deepCpy();
7079   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7080   ret->alloc(nbOfTuples,nbOfComp);
7081   ret->copyStringInfoFrom(*this);
7082   const int *src=getConstPointer();
7083   int *work=ret->getPointer();
7084   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7085     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7086   return ret.retn();
7087 }
7088
7089 /*!
7090  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7091  * This map, if applied to \a this array, would make it sorted. For example, if
7092  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7093  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7094  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7095  * This method is useful for renumbering (in MED file for example). For more info
7096  * on renumbering see \ref MEDCouplingArrayRenumbering.
7097  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7098  *          array using decrRef() as it is no more needed.
7099  *  \throw If \a this is not allocated.
7100  *  \throw If \a this->getNumberOfComponents() != 1.
7101  *  \throw If there are equal values in \a this array.
7102  */
7103 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7104 {
7105   checkAllocated();
7106   if(getNumberOfComponents()!=1)
7107     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7108   int nbTuples=getNumberOfTuples();
7109   const int *pt=getConstPointer();
7110   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7111   DataArrayInt *ret=DataArrayInt::New();
7112   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7113   return ret;
7114 }
7115
7116 /*!
7117  * 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
7118  * input array \a ids2.
7119  * \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.
7120  * 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
7121  * inversely.
7122  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7123  *
7124  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7125  *          array using decrRef() as it is no more needed.
7126  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7127  * 
7128  */
7129 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7130 {
7131   if(!ids1 || !ids2)
7132     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7133   if(!ids1->isAllocated() || !ids2->isAllocated())
7134     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7135   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7136     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7137   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7138     {
7139       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 !";
7140       throw INTERP_KERNEL::Exception(oss.str().c_str());
7141     }
7142   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7143   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7144   p1->sort(true); p2->sort(true);
7145   if(!p1->isEqualWithoutConsideringStr(*p2))
7146     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7147   p1=ids1->checkAndPreparePermutation();
7148   p2=ids2->checkAndPreparePermutation();
7149   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7150   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7151   return p2.retn();
7152 }
7153
7154 /*!
7155  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7156  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7157  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7158  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7159  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7160  * The first of out arrays returns indices of elements of \a this array, grouped by their
7161  * place in the set \a B. The second out array is the index of the first one; it shows how
7162  * many elements of \a A are mapped into each element of \a B. <br>
7163  * For more info on
7164  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7165  * \b Example:
7166  * - \a this: [0,3,2,3,2,2,1,2]
7167  * - \a targetNb: 4
7168  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7169  * - \a arrI: [0,1,2,6,8]
7170  *
7171  * This result means: <br>
7172  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7173  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7174  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7175  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7176  * \a arrI[ 2+1 ]]); <br> etc.
7177  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7178  *         than the maximal value of \a A.
7179  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7180  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7181  *         this array using decrRef() as it is no more needed.
7182  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7183  *         elements of \a this. The caller is to delete this array using decrRef() as it
7184  *         is no more needed.
7185  *  \throw If \a this is not allocated.
7186  *  \throw If \a this->getNumberOfComponents() != 1.
7187  *  \throw If any value in \a this is more or equal to \a targetNb.
7188  */
7189 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7190 {
7191   checkAllocated();
7192   if(getNumberOfComponents()!=1)
7193     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7194   int nbOfTuples=getNumberOfTuples();
7195   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7196   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7197   retI->alloc(targetNb+1,1);
7198   const int *input=getConstPointer();
7199   std::vector< std::vector<int> > tmp(targetNb);
7200   for(int i=0;i<nbOfTuples;i++)
7201     {
7202       int tmp2=input[i];
7203       if(tmp2>=0 && tmp2<targetNb)
7204         tmp[tmp2].push_back(i);
7205       else
7206         {
7207           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7208           throw INTERP_KERNEL::Exception(oss.str().c_str());
7209         }
7210     }
7211   int *retIPtr=retI->getPointer();
7212   *retIPtr=0;
7213   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7214     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7215   if(nbOfTuples!=retI->getIJ(targetNb,0))
7216     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7217   ret->alloc(nbOfTuples,1);
7218   int *retPtr=ret->getPointer();
7219   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7220     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7221   arr=ret.retn();
7222   arrI=retI.retn();
7223 }
7224
7225
7226 /*!
7227  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7228  * from a zip representation of a surjective format (returned e.g. by
7229  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7230  * for example). The result array minimizes the permutation. <br>
7231  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7232  * \b Example: <br>
7233  * - \a nbOfOldTuples: 10 
7234  * - \a arr          : [0,3, 5,7,9]
7235  * - \a arrIBg       : [0,2,5]
7236  * - \a newNbOfTuples: 7
7237  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7238  *
7239  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7240  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7241  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7242  *         (indices of) equal values. Its every element (except the last one) points to
7243  *         the first element of a group of equal values.
7244  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7245  *          arrIBg is \a arrIEnd[ -1 ].
7246  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7247  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7248  *          array using decrRef() as it is no more needed.
7249  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7250  */
7251 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7252 {
7253   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7254   ret->alloc(nbOfOldTuples,1);
7255   int *pt=ret->getPointer();
7256   std::fill(pt,pt+nbOfOldTuples,-1);
7257   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7258   const int *cIPtr=arrIBg;
7259   for(int i=0;i<nbOfGrps;i++)
7260     pt[arr[cIPtr[i]]]=-(i+2);
7261   int newNb=0;
7262   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7263     {
7264       if(pt[iNode]<0)
7265         {
7266           if(pt[iNode]==-1)
7267             pt[iNode]=newNb++;
7268           else
7269             {
7270               int grpId=-(pt[iNode]+2);
7271               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7272                 {
7273                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7274                     pt[arr[j]]=newNb;
7275                   else
7276                     {
7277                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7278                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7279                     }
7280                 }
7281               newNb++;
7282             }
7283         }
7284     }
7285   newNbOfTuples=newNb;
7286   return ret.retn();
7287 }
7288
7289 /*!
7290  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7291  * which if applied to \a this array would make it sorted ascendingly.
7292  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7293  * \b Example: <br>
7294  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7295  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7296  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7297  *
7298  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7299  *          array using decrRef() as it is no more needed.
7300  *  \throw If \a this is not allocated.
7301  *  \throw If \a this->getNumberOfComponents() != 1.
7302  */
7303 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7304 {
7305   checkAllocated();
7306   if(getNumberOfComponents()!=1)
7307     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7308   int nbOfTuples=getNumberOfTuples();
7309   const int *pt=getConstPointer();
7310   std::map<int,int> m;
7311   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7312   ret->alloc(nbOfTuples,1);
7313   int *opt=ret->getPointer();
7314   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7315     {
7316       int val=*pt;
7317       std::map<int,int>::iterator it=m.find(val);
7318       if(it!=m.end())
7319         {
7320           *opt=(*it).second;
7321           (*it).second++;
7322         }
7323       else
7324         {
7325           *opt=0;
7326           m.insert(std::pair<int,int>(val,1));
7327         }
7328     }
7329   int sum=0;
7330   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7331     {
7332       int vt=(*it).second;
7333       (*it).second=sum;
7334       sum+=vt;
7335     }
7336   pt=getConstPointer();
7337   opt=ret->getPointer();
7338   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7339     *opt+=m[*pt];
7340   //
7341   return ret.retn();
7342 }
7343
7344 /*!
7345  * Checks if contents of \a this array are equal to that of an array filled with
7346  * iota(). This method is particularly useful for DataArrayInt instances that represent
7347  * a renumbering array to check the real need in renumbering. 
7348  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7349  *  \throw If \a this is not allocated.
7350  *  \throw If \a this->getNumberOfComponents() != 1.
7351  */
7352 bool DataArrayInt::isIdentity() const
7353 {
7354   checkAllocated();
7355   if(getNumberOfComponents()!=1)
7356     return false;
7357   int nbOfTuples=getNumberOfTuples();
7358   const int *pt=getConstPointer();
7359   for(int i=0;i<nbOfTuples;i++,pt++)
7360     if(*pt!=i)
7361       return false;
7362   return true;
7363 }
7364
7365 /*!
7366  * Checks if all values in \a this array are equal to \a val.
7367  *  \param [in] val - value to check equality of array values to.
7368  *  \return bool - \a true if all values are \a val.
7369  *  \throw If \a this is not allocated.
7370  *  \throw If \a this->getNumberOfComponents() != 1
7371  */
7372 bool DataArrayInt::isUniform(int val) const
7373 {
7374   checkAllocated();
7375   if(getNumberOfComponents()!=1)
7376     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7377   int nbOfTuples=getNumberOfTuples();
7378   const int *w=getConstPointer();
7379   const int *end2=w+nbOfTuples;
7380   for(;w!=end2;w++)
7381     if(*w!=val)
7382       return false;
7383   return true;
7384 }
7385
7386 /*!
7387  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7388  * array to the new one.
7389  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7390  */
7391 DataArrayDouble *DataArrayInt::convertToDblArr() const
7392 {
7393   checkAllocated();
7394   DataArrayDouble *ret=DataArrayDouble::New();
7395   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7396   std::size_t nbOfVals=getNbOfElems();
7397   const int *src=getConstPointer();
7398   double *dest=ret->getPointer();
7399   std::copy(src,src+nbOfVals,dest);
7400   ret->copyStringInfoFrom(*this);
7401   return ret;
7402 }
7403
7404 /*!
7405  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7406  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7407  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7408  * This method is a specialization of selectByTupleId2().
7409  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7410  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7411  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7412  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7413  *          is to delete using decrRef() as it is no more needed.
7414  *  \throw If \a tupleIdBg < 0.
7415  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7416     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7417  *  \sa DataArrayInt::selectByTupleId2
7418  */
7419 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7420 {
7421   checkAllocated();
7422   int nbt=getNumberOfTuples();
7423   if(tupleIdBg<0)
7424     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7425   if(tupleIdBg>nbt)
7426     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7427   int trueEnd=tupleIdEnd;
7428   if(tupleIdEnd!=-1)
7429     {
7430       if(tupleIdEnd>nbt)
7431         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7432     }
7433   else
7434     trueEnd=nbt;
7435   int nbComp=getNumberOfComponents();
7436   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7437   ret->alloc(trueEnd-tupleIdBg,nbComp);
7438   ret->copyStringInfoFrom(*this);
7439   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7440   return ret.retn();
7441 }
7442
7443 /*!
7444  * Changes the number of components within \a this array so that its raw data **does
7445  * not** change, instead splitting this data into tuples changes.
7446  *  \warning This method erases all (name and unit) component info set before!
7447  *  \param [in] newNbOfComp - number of components for \a this array to have.
7448  *  \throw If \a this is not allocated
7449  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7450  *  \throw If \a newNbOfCompo is lower than 1.
7451  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7452  *  \warning This method erases all (name and unit) component info set before!
7453  */
7454 void DataArrayInt::rearrange(int newNbOfCompo)
7455 {
7456   checkAllocated();
7457   if(newNbOfCompo<1)
7458     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7459   std::size_t nbOfElems=getNbOfElems();
7460   if(nbOfElems%newNbOfCompo!=0)
7461     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7462   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7463     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7464   _info_on_compo.clear();
7465   _info_on_compo.resize(newNbOfCompo);
7466   declareAsNew();
7467 }
7468
7469 /*!
7470  * Changes the number of components within \a this array to be equal to its number
7471  * of tuples, and inversely its number of tuples to become equal to its number of 
7472  * components. So that its raw data **does not** change, instead splitting this
7473  * data into tuples changes.
7474  *  \warning This method erases all (name and unit) component info set before!
7475  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7476  *  \throw If \a this is not allocated.
7477  *  \sa rearrange()
7478  */
7479 void DataArrayInt::transpose()
7480 {
7481   checkAllocated();
7482   int nbOfTuples=getNumberOfTuples();
7483   rearrange(nbOfTuples);
7484 }
7485
7486 /*!
7487  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7488  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7489  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7490  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7491  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7492  * components.  
7493  *  \param [in] newNbOfComp - number of components for the new array to have.
7494  *  \param [in] dftValue - value assigned to new values added to the new array.
7495  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7496  *          is to delete using decrRef() as it is no more needed.
7497  *  \throw If \a this is not allocated.
7498  */
7499 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7500 {
7501   checkAllocated();
7502   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7503   ret->alloc(getNumberOfTuples(),newNbOfComp);
7504   const int *oldc=getConstPointer();
7505   int *nc=ret->getPointer();
7506   int nbOfTuples=getNumberOfTuples();
7507   int oldNbOfComp=getNumberOfComponents();
7508   int dim=std::min(oldNbOfComp,newNbOfComp);
7509   for(int i=0;i<nbOfTuples;i++)
7510     {
7511       int j=0;
7512       for(;j<dim;j++)
7513         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7514       for(;j<newNbOfComp;j++)
7515         nc[newNbOfComp*i+j]=dftValue;
7516     }
7517   ret->setName(getName().c_str());
7518   for(int i=0;i<dim;i++)
7519     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7520   ret->setName(getName().c_str());
7521   return ret.retn();
7522 }
7523
7524 /*!
7525  * Changes number of tuples in the array. If the new number of tuples is smaller
7526  * than the current number the array is truncated, otherwise the array is extended.
7527  *  \param [in] nbOfTuples - new number of tuples. 
7528  *  \throw If \a this is not allocated.
7529  *  \throw If \a nbOfTuples is negative.
7530  */
7531 void DataArrayInt::reAlloc(int nbOfTuples)
7532 {
7533   if(nbOfTuples<0)
7534     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7535   checkAllocated();
7536   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7537   declareAsNew();
7538 }
7539
7540
7541 /*!
7542  * Returns a copy of \a this array composed of selected components.
7543  * The new DataArrayInt has the same number of tuples but includes components
7544  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7545  * can be either less, same or more than \a this->getNbOfElems().
7546  *  \param [in] compoIds - sequence of zero based indices of components to include
7547  *              into the new array.
7548  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7549  *          is to delete using decrRef() as it is no more needed.
7550  *  \throw If \a this is not allocated.
7551  *  \throw If a component index (\a i) is not valid: 
7552  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7553  *
7554  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7555  */
7556 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7557 {
7558   checkAllocated();
7559   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7560   int newNbOfCompo=(int)compoIds.size();
7561   int oldNbOfCompo=getNumberOfComponents();
7562   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7563     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7564   int nbOfTuples=getNumberOfTuples();
7565   ret->alloc(nbOfTuples,newNbOfCompo);
7566   ret->copyPartOfStringInfoFrom(*this,compoIds);
7567   const int *oldc=getConstPointer();
7568   int *nc=ret->getPointer();
7569   for(int i=0;i<nbOfTuples;i++)
7570     for(int j=0;j<newNbOfCompo;j++,nc++)
7571       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7572   return ret.retn();
7573 }
7574
7575 /*!
7576  * Appends components of another array to components of \a this one, tuple by tuple.
7577  * So that the number of tuples of \a this array remains the same and the number of 
7578  * components increases.
7579  *  \param [in] other - the DataArrayInt to append to \a this one.
7580  *  \throw If \a this is not allocated.
7581  *  \throw If \a this and \a other arrays have different number of tuples.
7582  *
7583  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7584  *
7585  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7586  */
7587 void DataArrayInt::meldWith(const DataArrayInt *other)
7588 {
7589   if(!other)
7590     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7591   checkAllocated();
7592   other->checkAllocated();
7593   int nbOfTuples=getNumberOfTuples();
7594   if(nbOfTuples!=other->getNumberOfTuples())
7595     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7596   int nbOfComp1=getNumberOfComponents();
7597   int nbOfComp2=other->getNumberOfComponents();
7598   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7599   int *w=newArr;
7600   const int *inp1=getConstPointer();
7601   const int *inp2=other->getConstPointer();
7602   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7603     {
7604       w=std::copy(inp1,inp1+nbOfComp1,w);
7605       w=std::copy(inp2,inp2+nbOfComp2,w);
7606     }
7607   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7608   std::vector<int> compIds(nbOfComp2);
7609   for(int i=0;i<nbOfComp2;i++)
7610     compIds[i]=nbOfComp1+i;
7611   copyPartOfStringInfoFrom2(compIds,*other);
7612 }
7613
7614 /*!
7615  * Copy all components in a specified order from another DataArrayInt.
7616  * The specified components become the first ones in \a this array.
7617  * Both numerical and textual data is copied. The number of tuples in \a this and
7618  * the other array can be different.
7619  *  \param [in] a - the array to copy data from.
7620  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7621  *              to be copied.
7622  *  \throw If \a a is NULL.
7623  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7624  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7625  *
7626  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7627  */
7628 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7629 {
7630   if(!a)
7631     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7632   checkAllocated();
7633   a->checkAllocated();
7634   copyPartOfStringInfoFrom2(compoIds,*a);
7635   std::size_t partOfCompoSz=compoIds.size();
7636   int nbOfCompo=getNumberOfComponents();
7637   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7638   const int *ac=a->getConstPointer();
7639   int *nc=getPointer();
7640   for(int i=0;i<nbOfTuples;i++)
7641     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7642       nc[nbOfCompo*i+compoIds[j]]=*ac;
7643 }
7644
7645 /*!
7646  * Copy all values from another DataArrayInt into specified tuples and components
7647  * of \a this array. Textual data is not copied.
7648  * The tree parameters defining set of indices of tuples and components are similar to
7649  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7650  *  \param [in] a - the array to copy values from.
7651  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7652  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7653  *              are located.
7654  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7655  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7656  *  \param [in] endComp - index of the component before which the components to assign
7657  *              to are located.
7658  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7659  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7660  *              must be equal to the number of columns to assign to, else an
7661  *              exception is thrown; if \a false, then it is only required that \a
7662  *              a->getNbOfElems() equals to number of values to assign to (this condition
7663  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7664  *              values to assign to is given by following Python expression:
7665  *              \a nbTargetValues = 
7666  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7667  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7668  *  \throw If \a a is NULL.
7669  *  \throw If \a a is not allocated.
7670  *  \throw If \a this is not allocated.
7671  *  \throw If parameters specifying tuples and components to assign to do not give a
7672  *            non-empty range of increasing indices.
7673  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7674  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7675  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7676  *
7677  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7678  */
7679 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7680 {
7681   if(!a)
7682     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7683   const char msg[]="DataArrayInt::setPartOfValues1";
7684   checkAllocated();
7685   a->checkAllocated();
7686   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7687   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7688   int nbComp=getNumberOfComponents();
7689   int nbOfTuples=getNumberOfTuples();
7690   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7691   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7692   bool assignTech=true;
7693   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7694     {
7695       if(strictCompoCompare)
7696         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7697     }
7698   else
7699     {
7700       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7701       assignTech=false;
7702     }
7703   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7704   const int *srcPt=a->getConstPointer();
7705   if(assignTech)
7706     {
7707       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7708         for(int j=0;j<newNbOfComp;j++,srcPt++)
7709           pt[j*stepComp]=*srcPt;
7710     }
7711   else
7712     {
7713       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7714         {
7715           const int *srcPt2=srcPt;
7716           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7717             pt[j*stepComp]=*srcPt2;
7718         }
7719     }
7720 }
7721
7722 /*!
7723  * Assign a given value to values at specified tuples and components of \a this array.
7724  * The tree parameters defining set of indices of tuples and components are similar to
7725  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7726  *  \param [in] a - the value to assign.
7727  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7728  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7729  *              are located.
7730  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7731  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7732  *  \param [in] endComp - index of the component before which the components to assign
7733  *              to are located.
7734  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7735  *  \throw If \a this is not allocated.
7736  *  \throw If parameters specifying tuples and components to assign to, do not give a
7737  *            non-empty range of increasing indices or indices are out of a valid range
7738  *            for \this array.
7739  *
7740  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7741  */
7742 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7743 {
7744   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7745   checkAllocated();
7746   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7747   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7748   int nbComp=getNumberOfComponents();
7749   int nbOfTuples=getNumberOfTuples();
7750   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7751   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7752   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7753   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7754     for(int j=0;j<newNbOfComp;j++)
7755       pt[j*stepComp]=a;
7756 }
7757
7758
7759 /*!
7760  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7761  * components of \a this array. Textual data is not copied.
7762  * The tuples and components to assign to are defined by C arrays of indices.
7763  * There are two *modes of usage*:
7764  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7765  *   of \a a is assigned to its own location within \a this array. 
7766  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7767  *   components of every specified tuple of \a this array. In this mode it is required
7768  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7769  * 
7770  *  \param [in] a - the array to copy values from.
7771  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7772  *              assign values of \a a to.
7773  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7774  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7775  *              \a bgTuples <= \a pi < \a endTuples.
7776  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7777  *              assign values of \a a to.
7778  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7779  *              pointer to a component index <em>(pi)</em> varies as this: 
7780  *              \a bgComp <= \a pi < \a endComp.
7781  *  \param [in] strictCompoCompare - this parameter is checked only if the
7782  *               *mode of usage* is the first; if it is \a true (default), 
7783  *               then \a a->getNumberOfComponents() must be equal 
7784  *               to the number of specified columns, else this is not required.
7785  *  \throw If \a a is NULL.
7786  *  \throw If \a a is not allocated.
7787  *  \throw If \a this is not allocated.
7788  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7789  *         out of a valid range for \a this array.
7790  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7791  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7792  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7793  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7794  *
7795  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7796  */
7797 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7798 {
7799   if(!a)
7800     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7801   const char msg[]="DataArrayInt::setPartOfValues2";
7802   checkAllocated();
7803   a->checkAllocated();
7804   int nbComp=getNumberOfComponents();
7805   int nbOfTuples=getNumberOfTuples();
7806   for(const int *z=bgComp;z!=endComp;z++)
7807     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7808   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7809   int newNbOfComp=(int)std::distance(bgComp,endComp);
7810   bool assignTech=true;
7811   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7812     {
7813       if(strictCompoCompare)
7814         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7815     }
7816   else
7817     {
7818       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7819       assignTech=false;
7820     }
7821   int *pt=getPointer();
7822   const int *srcPt=a->getConstPointer();
7823   if(assignTech)
7824     {    
7825       for(const int *w=bgTuples;w!=endTuples;w++)
7826         {
7827           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7828           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7829             {    
7830               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7831             }
7832         }
7833     }
7834   else
7835     {
7836       for(const int *w=bgTuples;w!=endTuples;w++)
7837         {
7838           const int *srcPt2=srcPt;
7839           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7840           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7841             {    
7842               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7843             }
7844         }
7845     }
7846 }
7847
7848 /*!
7849  * Assign a given value to values at specified tuples and components of \a this array.
7850  * The tuples and components to assign to are defined by C arrays of indices.
7851  *  \param [in] a - the value to assign.
7852  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7853  *              assign \a a to.
7854  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7855  *              pointer to a tuple index (\a pi) varies as this: 
7856  *              \a bgTuples <= \a pi < \a endTuples.
7857  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7858  *              assign \a a to.
7859  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7860  *              pointer to a component index (\a pi) varies as this: 
7861  *              \a bgComp <= \a pi < \a endComp.
7862  *  \throw If \a this is not allocated.
7863  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7864  *         out of a valid range for \a this array.
7865  *
7866  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7867  */
7868 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7869 {
7870   checkAllocated();
7871   int nbComp=getNumberOfComponents();
7872   int nbOfTuples=getNumberOfTuples();
7873   for(const int *z=bgComp;z!=endComp;z++)
7874     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7875   int *pt=getPointer();
7876   for(const int *w=bgTuples;w!=endTuples;w++)
7877     for(const int *z=bgComp;z!=endComp;z++)
7878       {
7879         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7880         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7881       }
7882 }
7883
7884 /*!
7885  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7886  * components of \a this array. Textual data is not copied.
7887  * The tuples to assign to are defined by a C array of indices.
7888  * The components to assign to are defined by three values similar to parameters of
7889  * the Python function \c range(\c start,\c stop,\c step).
7890  * There are two *modes of usage*:
7891  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7892  *   of \a a is assigned to its own location within \a this array. 
7893  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7894  *   components of every specified tuple of \a this array. In this mode it is required
7895  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7896  *
7897  *  \param [in] a - the array to copy values from.
7898  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7899  *              assign values of \a a to.
7900  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7901  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7902  *              \a bgTuples <= \a pi < \a endTuples.
7903  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7904  *  \param [in] endComp - index of the component before which the components to assign
7905  *              to are located.
7906  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7907  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7908  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7909  *               then \a a->getNumberOfComponents() must be equal 
7910  *               to the number of specified columns, else this is not required.
7911  *  \throw If \a a is NULL.
7912  *  \throw If \a a is not allocated.
7913  *  \throw If \a this is not allocated.
7914  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7915  *         \a this array.
7916  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7917  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7918  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7919  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7920  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7921  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7922  *  \throw If parameters specifying components to assign to, do not give a
7923  *            non-empty range of increasing indices or indices are out of a valid range
7924  *            for \this array.
7925  *
7926  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7927  */
7928 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7929 {
7930   if(!a)
7931     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7932   const char msg[]="DataArrayInt::setPartOfValues3";
7933   checkAllocated();
7934   a->checkAllocated();
7935   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7936   int nbComp=getNumberOfComponents();
7937   int nbOfTuples=getNumberOfTuples();
7938   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7939   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7940   bool assignTech=true;
7941   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7942     {
7943       if(strictCompoCompare)
7944         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7945     }
7946   else
7947     {
7948       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7949       assignTech=false;
7950     }
7951   int *pt=getPointer()+bgComp;
7952   const int *srcPt=a->getConstPointer();
7953   if(assignTech)
7954     {
7955       for(const int *w=bgTuples;w!=endTuples;w++)
7956         for(int j=0;j<newNbOfComp;j++,srcPt++)
7957           {
7958             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7959             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7960           }
7961     }
7962   else
7963     {
7964       for(const int *w=bgTuples;w!=endTuples;w++)
7965         {
7966           const int *srcPt2=srcPt;
7967           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7968             {
7969               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7970               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7971             }
7972         }
7973     }
7974 }
7975
7976 /*!
7977  * Assign a given value to values at specified tuples and components of \a this array.
7978  * The tuples to assign to are defined by a C array of indices.
7979  * The components to assign to are defined by three values similar to parameters of
7980  * the Python function \c range(\c start,\c stop,\c step).
7981  *  \param [in] a - the value to assign.
7982  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7983  *              assign \a a to.
7984  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7985  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7986  *              \a bgTuples <= \a pi < \a endTuples.
7987  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7988  *  \param [in] endComp - index of the component before which the components to assign
7989  *              to are located.
7990  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7991  *  \throw If \a this is not allocated.
7992  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7993  *         \a this array.
7994  *  \throw If parameters specifying components to assign to, do not give a
7995  *            non-empty range of increasing indices or indices are out of a valid range
7996  *            for \this array.
7997  *
7998  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7999  */
8000 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8001 {
8002   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8003   checkAllocated();
8004   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8005   int nbComp=getNumberOfComponents();
8006   int nbOfTuples=getNumberOfTuples();
8007   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8008   int *pt=getPointer()+bgComp;
8009   for(const int *w=bgTuples;w!=endTuples;w++)
8010     for(int j=0;j<newNbOfComp;j++)
8011       {
8012         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8013         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8014       }
8015 }
8016
8017 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8018 {
8019   if(!a)
8020     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8021   const char msg[]="DataArrayInt::setPartOfValues4";
8022   checkAllocated();
8023   a->checkAllocated();
8024   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8025   int newNbOfComp=(int)std::distance(bgComp,endComp);
8026   int nbComp=getNumberOfComponents();
8027   for(const int *z=bgComp;z!=endComp;z++)
8028     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8029   int nbOfTuples=getNumberOfTuples();
8030   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8031   bool assignTech=true;
8032   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8033     {
8034       if(strictCompoCompare)
8035         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8036     }
8037   else
8038     {
8039       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8040       assignTech=false;
8041     }
8042   const int *srcPt=a->getConstPointer();
8043   int *pt=getPointer()+bgTuples*nbComp;
8044   if(assignTech)
8045     {
8046       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8047         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8048           pt[*z]=*srcPt;
8049     }
8050   else
8051     {
8052       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8053         {
8054           const int *srcPt2=srcPt;
8055           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8056             pt[*z]=*srcPt2;
8057         }
8058     }
8059 }
8060
8061 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8062 {
8063   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8064   checkAllocated();
8065   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8066   int nbComp=getNumberOfComponents();
8067   for(const int *z=bgComp;z!=endComp;z++)
8068     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8069   int nbOfTuples=getNumberOfTuples();
8070   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8071   int *pt=getPointer()+bgTuples*nbComp;
8072   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8073     for(const int *z=bgComp;z!=endComp;z++)
8074       pt[*z]=a;
8075 }
8076
8077 /*!
8078  * Copy some tuples from another DataArrayInt into specified tuples
8079  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8080  * components.
8081  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8082  * All components of selected tuples are copied.
8083  *  \param [in] a - the array to copy values from.
8084  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8085  *              target tuples of \a this. \a tuplesSelec has two components, and the
8086  *              first component specifies index of the source tuple and the second
8087  *              one specifies index of the target tuple.
8088  *  \throw If \a this is not allocated.
8089  *  \throw If \a a is NULL.
8090  *  \throw If \a a is not allocated.
8091  *  \throw If \a tuplesSelec is NULL.
8092  *  \throw If \a tuplesSelec is not allocated.
8093  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8094  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8095  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8096  *         the corresponding (\a this or \a a) array.
8097  */
8098 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8099 {
8100   if(!a || !tuplesSelec)
8101     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8102   checkAllocated();
8103   a->checkAllocated();
8104   tuplesSelec->checkAllocated();
8105   int nbOfComp=getNumberOfComponents();
8106   if(nbOfComp!=a->getNumberOfComponents())
8107     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8108   if(tuplesSelec->getNumberOfComponents()!=2)
8109     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8110   int thisNt=getNumberOfTuples();
8111   int aNt=a->getNumberOfTuples();
8112   int *valsToSet=getPointer();
8113   const int *valsSrc=a->getConstPointer();
8114   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8115     {
8116       if(tuple[1]>=0 && tuple[1]<aNt)
8117         {
8118           if(tuple[0]>=0 && tuple[0]<thisNt)
8119             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8120           else
8121             {
8122               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8123               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8124               throw INTERP_KERNEL::Exception(oss.str().c_str());
8125             }
8126         }
8127       else
8128         {
8129           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8130           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8131           throw INTERP_KERNEL::Exception(oss.str().c_str());
8132         }
8133     }
8134 }
8135
8136 /*!
8137  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8138  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8139  * components.
8140  * The tuples to assign to are defined by index of the first tuple, and
8141  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8142  * The tuples to copy are defined by values of a DataArrayInt.
8143  * All components of selected tuples are copied.
8144  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8145  *              values to.
8146  *  \param [in] aBase - the array to copy values from.
8147  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8148  *  \throw If \a this is not allocated.
8149  *  \throw If \a aBase is NULL.
8150  *  \throw If \a aBase is not allocated.
8151  *  \throw If \a tuplesSelec is NULL.
8152  *  \throw If \a tuplesSelec is not allocated.
8153  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8154  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8155  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8156  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8157  *         \a aBase array.
8158  */
8159 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8160 {
8161   if(!aBase || !tuplesSelec)
8162     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8163   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8164   if(!a)
8165     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8166   checkAllocated();
8167   a->checkAllocated();
8168   tuplesSelec->checkAllocated();
8169   int nbOfComp=getNumberOfComponents();
8170   if(nbOfComp!=a->getNumberOfComponents())
8171     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8172   if(tuplesSelec->getNumberOfComponents()!=1)
8173     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8174   int thisNt=getNumberOfTuples();
8175   int aNt=a->getNumberOfTuples();
8176   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8177   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8178   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8179     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8180   const int *valsSrc=a->getConstPointer();
8181   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8182     {
8183       if(*tuple>=0 && *tuple<aNt)
8184         {
8185           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8186         }
8187       else
8188         {
8189           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8190           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8191           throw INTERP_KERNEL::Exception(oss.str().c_str());
8192         }
8193     }
8194 }
8195
8196 /*!
8197  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8198  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8199  * components.
8200  * The tuples to copy are defined by three values similar to parameters of
8201  * the Python function \c range(\c start,\c stop,\c step).
8202  * The tuples to assign to are defined by index of the first tuple, and
8203  * their number is defined by number of tuples to copy.
8204  * All components of selected tuples are copied.
8205  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8206  *              values to.
8207  *  \param [in] aBase - the array to copy values from.
8208  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8209  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8210  *              are located.
8211  *  \param [in] step - index increment to get index of the next tuple to copy.
8212  *  \throw If \a this is not allocated.
8213  *  \throw If \a aBase is NULL.
8214  *  \throw If \a aBase is not allocated.
8215  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8216  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8217  *  \throw If parameters specifying tuples to copy, do not give a
8218  *            non-empty range of increasing indices or indices are out of a valid range
8219  *            for the array \a aBase.
8220  */
8221 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8222 {
8223   if(!aBase)
8224     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8225   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8226   if(!a)
8227     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8228   checkAllocated();
8229   a->checkAllocated();
8230   int nbOfComp=getNumberOfComponents();
8231   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8232   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8233   if(nbOfComp!=a->getNumberOfComponents())
8234     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8235   int thisNt=getNumberOfTuples();
8236   int aNt=a->getNumberOfTuples();
8237   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8238   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8239     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8240   if(end2>aNt)
8241     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8242   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8243   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8244     {
8245       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8246     }
8247 }
8248
8249 /*!
8250  * Returns a value located at specified tuple and component.
8251  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8252  * parameters is checked. So this method is safe but expensive if used to go through
8253  * all values of \a this.
8254  *  \param [in] tupleId - index of tuple of interest.
8255  *  \param [in] compoId - index of component of interest.
8256  *  \return double - value located by \a tupleId and \a compoId.
8257  *  \throw If \a this is not allocated.
8258  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8259  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8260  */
8261 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8262 {
8263   checkAllocated();
8264   if(tupleId<0 || tupleId>=getNumberOfTuples())
8265     {
8266       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8267       throw INTERP_KERNEL::Exception(oss.str().c_str());
8268     }
8269   if(compoId<0 || compoId>=getNumberOfComponents())
8270     {
8271       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8272       throw INTERP_KERNEL::Exception(oss.str().c_str());
8273     }
8274   return _mem[tupleId*_info_on_compo.size()+compoId];
8275 }
8276
8277 /*!
8278  * Returns the first value of \a this. 
8279  *  \return int - the last value of \a this array.
8280  *  \throw If \a this is not allocated.
8281  *  \throw If \a this->getNumberOfComponents() != 1.
8282  *  \throw If \a this->getNumberOfTuples() < 1.
8283  */
8284 int DataArrayInt::front() const
8285 {
8286   checkAllocated();
8287   if(getNumberOfComponents()!=1)
8288     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8289   int nbOfTuples=getNumberOfTuples();
8290   if(nbOfTuples<1)
8291     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8292   return *(getConstPointer());
8293 }
8294
8295 /*!
8296  * Returns the last value of \a this. 
8297  *  \return int - the last value of \a this array.
8298  *  \throw If \a this is not allocated.
8299  *  \throw If \a this->getNumberOfComponents() != 1.
8300  *  \throw If \a this->getNumberOfTuples() < 1.
8301  */
8302 int DataArrayInt::back() const
8303 {
8304   checkAllocated();
8305   if(getNumberOfComponents()!=1)
8306     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8307   int nbOfTuples=getNumberOfTuples();
8308   if(nbOfTuples<1)
8309     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8310   return *(getConstPointer()+nbOfTuples-1);
8311 }
8312
8313 /*!
8314  * Assign pointer to one array to a pointer to another appay. Reference counter of
8315  * \a arrayToSet is incremented / decremented.
8316  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8317  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8318  */
8319 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8320 {
8321   if(newArray!=arrayToSet)
8322     {
8323       if(arrayToSet)
8324         arrayToSet->decrRef();
8325       arrayToSet=newArray;
8326       if(arrayToSet)
8327         arrayToSet->incrRef();
8328     }
8329 }
8330
8331 DataArrayIntIterator *DataArrayInt::iterator()
8332 {
8333   return new DataArrayIntIterator(this);
8334 }
8335
8336 /*!
8337  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8338  * given one.
8339  *  \param [in] val - the value to find within \a this.
8340  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8341  *          array using decrRef() as it is no more needed.
8342  *  \throw If \a this is not allocated.
8343  *  \throw If \a this->getNumberOfComponents() != 1.
8344  */
8345 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8346 {
8347   checkAllocated();
8348   if(getNumberOfComponents()!=1)
8349     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8350   const int *cptr=getConstPointer();
8351   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8352   int nbOfTuples=getNumberOfTuples();
8353   for(int i=0;i<nbOfTuples;i++,cptr++)
8354     if(*cptr==val)
8355       ret->pushBackSilent(i);
8356   return ret.retn();
8357 }
8358
8359 /*!
8360  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8361  * equal to a given one. 
8362  *  \param [in] val - the value to ignore within \a this.
8363  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8364  *          array using decrRef() as it is no more needed.
8365  *  \throw If \a this is not allocated.
8366  *  \throw If \a this->getNumberOfComponents() != 1.
8367  */
8368 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8369 {
8370   checkAllocated();
8371   if(getNumberOfComponents()!=1)
8372     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8373   const int *cptr=getConstPointer();
8374   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8375   int nbOfTuples=getNumberOfTuples();
8376   for(int i=0;i<nbOfTuples;i++,cptr++)
8377     if(*cptr!=val)
8378       ret->pushBackSilent(i);
8379   return ret.retn();
8380 }
8381
8382
8383 /*!
8384  * Assigns \a newValue to all elements holding \a oldValue within \a this
8385  * one-dimensional array.
8386  *  \param [in] oldValue - the value to replace.
8387  *  \param [in] newValue - the value to assign.
8388  *  \return int - number of replacements performed.
8389  *  \throw If \a this is not allocated.
8390  *  \throw If \a this->getNumberOfComponents() != 1.
8391  */
8392 int DataArrayInt::changeValue(int oldValue, int newValue)
8393 {
8394   checkAllocated();
8395   if(getNumberOfComponents()!=1)
8396     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8397   int *start=getPointer();
8398   int *end2=start+getNbOfElems();
8399   int ret=0;
8400   for(int *val=start;val!=end2;val++)
8401     {
8402       if(*val==oldValue)
8403         {
8404           *val=newValue;
8405           ret++;
8406         }
8407     }
8408   return ret;
8409 }
8410
8411 /*!
8412  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8413  * one of given values.
8414  *  \param [in] valsBg - an array of values to find within \a this array.
8415  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8416  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8417  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8418  *          array using decrRef() as it is no more needed.
8419  *  \throw If \a this->getNumberOfComponents() != 1.
8420  */
8421 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8422 {
8423   if(getNumberOfComponents()!=1)
8424     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8425   std::set<int> vals2(valsBg,valsEnd);
8426   const int *cptr=getConstPointer();
8427   std::vector<int> res;
8428   int nbOfTuples=getNumberOfTuples();
8429   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8430   for(int i=0;i<nbOfTuples;i++,cptr++)
8431     if(vals2.find(*cptr)!=vals2.end())
8432       ret->pushBackSilent(i);
8433   return ret.retn();
8434 }
8435
8436 /*!
8437  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8438  * equal to any of given values.
8439  *  \param [in] valsBg - an array of values to ignore within \a this array.
8440  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8441  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8442  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8443  *          array using decrRef() as it is no more needed.
8444  *  \throw If \a this->getNumberOfComponents() != 1.
8445  */
8446 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8447 {
8448   if(getNumberOfComponents()!=1)
8449     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8450   std::set<int> vals2(valsBg,valsEnd);
8451   const int *cptr=getConstPointer();
8452   std::vector<int> res;
8453   int nbOfTuples=getNumberOfTuples();
8454   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8455   for(int i=0;i<nbOfTuples;i++,cptr++)
8456     if(vals2.find(*cptr)==vals2.end())
8457       ret->pushBackSilent(i);
8458   return ret.retn();
8459 }
8460
8461 /*!
8462  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8463  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8464  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8465  * If any the tuple id is returned. If not -1 is returned.
8466  * 
8467  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8468  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8469  *
8470  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8471  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8472  */
8473 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8474 {
8475   checkAllocated();
8476   int nbOfCompo=getNumberOfComponents();
8477   if(nbOfCompo==0)
8478     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8479   if(nbOfCompo!=(int)tupl.size())
8480     {
8481       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8482       throw INTERP_KERNEL::Exception(oss.str().c_str());
8483     }
8484   const int *cptr=getConstPointer();
8485   std::size_t nbOfVals=getNbOfElems();
8486   for(const int *work=cptr;work!=cptr+nbOfVals;)
8487     {
8488       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8489       if(work!=cptr+nbOfVals)
8490         {
8491           if(std::distance(cptr,work)%nbOfCompo!=0)
8492             work++;
8493           else
8494             return std::distance(cptr,work)/nbOfCompo;
8495         }
8496     }
8497   return -1;
8498 }
8499
8500 /*!
8501  * This method searches the sequence specified in input parameter \b vals in \b this.
8502  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8503  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8504  * \sa DataArrayInt::locateTuple
8505  */
8506 int DataArrayInt::search(const std::vector<int>& vals) const
8507 {
8508   checkAllocated();
8509   int nbOfCompo=getNumberOfComponents();
8510   if(nbOfCompo!=1)
8511     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8512   const int *cptr=getConstPointer();
8513   std::size_t nbOfVals=getNbOfElems();
8514   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8515   if(loc!=cptr+nbOfVals)
8516     return std::distance(cptr,loc);
8517   return -1;
8518 }
8519
8520 /*!
8521  * This method expects to be called when number of components of this is equal to one.
8522  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8523  * If not any tuple contains \b value -1 is returned.
8524  * \sa DataArrayInt::presenceOfValue
8525  */
8526 int DataArrayInt::locateValue(int value) const
8527 {
8528   checkAllocated();
8529   if(getNumberOfComponents()!=1)
8530     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8531   const int *cptr=getConstPointer();
8532   int nbOfTuples=getNumberOfTuples();
8533   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8534   if(ret!=cptr+nbOfTuples)
8535     return std::distance(cptr,ret);
8536   return -1;
8537 }
8538
8539 /*!
8540  * This method expects to be called when number of components of this is equal to one.
8541  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8542  * If not any tuple contains one of the values contained in 'vals' false is returned.
8543  * \sa DataArrayInt::presenceOfValue
8544  */
8545 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8546 {
8547   checkAllocated();
8548   if(getNumberOfComponents()!=1)
8549     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8550   std::set<int> vals2(vals.begin(),vals.end());
8551   const int *cptr=getConstPointer();
8552   int nbOfTuples=getNumberOfTuples();
8553   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8554     if(vals2.find(*w)!=vals2.end())
8555       return std::distance(cptr,w);
8556   return -1;
8557 }
8558
8559 /*!
8560  * This method returns the number of values in \a this that are equals to input parameter \a value.
8561  * This method only works for single component array.
8562  *
8563  * \return a value in [ 0, \c this->getNumberOfTuples() )
8564  *
8565  * \throw If \a this is not allocated
8566  *
8567  */
8568 int DataArrayInt::count(int value) const
8569 {
8570   int ret=0;
8571   checkAllocated();
8572   if(getNumberOfComponents()!=1)
8573     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8574   const int *vals=begin();
8575   int nbOfTuples=getNumberOfTuples();
8576   for(int i=0;i<nbOfTuples;i++,vals++)
8577     if(*vals==value)
8578       ret++;
8579   return ret;
8580 }
8581
8582 /*!
8583  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8584  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8585  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8586  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8587  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8588  * \sa DataArrayInt::locateTuple
8589  */
8590 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8591 {
8592   return locateTuple(tupl)!=-1;
8593 }
8594
8595
8596 /*!
8597  * Returns \a true if a given value is present within \a this one-dimensional array.
8598  *  \param [in] value - the value to find within \a this array.
8599  *  \return bool - \a true in case if \a value is present within \a this array.
8600  *  \throw If \a this is not allocated.
8601  *  \throw If \a this->getNumberOfComponents() != 1.
8602  *  \sa locateValue()
8603  */
8604 bool DataArrayInt::presenceOfValue(int value) const
8605 {
8606   return locateValue(value)!=-1;
8607 }
8608
8609 /*!
8610  * This method expects to be called when number of components of this is equal to one.
8611  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8612  * If not any tuple contains one of the values contained in 'vals' false is returned.
8613  * \sa DataArrayInt::locateValue
8614  */
8615 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8616 {
8617   return locateValue(vals)!=-1;
8618 }
8619
8620 /*!
8621  * Accumulates values of each component of \a this array.
8622  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8623  *         by the caller, that is filled by this method with sum value for each
8624  *         component.
8625  *  \throw If \a this is not allocated.
8626  */
8627 void DataArrayInt::accumulate(int *res) const
8628 {
8629   checkAllocated();
8630   const int *ptr=getConstPointer();
8631   int nbTuple=getNumberOfTuples();
8632   int nbComps=getNumberOfComponents();
8633   std::fill(res,res+nbComps,0);
8634   for(int i=0;i<nbTuple;i++)
8635     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8636 }
8637
8638 int DataArrayInt::accumulate(int compId) const
8639 {
8640   checkAllocated();
8641   const int *ptr=getConstPointer();
8642   int nbTuple=getNumberOfTuples();
8643   int nbComps=getNumberOfComponents();
8644   if(compId<0 || compId>=nbComps)
8645     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8646   int ret=0;
8647   for(int i=0;i<nbTuple;i++)
8648     ret+=ptr[i*nbComps+compId];
8649   return ret;
8650 }
8651
8652 /*!
8653  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8654  * The returned array will have same number of components than \a this and number of tuples equal to
8655  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8656  *
8657  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8658  *
8659  * \param [in] bgOfIndex - begin (included) of the input index array.
8660  * \param [in] endOfIndex - end (excluded) of the input index array.
8661  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8662  * 
8663  * \throw If bgOfIndex or end is NULL.
8664  * \throw If input index array is not ascendingly sorted.
8665  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8666  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8667  */
8668 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8669 {
8670   if(!bgOfIndex || !endOfIndex)
8671     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8672   checkAllocated();
8673   int nbCompo=getNumberOfComponents();
8674   int nbOfTuples=getNumberOfTuples();
8675   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8676   if(sz<1)
8677     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8678   sz--;
8679   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8680   const int *w=bgOfIndex;
8681   if(*w<0 || *w>=nbOfTuples)
8682     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8683   const int *srcPt=begin()+(*w)*nbCompo;
8684   int *tmp=ret->getPointer();
8685   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8686     {
8687       std::fill(tmp,tmp+nbCompo,0);
8688       if(w[1]>=w[0])
8689         {
8690           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8691             {
8692               if(j>=0 && j<nbOfTuples)
8693                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8694               else
8695                 {
8696                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8697                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8698                 }
8699             }
8700         }
8701       else
8702         {
8703           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8704           throw INTERP_KERNEL::Exception(oss.str().c_str());
8705         }
8706     }
8707   ret->copyStringInfoFrom(*this);
8708   return ret.retn();
8709 }
8710
8711 /*!
8712  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8713  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8714  * offsetA2</em> and (2)
8715  * the number of component in the result array is same as that of each of given arrays.
8716  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8717  * Info on components is copied from the first of the given arrays. Number of components
8718  * in the given arrays must be the same.
8719  *  \param [in] a1 - an array to include in the result array.
8720  *  \param [in] a2 - another array to include in the result array.
8721  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8722  *  \return DataArrayInt * - the new instance of DataArrayInt.
8723  *          The caller is to delete this result array using decrRef() as it is no more
8724  *          needed.
8725  *  \throw If either \a a1 or \a a2 is NULL.
8726  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8727  */
8728 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8729 {
8730   if(!a1 || !a2)
8731     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8732   int nbOfComp=a1->getNumberOfComponents();
8733   if(nbOfComp!=a2->getNumberOfComponents())
8734     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8735   int nbOfTuple1=a1->getNumberOfTuples();
8736   int nbOfTuple2=a2->getNumberOfTuples();
8737   DataArrayInt *ret=DataArrayInt::New();
8738   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8739   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8740   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8741   ret->copyStringInfoFrom(*a1);
8742   return ret;
8743 }
8744
8745 /*!
8746  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8747  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8748  * the number of component in the result array is same as that of each of given arrays.
8749  * Info on components is copied from the first of the given arrays. Number of components
8750  * in the given arrays must be  the same.
8751  *  \param [in] arr - a sequence of arrays to include in the result array.
8752  *  \return DataArrayInt * - the new instance of DataArrayInt.
8753  *          The caller is to delete this result array using decrRef() as it is no more
8754  *          needed.
8755  *  \throw If all arrays within \a arr are NULL.
8756  *  \throw If getNumberOfComponents() of arrays within \a arr.
8757  */
8758 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8759 {
8760   std::vector<const DataArrayInt *> a;
8761   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8762     if(*it4)
8763       a.push_back(*it4);
8764   if(a.empty())
8765     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8766   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8767   int nbOfComp=(*it)->getNumberOfComponents();
8768   int nbt=(*it++)->getNumberOfTuples();
8769   for(int i=1;it!=a.end();it++,i++)
8770     {
8771       if((*it)->getNumberOfComponents()!=nbOfComp)
8772         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8773       nbt+=(*it)->getNumberOfTuples();
8774     }
8775   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8776   ret->alloc(nbt,nbOfComp);
8777   int *pt=ret->getPointer();
8778   for(it=a.begin();it!=a.end();it++)
8779     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8780   ret->copyStringInfoFrom(*(a[0]));
8781   return ret.retn();
8782 }
8783
8784 /*!
8785  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8786  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8787  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8788  * 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.
8789  * 
8790  * \return DataArrayInt * - a new object to be managed by the caller.
8791  */
8792 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8793 {
8794   int retSz=1;
8795   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8796     {
8797       if(*it4)
8798         {
8799           (*it4)->checkAllocated();
8800           if((*it4)->getNumberOfComponents()!=1)
8801             {
8802               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8803               throw INTERP_KERNEL::Exception(oss.str().c_str());
8804             }
8805           int nbTupl=(*it4)->getNumberOfTuples();
8806           if(nbTupl<1)
8807             {
8808               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8809               throw INTERP_KERNEL::Exception(oss.str().c_str());
8810             }
8811           if((*it4)->front()!=0)
8812             {
8813               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8814               throw INTERP_KERNEL::Exception(oss.str().c_str());
8815             }
8816           retSz+=nbTupl-1;
8817         }
8818       else
8819         {
8820           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8821           throw INTERP_KERNEL::Exception(oss.str().c_str());
8822         }
8823     }
8824   if(arrs.empty())
8825     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8826   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8827   ret->alloc(retSz,1);
8828   int *pt=ret->getPointer(); *pt++=0;
8829   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8830     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8831   ret->copyStringInfoFrom(*(arrs[0]));
8832   return ret.retn();
8833 }
8834
8835 /*!
8836  * Returns the maximal value and its location within \a this one-dimensional array.
8837  *  \param [out] tupleId - index of the tuple holding the maximal value.
8838  *  \return int - the maximal value among all values of \a this array.
8839  *  \throw If \a this->getNumberOfComponents() != 1
8840  *  \throw If \a this->getNumberOfTuples() < 1
8841  */
8842 int DataArrayInt::getMaxValue(int& tupleId) const
8843 {
8844   checkAllocated();
8845   if(getNumberOfComponents()!=1)
8846     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8847   int nbOfTuples=getNumberOfTuples();
8848   if(nbOfTuples<=0)
8849     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8850   const int *vals=getConstPointer();
8851   const int *loc=std::max_element(vals,vals+nbOfTuples);
8852   tupleId=(int)std::distance(vals,loc);
8853   return *loc;
8854 }
8855
8856 /*!
8857  * Returns the maximal value within \a this array that is allowed to have more than
8858  *  one component.
8859  *  \return int - the maximal value among all values of \a this array.
8860  *  \throw If \a this is not allocated.
8861  */
8862 int DataArrayInt::getMaxValueInArray() const
8863 {
8864   checkAllocated();
8865   const int *loc=std::max_element(begin(),end());
8866   return *loc;
8867 }
8868
8869 /*!
8870  * Returns the minimal value and its location within \a this one-dimensional array.
8871  *  \param [out] tupleId - index of the tuple holding the minimal value.
8872  *  \return int - the minimal value among all values of \a this array.
8873  *  \throw If \a this->getNumberOfComponents() != 1
8874  *  \throw If \a this->getNumberOfTuples() < 1
8875  */
8876 int DataArrayInt::getMinValue(int& tupleId) const
8877 {
8878   checkAllocated();
8879   if(getNumberOfComponents()!=1)
8880     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8881   int nbOfTuples=getNumberOfTuples();
8882   if(nbOfTuples<=0)
8883     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8884   const int *vals=getConstPointer();
8885   const int *loc=std::min_element(vals,vals+nbOfTuples);
8886   tupleId=(int)std::distance(vals,loc);
8887   return *loc;
8888 }
8889
8890 /*!
8891  * Returns the minimal value within \a this array that is allowed to have more than
8892  *  one component.
8893  *  \return int - the minimal value among all values of \a this array.
8894  *  \throw If \a this is not allocated.
8895  */
8896 int DataArrayInt::getMinValueInArray() const
8897 {
8898   checkAllocated();
8899   const int *loc=std::min_element(begin(),end());
8900   return *loc;
8901 }
8902
8903 /*!
8904  * Converts every value of \a this array to its absolute value.
8905  *  \throw If \a this is not allocated.
8906  */
8907 void DataArrayInt::abs()
8908 {
8909   checkAllocated();
8910   int *ptr=getPointer();
8911   std::size_t nbOfElems=getNbOfElems();
8912   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8913   declareAsNew();
8914 }
8915
8916 /*!
8917  * Apply a liner function to a given component of \a this array, so that
8918  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8919  *  \param [in] a - the first coefficient of the function.
8920  *  \param [in] b - the second coefficient of the function.
8921  *  \param [in] compoId - the index of component to modify.
8922  *  \throw If \a this is not allocated.
8923  */
8924 void DataArrayInt::applyLin(int a, int b, int compoId)
8925 {
8926   checkAllocated();
8927   int *ptr=getPointer()+compoId;
8928   int nbOfComp=getNumberOfComponents();
8929   int nbOfTuple=getNumberOfTuples();
8930   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8931     *ptr=a*(*ptr)+b;
8932   declareAsNew();
8933 }
8934
8935 /*!
8936  * Apply a liner function to all elements of \a this array, so that
8937  * an element _x_ becomes \f$ a * x + b \f$.
8938  *  \param [in] a - the first coefficient of the function.
8939  *  \param [in] b - the second coefficient of the function.
8940  *  \throw If \a this is not allocated.
8941  */
8942 void DataArrayInt::applyLin(int a, int b)
8943 {
8944   checkAllocated();
8945   int *ptr=getPointer();
8946   std::size_t nbOfElems=getNbOfElems();
8947   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8948     *ptr=a*(*ptr)+b;
8949   declareAsNew();
8950 }
8951
8952 /*!
8953  * Returns a full copy of \a this array except that sign of all elements is reversed.
8954  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8955  *          same number of tuples and component as \a this array.
8956  *          The caller is to delete this result array using decrRef() as it is no more
8957  *          needed.
8958  *  \throw If \a this is not allocated.
8959  */
8960 DataArrayInt *DataArrayInt::negate() const
8961 {
8962   checkAllocated();
8963   DataArrayInt *newArr=DataArrayInt::New();
8964   int nbOfTuples=getNumberOfTuples();
8965   int nbOfComp=getNumberOfComponents();
8966   newArr->alloc(nbOfTuples,nbOfComp);
8967   const int *cptr=getConstPointer();
8968   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8969   newArr->copyStringInfoFrom(*this);
8970   return newArr;
8971 }
8972
8973 /*!
8974  * Modify all elements of \a this array, so that
8975  * an element _x_ becomes \f$ numerator / x \f$.
8976  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8977  *           array, all elements processed before detection of the zero element remain
8978  *           modified.
8979  *  \param [in] numerator - the numerator used to modify array elements.
8980  *  \throw If \a this is not allocated.
8981  *  \throw If there is an element equal to 0 in \a this array.
8982  */
8983 void DataArrayInt::applyInv(int numerator)
8984 {
8985   checkAllocated();
8986   int *ptr=getPointer();
8987   std::size_t nbOfElems=getNbOfElems();
8988   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8989     {
8990       if(*ptr!=0)
8991         {
8992           *ptr=numerator/(*ptr);
8993         }
8994       else
8995         {
8996           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8997           oss << " !";
8998           throw INTERP_KERNEL::Exception(oss.str().c_str());
8999         }
9000     }
9001   declareAsNew();
9002 }
9003
9004 /*!
9005  * Modify all elements of \a this array, so that
9006  * an element _x_ becomes \f$ x / val \f$.
9007  *  \param [in] val - the denominator used to modify array elements.
9008  *  \throw If \a this is not allocated.
9009  *  \throw If \a val == 0.
9010  */
9011 void DataArrayInt::applyDivideBy(int val)
9012 {
9013   if(val==0)
9014     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9015   checkAllocated();
9016   int *ptr=getPointer();
9017   std::size_t nbOfElems=getNbOfElems();
9018   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9019   declareAsNew();
9020 }
9021
9022 /*!
9023  * Modify all elements of \a this array, so that
9024  * an element _x_ becomes  <em> x % val </em>.
9025  *  \param [in] val - the divisor used to modify array elements.
9026  *  \throw If \a this is not allocated.
9027  *  \throw If \a val <= 0.
9028  */
9029 void DataArrayInt::applyModulus(int val)
9030 {
9031   if(val<=0)
9032     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9033   checkAllocated();
9034   int *ptr=getPointer();
9035   std::size_t nbOfElems=getNbOfElems();
9036   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9037   declareAsNew();
9038 }
9039
9040 /*!
9041  * This method works only on data array with one component.
9042  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9043  * this[*id] in [\b vmin,\b vmax)
9044  * 
9045  * \param [in] vmin begin of range. This value is included in range (included).
9046  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9047  * \return a newly allocated data array that the caller should deal with.
9048  *
9049  * \sa DataArrayInt::getIdsNotInRange
9050  */
9051 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9052 {
9053   checkAllocated();
9054   if(getNumberOfComponents()!=1)
9055     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9056   const int *cptr(begin());
9057   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9058   int nbOfTuples(getNumberOfTuples());
9059   for(int i=0;i<nbOfTuples;i++,cptr++)
9060     if(*cptr>=vmin && *cptr<vmax)
9061       ret->pushBackSilent(i);
9062   return ret.retn();
9063 }
9064
9065 /*!
9066  * This method works only on data array with one component.
9067  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9068  * this[*id] \b not in [\b vmin,\b vmax)
9069  * 
9070  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9071  * \param [in] vmax end of range. This value is included in range (included).
9072  * \return a newly allocated data array that the caller should deal with.
9073  * 
9074  * \sa DataArrayInt::getIdsInRange
9075  */
9076 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9077 {
9078   checkAllocated();
9079   if(getNumberOfComponents()!=1)
9080     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9081   const int *cptr(getConstPointer());
9082   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9083   int nbOfTuples(getNumberOfTuples());
9084   for(int i=0;i<nbOfTuples;i++,cptr++)
9085     if(*cptr<vmin || *cptr>=vmax)
9086       ret->pushBackSilent(i);
9087   return ret.retn();
9088 }
9089
9090 /*!
9091  * This method works only on data array with one component.
9092  * 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.
9093  * 
9094  * \param [in] vmin begin of range. This value is included in range (included).
9095  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9096  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9097 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9098 {
9099   checkAllocated();
9100   if(getNumberOfComponents()!=1)
9101     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9102   int nbOfTuples=getNumberOfTuples();
9103   bool ret=true;
9104   const int *cptr=getConstPointer();
9105   for(int i=0;i<nbOfTuples;i++,cptr++)
9106     {
9107       if(*cptr>=vmin && *cptr<vmax)
9108         { ret=ret && *cptr==i; }
9109       else
9110         {
9111           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9112           throw INTERP_KERNEL::Exception(oss.str().c_str());
9113         }
9114     }
9115   return ret;
9116 }
9117
9118 /*!
9119  * Modify all elements of \a this array, so that
9120  * an element _x_ becomes <em> val % x </em>.
9121  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9122  *           array, all elements processed before detection of the zero element remain
9123  *           modified.
9124  *  \param [in] val - the divident used to modify array elements.
9125  *  \throw If \a this is not allocated.
9126  *  \throw If there is an element equal to or less than 0 in \a this array.
9127  */
9128 void DataArrayInt::applyRModulus(int val)
9129 {
9130   checkAllocated();
9131   int *ptr=getPointer();
9132   std::size_t nbOfElems=getNbOfElems();
9133   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9134     {
9135       if(*ptr>0)
9136         {
9137           *ptr=val%(*ptr);
9138         }
9139       else
9140         {
9141           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9142           oss << " !";
9143           throw INTERP_KERNEL::Exception(oss.str().c_str());
9144         }
9145     }
9146   declareAsNew();
9147 }
9148
9149 /*!
9150  * Modify all elements of \a this array, so that
9151  * an element _x_ becomes <em> val ^ x </em>.
9152  *  \param [in] val - the value used to apply pow on all array elements.
9153  *  \throw If \a this is not allocated.
9154  *  \throw If \a val < 0.
9155  */
9156 void DataArrayInt::applyPow(int val)
9157 {
9158   checkAllocated();
9159   if(val<0)
9160     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9161   int *ptr=getPointer();
9162   std::size_t nbOfElems=getNbOfElems();
9163   if(val==0)
9164     {
9165       std::fill(ptr,ptr+nbOfElems,1);
9166       return ;
9167     }
9168   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9169     {
9170       int tmp=1;
9171       for(int j=0;j<val;j++)
9172         tmp*=*ptr;
9173       *ptr=tmp;
9174     }
9175   declareAsNew();
9176 }
9177
9178 /*!
9179  * Modify all elements of \a this array, so that
9180  * an element _x_ becomes \f$ val ^ x \f$.
9181  *  \param [in] val - the value used to apply pow on all array elements.
9182  *  \throw If \a this is not allocated.
9183  *  \throw If there is an element < 0 in \a this array.
9184  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9185  *           array, all elements processed before detection of the zero element remain
9186  *           modified.
9187  */
9188 void DataArrayInt::applyRPow(int val)
9189 {
9190   checkAllocated();
9191   int *ptr=getPointer();
9192   std::size_t nbOfElems=getNbOfElems();
9193   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9194     {
9195       if(*ptr>=0)
9196         {
9197           int tmp=1;
9198           for(int j=0;j<*ptr;j++)
9199             tmp*=val;
9200           *ptr=tmp;
9201         }
9202       else
9203         {
9204           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9205           oss << " !";
9206           throw INTERP_KERNEL::Exception(oss.str().c_str());
9207         }
9208     }
9209   declareAsNew();
9210 }
9211
9212 /*!
9213  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9214  * of components in the result array is a sum of the number of components of given arrays
9215  * and (2) the number of tuples in the result array is same as that of each of given
9216  * arrays. In other words the i-th tuple of result array includes all components of
9217  * i-th tuples of all given arrays.
9218  * Number of tuples in the given arrays must be the same.
9219  *  \param [in] a1 - an array to include in the result array.
9220  *  \param [in] a2 - another array to include in the result array.
9221  *  \return DataArrayInt * - the new instance of DataArrayInt.
9222  *          The caller is to delete this result array using decrRef() as it is no more
9223  *          needed.
9224  *  \throw If both \a a1 and \a a2 are NULL.
9225  *  \throw If any given array is not allocated.
9226  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9227  */
9228 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9229 {
9230   std::vector<const DataArrayInt *> arr(2);
9231   arr[0]=a1; arr[1]=a2;
9232   return Meld(arr);
9233 }
9234
9235 /*!
9236  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9237  * of components in the result array is a sum of the number of components of given arrays
9238  * and (2) the number of tuples in the result array is same as that of each of given
9239  * arrays. In other words the i-th tuple of result array includes all components of
9240  * i-th tuples of all given arrays.
9241  * Number of tuples in the given arrays must be  the same.
9242  *  \param [in] arr - a sequence of arrays to include in the result array.
9243  *  \return DataArrayInt * - the new instance of DataArrayInt.
9244  *          The caller is to delete this result array using decrRef() as it is no more
9245  *          needed.
9246  *  \throw If all arrays within \a arr are NULL.
9247  *  \throw If any given array is not allocated.
9248  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9249  */
9250 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9251 {
9252   std::vector<const DataArrayInt *> a;
9253   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9254     if(*it4)
9255       a.push_back(*it4);
9256   if(a.empty())
9257     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9258   std::vector<const DataArrayInt *>::const_iterator it;
9259   for(it=a.begin();it!=a.end();it++)
9260     (*it)->checkAllocated();
9261   it=a.begin();
9262   int nbOfTuples=(*it)->getNumberOfTuples();
9263   std::vector<int> nbc(a.size());
9264   std::vector<const int *> pts(a.size());
9265   nbc[0]=(*it)->getNumberOfComponents();
9266   pts[0]=(*it++)->getConstPointer();
9267   for(int i=1;it!=a.end();it++,i++)
9268     {
9269       if(nbOfTuples!=(*it)->getNumberOfTuples())
9270         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9271       nbc[i]=(*it)->getNumberOfComponents();
9272       pts[i]=(*it)->getConstPointer();
9273     }
9274   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9275   DataArrayInt *ret=DataArrayInt::New();
9276   ret->alloc(nbOfTuples,totalNbOfComp);
9277   int *retPtr=ret->getPointer();
9278   for(int i=0;i<nbOfTuples;i++)
9279     for(int j=0;j<(int)a.size();j++)
9280       {
9281         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9282         pts[j]+=nbc[j];
9283       }
9284   int k=0;
9285   for(int i=0;i<(int)a.size();i++)
9286     for(int j=0;j<nbc[i];j++,k++)
9287       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9288   return ret;
9289 }
9290
9291 /*!
9292  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9293  * The i-th item of the result array is an ID of a set of elements belonging to a
9294  * unique set of groups, which the i-th element is a part of. This set of elements
9295  * belonging to a unique set of groups is called \a family, so the result array contains
9296  * IDs of families each element belongs to.
9297  *
9298  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9299  * then there are 3 families:
9300  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9301  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9302  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9303  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9304  * stands for the element #3 which is in none of groups.
9305  *
9306  *  \param [in] groups - sequence of groups of element IDs.
9307  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9308  *         in \a groups.
9309  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9310  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9311  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9312  *         delete this array using decrRef() as it is no more needed.
9313  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9314  */
9315 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9316 {
9317   std::vector<const DataArrayInt *> groups2;
9318   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9319     if(*it4)
9320       groups2.push_back(*it4);
9321   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9322   ret->alloc(newNb,1);
9323   int *retPtr=ret->getPointer();
9324   std::fill(retPtr,retPtr+newNb,0);
9325   int fid=1;
9326   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9327     {
9328       const int *ptr=(*iter)->getConstPointer();
9329       std::size_t nbOfElem=(*iter)->getNbOfElems();
9330       int sfid=fid;
9331       for(int j=0;j<sfid;j++)
9332         {
9333           bool found=false;
9334           for(std::size_t i=0;i<nbOfElem;i++)
9335             {
9336               if(ptr[i]>=0 && ptr[i]<newNb)
9337                 {
9338                   if(retPtr[ptr[i]]==j)
9339                     {
9340                       retPtr[ptr[i]]=fid;
9341                       found=true;
9342                     }
9343                 }
9344               else
9345                 {
9346                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9347                   oss << ") !";
9348                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9349                 }
9350             }
9351           if(found)
9352             fid++;
9353         }
9354     }
9355   fidsOfGroups.clear();
9356   fidsOfGroups.resize(groups2.size());
9357   int grId=0;
9358   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9359     {
9360       std::set<int> tmp;
9361       const int *ptr=(*iter)->getConstPointer();
9362       std::size_t nbOfElem=(*iter)->getNbOfElems();
9363       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9364         tmp.insert(retPtr[*p]);
9365       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9366     }
9367   return ret.retn();
9368 }
9369
9370 /*!
9371  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9372  * arrays. The result array does not contain any duplicates and its values
9373  * are sorted in ascending order.
9374  *  \param [in] arr - sequence of DataArrayInt's to unite.
9375  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9376  *         array using decrRef() as it is no more needed.
9377  *  \throw If any \a arr[i] is not allocated.
9378  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9379  */
9380 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9381 {
9382   std::vector<const DataArrayInt *> a;
9383   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9384     if(*it4)
9385       a.push_back(*it4);
9386   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9387     {
9388       (*it)->checkAllocated();
9389       if((*it)->getNumberOfComponents()!=1)
9390         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9391     }
9392   //
9393   std::set<int> r;
9394   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9395     {
9396       const int *pt=(*it)->getConstPointer();
9397       int nbOfTuples=(*it)->getNumberOfTuples();
9398       r.insert(pt,pt+nbOfTuples);
9399     }
9400   DataArrayInt *ret=DataArrayInt::New();
9401   ret->alloc((int)r.size(),1);
9402   std::copy(r.begin(),r.end(),ret->getPointer());
9403   return ret;
9404 }
9405
9406 /*!
9407  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9408  * arrays. The result array does not contain any duplicates and its values
9409  * are sorted in ascending order.
9410  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9411  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9412  *         array using decrRef() as it is no more needed.
9413  *  \throw If any \a arr[i] is not allocated.
9414  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9415  */
9416 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9417 {
9418   std::vector<const DataArrayInt *> a;
9419   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9420     if(*it4)
9421       a.push_back(*it4);
9422   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9423     {
9424       (*it)->checkAllocated();
9425       if((*it)->getNumberOfComponents()!=1)
9426         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9427     }
9428   //
9429   std::set<int> r;
9430   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9431     {
9432       const int *pt=(*it)->getConstPointer();
9433       int nbOfTuples=(*it)->getNumberOfTuples();
9434       std::set<int> s1(pt,pt+nbOfTuples);
9435       if(it!=a.begin())
9436         {
9437           std::set<int> r2;
9438           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9439           r=r2;
9440         }
9441       else
9442         r=s1;
9443     }
9444   DataArrayInt *ret=DataArrayInt::New();
9445   ret->alloc((int)r.size(),1);
9446   std::copy(r.begin(),r.end(),ret->getPointer());
9447   return ret;
9448 }
9449
9450 /*!
9451  * Returns a new DataArrayInt which contains a complement of elements of \a this
9452  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9453  * \a nbOfElement) not present in \a this array.
9454  *  \param [in] nbOfElement - maximal size of the result array.
9455  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9456  *         array using decrRef() as it is no more needed.
9457  *  \throw If \a this is not allocated.
9458  *  \throw If \a this->getNumberOfComponents() != 1.
9459  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9460  *         nbOfElement ).
9461  */
9462 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9463 {
9464    checkAllocated();
9465    if(getNumberOfComponents()!=1)
9466      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9467    std::vector<bool> tmp(nbOfElement);
9468    const int *pt=getConstPointer();
9469    int nbOfTuples=getNumberOfTuples();
9470    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9471      if(*w>=0 && *w<nbOfElement)
9472        tmp[*w]=true;
9473      else
9474        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9475    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9476    DataArrayInt *ret=DataArrayInt::New();
9477    ret->alloc(nbOfRetVal,1);
9478    int j=0;
9479    int *retPtr=ret->getPointer();
9480    for(int i=0;i<nbOfElement;i++)
9481      if(!tmp[i])
9482        retPtr[j++]=i;
9483    return ret;
9484 }
9485
9486 /*!
9487  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9488  * from an \a other one-dimensional array.
9489  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9490  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9491  *         caller is to delete this array using decrRef() as it is no more needed.
9492  *  \throw If \a other is NULL.
9493  *  \throw If \a other is not allocated.
9494  *  \throw If \a other->getNumberOfComponents() != 1.
9495  *  \throw If \a this is not allocated.
9496  *  \throw If \a this->getNumberOfComponents() != 1.
9497  *  \sa DataArrayInt::buildSubstractionOptimized()
9498  */
9499 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9500 {
9501   if(!other)
9502     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9503   checkAllocated();
9504   other->checkAllocated();
9505   if(getNumberOfComponents()!=1)
9506      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9507   if(other->getNumberOfComponents()!=1)
9508      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9509   const int *pt=getConstPointer();
9510   int nbOfTuples=getNumberOfTuples();
9511   std::set<int> s1(pt,pt+nbOfTuples);
9512   pt=other->getConstPointer();
9513   nbOfTuples=other->getNumberOfTuples();
9514   std::set<int> s2(pt,pt+nbOfTuples);
9515   std::vector<int> r;
9516   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9517   DataArrayInt *ret=DataArrayInt::New();
9518   ret->alloc((int)r.size(),1);
9519   std::copy(r.begin(),r.end(),ret->getPointer());
9520   return ret;
9521 }
9522
9523 /*!
9524  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9525  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9526  * 
9527  * \param [in] other an array with one component and expected to be sorted ascendingly.
9528  * \ret list of ids in \a this but not in \a other.
9529  * \sa DataArrayInt::buildSubstraction
9530  */
9531 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9532 {
9533   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9534   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9535   checkAllocated(); other->checkAllocated();
9536   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9537   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9538   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9539   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9540   for(;work1!=pt1End;work1++)
9541     {
9542       if(work2!=pt2End && *work1==*work2)
9543         work2++;
9544       else
9545         ret->pushBackSilent(*work1);
9546     }
9547   return ret.retn();
9548 }
9549
9550
9551 /*!
9552  * Returns a new DataArrayInt which contains all elements of \a this and a given
9553  * one-dimensional arrays. The result array does not contain any duplicates
9554  * and its values are sorted in ascending order.
9555  *  \param [in] other - an array to unite with \a this one.
9556  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9557  *         array using decrRef() as it is no more needed.
9558  *  \throw If \a this or \a other is not allocated.
9559  *  \throw If \a this->getNumberOfComponents() != 1.
9560  *  \throw If \a other->getNumberOfComponents() != 1.
9561  */
9562 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9563 {
9564   std::vector<const DataArrayInt *>arrs(2);
9565   arrs[0]=this; arrs[1]=other;
9566   return BuildUnion(arrs);
9567 }
9568
9569
9570 /*!
9571  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9572  * one-dimensional arrays. The result array does not contain any duplicates
9573  * and its values are sorted in ascending order.
9574  *  \param [in] other - an array to intersect with \a this one.
9575  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9576  *         array using decrRef() as it is no more needed.
9577  *  \throw If \a this or \a other is not allocated.
9578  *  \throw If \a this->getNumberOfComponents() != 1.
9579  *  \throw If \a other->getNumberOfComponents() != 1.
9580  */
9581 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9582 {
9583   std::vector<const DataArrayInt *>arrs(2);
9584   arrs[0]=this; arrs[1]=other;
9585   return BuildIntersection(arrs);
9586 }
9587
9588 /*!
9589  * This method can be applied on allocated with one component DataArrayInt instance.
9590  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9591  * 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]
9592  * 
9593  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9594  * \throw if \a this is not allocated or if \a this has not exactly one component.
9595  */
9596 DataArrayInt *DataArrayInt::buildUnique() const
9597 {
9598   checkAllocated();
9599   if(getNumberOfComponents()!=1)
9600      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9601   int nbOfTuples=getNumberOfTuples();
9602   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9603   int *data=tmp->getPointer();
9604   int *last=std::unique(data,data+nbOfTuples);
9605   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9606   ret->alloc(std::distance(data,last),1);
9607   std::copy(data,last,ret->getPointer());
9608   return ret.retn();
9609 }
9610
9611 /*!
9612  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9613  * "index" array. Such "index" array is returned for example by 
9614  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9615  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9616  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9617  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9618  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9619  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9620  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9621  *          The caller is to delete this array using decrRef() as it is no more needed. 
9622  *  \throw If \a this is not allocated.
9623  *  \throw If \a this->getNumberOfComponents() != 1.
9624  *  \throw If \a this->getNumberOfTuples() < 2.
9625  *
9626  *  \b Example: <br> 
9627  *         - this contains [1,3,6,7,7,9,15]
9628  *         - result array contains [2,3,1,0,2,6],
9629  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9630  *
9631  * \sa DataArrayInt::computeOffsets2
9632  */
9633 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9634 {
9635   checkAllocated();
9636   if(getNumberOfComponents()!=1)
9637      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9638   int nbOfTuples=getNumberOfTuples();
9639   if(nbOfTuples<2)
9640     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9641   const int *ptr=getConstPointer();
9642   DataArrayInt *ret=DataArrayInt::New();
9643   ret->alloc(nbOfTuples-1,1);
9644   int *out=ret->getPointer();
9645   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9646   return ret;
9647 }
9648
9649 /*!
9650  * Modifies \a this one-dimensional array so that value of each element \a x
9651  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9652  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9653  * and components remains the same.<br>
9654  * This method is useful for allToAllV in MPI with contiguous policy. This method
9655  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9656  * this one.
9657  *  \throw If \a this is not allocated.
9658  *  \throw If \a this->getNumberOfComponents() != 1.
9659  *
9660  *  \b Example: <br>
9661  *          - Before \a this contains [3,5,1,2,0,8]
9662  *          - After \a this contains  [0,3,8,9,11,11]<br>
9663  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9664  *          array is retained and thus there is no space to store the last element.
9665  */
9666 void DataArrayInt::computeOffsets()
9667 {
9668   checkAllocated();
9669   if(getNumberOfComponents()!=1)
9670      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9671   int nbOfTuples=getNumberOfTuples();
9672   if(nbOfTuples==0)
9673     return ;
9674   int *work=getPointer();
9675   int tmp=work[0];
9676   work[0]=0;
9677   for(int i=1;i<nbOfTuples;i++)
9678     {
9679       int tmp2=work[i];
9680       work[i]=work[i-1]+tmp;
9681       tmp=tmp2;
9682     }
9683   declareAsNew();
9684 }
9685
9686
9687 /*!
9688  * Modifies \a this one-dimensional array so that value of each element \a x
9689  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9690  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9691  * components remains the same and number of tuples is inceamented by one.<br>
9692  * This method is useful for allToAllV in MPI with contiguous policy. This method
9693  * differs from computeOffsets() in that the number of tuples is changed by this one.
9694  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9695  *  \throw If \a this is not allocated.
9696  *  \throw If \a this->getNumberOfComponents() != 1.
9697  *
9698  *  \b Example: <br>
9699  *          - Before \a this contains [3,5,1,2,0,8]
9700  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9701  * \sa DataArrayInt::deltaShiftIndex
9702  */
9703 void DataArrayInt::computeOffsets2()
9704 {
9705   checkAllocated();
9706   if(getNumberOfComponents()!=1)
9707     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9708   int nbOfTuples=getNumberOfTuples();
9709   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9710   if(nbOfTuples==0)
9711     return ;
9712   const int *work=getConstPointer();
9713   ret[0]=0;
9714   for(int i=0;i<nbOfTuples;i++)
9715     ret[i+1]=work[i]+ret[i];
9716   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9717   declareAsNew();
9718 }
9719
9720 /*!
9721  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9722  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9723  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9724  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9725  * filling completely one of the ranges in \a this.
9726  *
9727  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9728  * \param [out] rangeIdsFetched the range ids fetched
9729  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9730  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9731  *
9732  * \sa DataArrayInt::computeOffsets2
9733  *
9734  *  \b Example: <br>
9735  *          - \a this : [0,3,7,9,15,18]
9736  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9737  *          - \a rangeIdsFetched result array: [0,2,4]
9738  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9739  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9740  * <br>
9741  */
9742 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9743 {
9744   if(!listOfIds)
9745     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9746   listOfIds->checkAllocated(); checkAllocated();
9747   if(listOfIds->getNumberOfComponents()!=1)
9748     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9749   if(getNumberOfComponents()!=1)
9750     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9751   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9752   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9753   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9754   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9755   while(tupPtr!=tupEnd && offPtr!=offEnd)
9756     {
9757       if(*tupPtr==*offPtr)
9758         {
9759           int i=offPtr[0];
9760           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9761           if(i==offPtr[1])
9762             {
9763               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9764               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9765               offPtr++;
9766             }
9767         }
9768       else
9769         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9770     }
9771   rangeIdsFetched=ret0.retn();
9772   idsInInputListThatFetch=ret1.retn();
9773 }
9774
9775 /*!
9776  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9777  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9778  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9779  * beginning within the "iota" array. And \a this is a one-dimensional array
9780  * considered as a selector of groups described by \a offsets to include into the result array.
9781  *  \throw If \a offsets is NULL.
9782  *  \throw If \a offsets is not allocated.
9783  *  \throw If \a offsets->getNumberOfComponents() != 1.
9784  *  \throw If \a offsets is not monotonically increasing.
9785  *  \throw If \a this is not allocated.
9786  *  \throw If \a this->getNumberOfComponents() != 1.
9787  *  \throw If any element of \a this is not a valid index for \a offsets array.
9788  *
9789  *  \b Example: <br>
9790  *          - \a this: [0,2,3]
9791  *          - \a offsets: [0,3,6,10,14,20]
9792  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9793  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9794  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9795  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9796  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9797  */
9798 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
9799 {
9800   if(!offsets)
9801     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9802   checkAllocated();
9803   if(getNumberOfComponents()!=1)
9804      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9805   offsets->checkAllocated();
9806   if(offsets->getNumberOfComponents()!=1)
9807      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9808   int othNbTuples=offsets->getNumberOfTuples()-1;
9809   int nbOfTuples=getNumberOfTuples();
9810   int retNbOftuples=0;
9811   const int *work=getConstPointer();
9812   const int *offPtr=offsets->getConstPointer();
9813   for(int i=0;i<nbOfTuples;i++)
9814     {
9815       int val=work[i];
9816       if(val>=0 && val<othNbTuples)
9817         {
9818           int delta=offPtr[val+1]-offPtr[val];
9819           if(delta>=0)
9820             retNbOftuples+=delta;
9821           else
9822             {
9823               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9824               throw INTERP_KERNEL::Exception(oss.str().c_str());
9825             }
9826         }
9827       else
9828         {
9829           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9830           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9831           throw INTERP_KERNEL::Exception(oss.str().c_str());
9832         }
9833     }
9834   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9835   ret->alloc(retNbOftuples,1);
9836   int *retPtr=ret->getPointer();
9837   for(int i=0;i<nbOfTuples;i++)
9838     {
9839       int val=work[i];
9840       int start=offPtr[val];
9841       int off=offPtr[val+1]-start;
9842       for(int j=0;j<off;j++,retPtr++)
9843         *retPtr=start+j;
9844     }
9845   return ret.retn();
9846 }
9847
9848 /*!
9849  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9850  * scaled array (monotonically increasing).
9851 from that of \a this and \a
9852  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9853  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9854  * beginning within the "iota" array. And \a this is a one-dimensional array
9855  * considered as a selector of groups described by \a offsets to include into the result array.
9856  *  \throw If \a  is NULL.
9857  *  \throw If \a this is not allocated.
9858  *  \throw If \a this->getNumberOfComponents() != 1.
9859  *  \throw If \a this->getNumberOfTuples() == 0.
9860  *  \throw If \a this is not monotonically increasing.
9861  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
9862  *
9863  *  \b Example: <br>
9864  *          - \a bg , \a stop and \a step : (0,5,2)
9865  *          - \a this: [0,3,6,10,14,20]
9866  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9867  */
9868 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
9869 {
9870   if(!isAllocated())
9871     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9872   if(getNumberOfComponents()!=1)
9873     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9874   int nbOfTuples(getNumberOfTuples());
9875   if(nbOfTuples==0)
9876     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9877   const int *ids(begin());
9878   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9879   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9880     {
9881       if(pos>=0 && pos<nbOfTuples-1)
9882         {
9883           int delta(ids[pos+1]-ids[pos]);
9884           sz+=delta;
9885           if(delta<0)
9886             {
9887               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9888               throw INTERP_KERNEL::Exception(oss.str().c_str());
9889             }          
9890         }
9891       else
9892         {
9893           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9894           throw INTERP_KERNEL::Exception(oss.str().c_str());
9895         }
9896     }
9897   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9898   int *retPtr(ret->getPointer());
9899   pos=bg;
9900   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9901     {
9902       int delta(ids[pos+1]-ids[pos]);
9903       for(int j=0;j<delta;j++,retPtr++)
9904         *retPtr=pos;
9905     }
9906   return ret.retn();
9907 }
9908
9909 /*!
9910  * 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.
9911  * 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
9912  * in tuple **i** of returned DataArrayInt.
9913  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9914  *
9915  * 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)]
9916  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9917  * 
9918  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9919  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9920  * \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
9921  *        is thrown if no ranges in \a ranges contains value in \a this.
9922  * 
9923  * \sa DataArrayInt::findIdInRangeForEachTuple
9924  */
9925 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
9926 {
9927   if(!ranges)
9928     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9929   if(ranges->getNumberOfComponents()!=2)
9930     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9931   checkAllocated();
9932   if(getNumberOfComponents()!=1)
9933     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9934   int nbTuples=getNumberOfTuples();
9935   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9936   int nbOfRanges=ranges->getNumberOfTuples();
9937   const int *rangesPtr=ranges->getConstPointer();
9938   int *retPtr=ret->getPointer();
9939   const int *inPtr=getConstPointer();
9940   for(int i=0;i<nbTuples;i++,retPtr++)
9941     {
9942       int val=inPtr[i];
9943       bool found=false;
9944       for(int j=0;j<nbOfRanges && !found;j++)
9945         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9946           { *retPtr=j; found=true; }
9947       if(found)
9948         continue;
9949       else
9950         {
9951           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9952           throw INTERP_KERNEL::Exception(oss.str().c_str());
9953         }
9954     }
9955   return ret.retn();
9956 }
9957
9958 /*!
9959  * 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.
9960  * 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
9961  * in tuple **i** of returned DataArrayInt.
9962  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9963  *
9964  * 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)]
9965  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9966  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9967  * 
9968  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9969  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9970  * \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
9971  *        is thrown if no ranges in \a ranges contains value in \a this.
9972  * \sa DataArrayInt::findRangeIdForEachTuple
9973  */
9974 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
9975 {
9976   if(!ranges)
9977     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9978   if(ranges->getNumberOfComponents()!=2)
9979     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9980   checkAllocated();
9981   if(getNumberOfComponents()!=1)
9982     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9983   int nbTuples=getNumberOfTuples();
9984   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9985   int nbOfRanges=ranges->getNumberOfTuples();
9986   const int *rangesPtr=ranges->getConstPointer();
9987   int *retPtr=ret->getPointer();
9988   const int *inPtr=getConstPointer();
9989   for(int i=0;i<nbTuples;i++,retPtr++)
9990     {
9991       int val=inPtr[i];
9992       bool found=false;
9993       for(int j=0;j<nbOfRanges && !found;j++)
9994         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9995           { *retPtr=val-rangesPtr[2*j]; found=true; }
9996       if(found)
9997         continue;
9998       else
9999         {
10000           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10001           throw INTERP_KERNEL::Exception(oss.str().c_str());
10002         }
10003     }
10004   return ret.retn();
10005 }
10006
10007 /*!
10008  * 
10009  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10010  *             \a nbTimes  should be at least equal to 1.
10011  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10012  * \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.
10013  */
10014 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10015 {
10016   checkAllocated();
10017   if(getNumberOfComponents()!=1)
10018     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10019   if(nbTimes<1)
10020     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10021   int nbTuples=getNumberOfTuples();
10022   const int *inPtr=getConstPointer();
10023   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10024   int *retPtr=ret->getPointer();
10025   for(int i=0;i<nbTuples;i++,inPtr++)
10026     {
10027       int val=*inPtr;
10028       for(int j=0;j<nbTimes;j++,retPtr++)
10029         *retPtr=val;
10030     }
10031   ret->copyStringInfoFrom(*this);
10032   return ret.retn();
10033 }
10034
10035 /*!
10036  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10037  * But the number of components can be different from one.
10038  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10039  */
10040 DataArrayInt *DataArrayInt::getDifferentValues() const
10041 {
10042   checkAllocated();
10043   std::set<int> ret;
10044   ret.insert(begin(),end());
10045   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10046   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10047   return ret2.retn();
10048 }
10049
10050 /*!
10051  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10052  * them it tells which tuple id have this id.
10053  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10054  * This method returns two arrays having same size.
10055  * 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.
10056  * 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]]
10057  */
10058 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10059 {
10060   checkAllocated();
10061   if(getNumberOfComponents()!=1)
10062     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10063   int id=0;
10064   std::map<int,int> m,m2,m3;
10065   for(const int *w=begin();w!=end();w++)
10066     m[*w]++;
10067   differentIds.resize(m.size());
10068   std::vector<DataArrayInt *> ret(m.size());
10069   std::vector<int *> retPtr(m.size());
10070   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10071     {
10072       m2[(*it).first]=id;
10073       ret[id]=DataArrayInt::New();
10074       ret[id]->alloc((*it).second,1);
10075       retPtr[id]=ret[id]->getPointer();
10076       differentIds[id]=(*it).first;
10077     }
10078   id=0;
10079   for(const int *w=begin();w!=end();w++,id++)
10080     {
10081       retPtr[m2[*w]][m3[*w]++]=id;
10082     }
10083   return ret;
10084 }
10085
10086 /*!
10087  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10088  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10089  *
10090  * \param [in] nbOfSlices - number of slices expected.
10091  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10092  * 
10093  * \sa DataArray::GetSlice
10094  * \throw If \a this is not allocated or not with exactly one component.
10095  * \throw If an element in \a this if < 0.
10096  */
10097 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10098 {
10099   if(!isAllocated() || getNumberOfComponents()!=1)
10100     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10101   if(nbOfSlices<=0)
10102     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10103   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10104   int sumPerSlc(sum/nbOfSlices),pos(0);
10105   const int *w(begin());
10106   std::vector< std::pair<int,int> > ret(nbOfSlices);
10107   for(int i=0;i<nbOfSlices;i++)
10108     {
10109       std::pair<int,int> p(pos,-1);
10110       int locSum(0);
10111       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10112       if(i!=nbOfSlices-1)
10113         p.second=pos;
10114       else
10115         p.second=nbOfTuples;
10116       ret[i]=p;
10117     }
10118   return ret;
10119 }
10120
10121 /*!
10122  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10123  * valid cases.
10124  * 1.  The arrays have same number of tuples and components. Then each value of
10125  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10126  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10127  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10128  *   component. Then
10129  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10130  * 3.  The arrays have same number of components and one array, say _a2_, has one
10131  *   tuple. Then
10132  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10133  *
10134  * Info on components is copied either from the first array (in the first case) or from
10135  * the array with maximal number of elements (getNbOfElems()).
10136  *  \param [in] a1 - an array to sum up.
10137  *  \param [in] a2 - another array to sum up.
10138  *  \return DataArrayInt * - the new instance of DataArrayInt.
10139  *          The caller is to delete this result array using decrRef() as it is no more
10140  *          needed.
10141  *  \throw If either \a a1 or \a a2 is NULL.
10142  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10143  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10144  *         none of them has number of tuples or components equal to 1.
10145  */
10146 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10147 {
10148   if(!a1 || !a2)
10149     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10150   int nbOfTuple=a1->getNumberOfTuples();
10151   int nbOfTuple2=a2->getNumberOfTuples();
10152   int nbOfComp=a1->getNumberOfComponents();
10153   int nbOfComp2=a2->getNumberOfComponents();
10154   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10155   if(nbOfTuple==nbOfTuple2)
10156     {
10157       if(nbOfComp==nbOfComp2)
10158         {
10159           ret=DataArrayInt::New();
10160           ret->alloc(nbOfTuple,nbOfComp);
10161           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10162           ret->copyStringInfoFrom(*a1);
10163         }
10164       else
10165         {
10166           int nbOfCompMin,nbOfCompMax;
10167           const DataArrayInt *aMin, *aMax;
10168           if(nbOfComp>nbOfComp2)
10169             {
10170               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10171               aMin=a2; aMax=a1;
10172             }
10173           else
10174             {
10175               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10176               aMin=a1; aMax=a2;
10177             }
10178           if(nbOfCompMin==1)
10179             {
10180               ret=DataArrayInt::New();
10181               ret->alloc(nbOfTuple,nbOfCompMax);
10182               const int *aMinPtr=aMin->getConstPointer();
10183               const int *aMaxPtr=aMax->getConstPointer();
10184               int *res=ret->getPointer();
10185               for(int i=0;i<nbOfTuple;i++)
10186                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10187               ret->copyStringInfoFrom(*aMax);
10188             }
10189           else
10190             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10191         }
10192     }
10193   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10194     {
10195       if(nbOfComp==nbOfComp2)
10196         {
10197           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10198           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10199           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10200           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10201           ret=DataArrayInt::New();
10202           ret->alloc(nbOfTupleMax,nbOfComp);
10203           int *res=ret->getPointer();
10204           for(int i=0;i<nbOfTupleMax;i++)
10205             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10206           ret->copyStringInfoFrom(*aMax);
10207         }
10208       else
10209         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10210     }
10211   else
10212     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10213   return ret.retn();
10214 }
10215
10216 /*!
10217  * Adds values of another DataArrayInt to values of \a this one. There are 3
10218  * valid cases.
10219  * 1.  The arrays have same number of tuples and components. Then each value of
10220  *   \a other array is added to the corresponding value of \a this array, i.e.:
10221  *   _a_ [ i, j ] += _other_ [ i, j ].
10222  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10223  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10224  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10225  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10226  *
10227  *  \param [in] other - an array to add to \a this one.
10228  *  \throw If \a other is NULL.
10229  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10230  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10231  *         \a other has number of both tuples and components not equal to 1.
10232  */
10233 void DataArrayInt::addEqual(const DataArrayInt *other)
10234 {
10235   if(!other)
10236     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10237   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10238   checkAllocated(); other->checkAllocated();
10239   int nbOfTuple=getNumberOfTuples();
10240   int nbOfTuple2=other->getNumberOfTuples();
10241   int nbOfComp=getNumberOfComponents();
10242   int nbOfComp2=other->getNumberOfComponents();
10243   if(nbOfTuple==nbOfTuple2)
10244     {
10245       if(nbOfComp==nbOfComp2)
10246         {
10247           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10248         }
10249       else if(nbOfComp2==1)
10250         {
10251           int *ptr=getPointer();
10252           const int *ptrc=other->getConstPointer();
10253           for(int i=0;i<nbOfTuple;i++)
10254             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10255         }
10256       else
10257         throw INTERP_KERNEL::Exception(msg);
10258     }
10259   else if(nbOfTuple2==1)
10260     {
10261       if(nbOfComp2==nbOfComp)
10262         {
10263           int *ptr=getPointer();
10264           const int *ptrc=other->getConstPointer();
10265           for(int i=0;i<nbOfTuple;i++)
10266             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10267         }
10268       else
10269         throw INTERP_KERNEL::Exception(msg);
10270     }
10271   else
10272     throw INTERP_KERNEL::Exception(msg);
10273   declareAsNew();
10274 }
10275
10276 /*!
10277  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10278  * valid cases.
10279  * 1.  The arrays have same number of tuples and components. Then each value of
10280  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10281  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10282  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10283  *   component. Then
10284  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10285  * 3.  The arrays have same number of components and one array, say _a2_, has one
10286  *   tuple. Then
10287  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10288  *
10289  * Info on components is copied either from the first array (in the first case) or from
10290  * the array with maximal number of elements (getNbOfElems()).
10291  *  \param [in] a1 - an array to subtract from.
10292  *  \param [in] a2 - an array to subtract.
10293  *  \return DataArrayInt * - the new instance of DataArrayInt.
10294  *          The caller is to delete this result array using decrRef() as it is no more
10295  *          needed.
10296  *  \throw If either \a a1 or \a a2 is NULL.
10297  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10298  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10299  *         none of them has number of tuples or components equal to 1.
10300  */
10301 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10302 {
10303   if(!a1 || !a2)
10304     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10305   int nbOfTuple1=a1->getNumberOfTuples();
10306   int nbOfTuple2=a2->getNumberOfTuples();
10307   int nbOfComp1=a1->getNumberOfComponents();
10308   int nbOfComp2=a2->getNumberOfComponents();
10309   if(nbOfTuple2==nbOfTuple1)
10310     {
10311       if(nbOfComp1==nbOfComp2)
10312         {
10313           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10314           ret->alloc(nbOfTuple2,nbOfComp1);
10315           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10316           ret->copyStringInfoFrom(*a1);
10317           return ret.retn();
10318         }
10319       else if(nbOfComp2==1)
10320         {
10321           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10322           ret->alloc(nbOfTuple1,nbOfComp1);
10323           const int *a2Ptr=a2->getConstPointer();
10324           const int *a1Ptr=a1->getConstPointer();
10325           int *res=ret->getPointer();
10326           for(int i=0;i<nbOfTuple1;i++)
10327             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10328           ret->copyStringInfoFrom(*a1);
10329           return ret.retn();
10330         }
10331       else
10332         {
10333           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10334           return 0;
10335         }
10336     }
10337   else if(nbOfTuple2==1)
10338     {
10339       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10340       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10341       ret->alloc(nbOfTuple1,nbOfComp1);
10342       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10343       int *pt=ret->getPointer();
10344       for(int i=0;i<nbOfTuple1;i++)
10345         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10346       ret->copyStringInfoFrom(*a1);
10347       return ret.retn();
10348     }
10349   else
10350     {
10351       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10352       return 0;
10353     }
10354 }
10355
10356 /*!
10357  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10358  * valid cases.
10359  * 1.  The arrays have same number of tuples and components. Then each value of
10360  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10361  *   _a_ [ i, j ] -= _other_ [ i, j ].
10362  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10363  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10364  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10365  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10366  *
10367  *  \param [in] other - an array to subtract from \a this one.
10368  *  \throw If \a other is NULL.
10369  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10370  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10371  *         \a other has number of both tuples and components not equal to 1.
10372  */
10373 void DataArrayInt::substractEqual(const DataArrayInt *other)
10374 {
10375   if(!other)
10376     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10377   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10378   checkAllocated(); other->checkAllocated();
10379   int nbOfTuple=getNumberOfTuples();
10380   int nbOfTuple2=other->getNumberOfTuples();
10381   int nbOfComp=getNumberOfComponents();
10382   int nbOfComp2=other->getNumberOfComponents();
10383   if(nbOfTuple==nbOfTuple2)
10384     {
10385       if(nbOfComp==nbOfComp2)
10386         {
10387           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10388         }
10389       else if(nbOfComp2==1)
10390         {
10391           int *ptr=getPointer();
10392           const int *ptrc=other->getConstPointer();
10393           for(int i=0;i<nbOfTuple;i++)
10394             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10395         }
10396       else
10397         throw INTERP_KERNEL::Exception(msg);
10398     }
10399   else if(nbOfTuple2==1)
10400     {
10401       int *ptr=getPointer();
10402       const int *ptrc=other->getConstPointer();
10403       for(int i=0;i<nbOfTuple;i++)
10404         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10405     }
10406   else
10407     throw INTERP_KERNEL::Exception(msg);
10408   declareAsNew();
10409 }
10410
10411 /*!
10412  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10413  * valid cases.
10414  * 1.  The arrays have same number of tuples and components. Then each value of
10415  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10416  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10417  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10418  *   component. Then
10419  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10420  * 3.  The arrays have same number of components and one array, say _a2_, has one
10421  *   tuple. Then
10422  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10423  *
10424  * Info on components is copied either from the first array (in the first case) or from
10425  * the array with maximal number of elements (getNbOfElems()).
10426  *  \param [in] a1 - a factor array.
10427  *  \param [in] a2 - another factor array.
10428  *  \return DataArrayInt * - the new instance of DataArrayInt.
10429  *          The caller is to delete this result array using decrRef() as it is no more
10430  *          needed.
10431  *  \throw If either \a a1 or \a a2 is NULL.
10432  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10433  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10434  *         none of them has number of tuples or components equal to 1.
10435  */
10436 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10437 {
10438   if(!a1 || !a2)
10439     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10440   int nbOfTuple=a1->getNumberOfTuples();
10441   int nbOfTuple2=a2->getNumberOfTuples();
10442   int nbOfComp=a1->getNumberOfComponents();
10443   int nbOfComp2=a2->getNumberOfComponents();
10444   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10445   if(nbOfTuple==nbOfTuple2)
10446     {
10447       if(nbOfComp==nbOfComp2)
10448         {
10449           ret=DataArrayInt::New();
10450           ret->alloc(nbOfTuple,nbOfComp);
10451           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10452           ret->copyStringInfoFrom(*a1);
10453         }
10454       else
10455         {
10456           int nbOfCompMin,nbOfCompMax;
10457           const DataArrayInt *aMin, *aMax;
10458           if(nbOfComp>nbOfComp2)
10459             {
10460               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10461               aMin=a2; aMax=a1;
10462             }
10463           else
10464             {
10465               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10466               aMin=a1; aMax=a2;
10467             }
10468           if(nbOfCompMin==1)
10469             {
10470               ret=DataArrayInt::New();
10471               ret->alloc(nbOfTuple,nbOfCompMax);
10472               const int *aMinPtr=aMin->getConstPointer();
10473               const int *aMaxPtr=aMax->getConstPointer();
10474               int *res=ret->getPointer();
10475               for(int i=0;i<nbOfTuple;i++)
10476                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10477               ret->copyStringInfoFrom(*aMax);
10478             }
10479           else
10480             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10481         }
10482     }
10483   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10484     {
10485       if(nbOfComp==nbOfComp2)
10486         {
10487           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10488           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10489           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10490           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10491           ret=DataArrayInt::New();
10492           ret->alloc(nbOfTupleMax,nbOfComp);
10493           int *res=ret->getPointer();
10494           for(int i=0;i<nbOfTupleMax;i++)
10495             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10496           ret->copyStringInfoFrom(*aMax);
10497         }
10498       else
10499         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10500     }
10501   else
10502     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10503   return ret.retn();
10504 }
10505
10506
10507 /*!
10508  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10509  * valid cases.
10510  * 1.  The arrays have same number of tuples and components. Then each value of
10511  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10512  *   _a_ [ i, j ] *= _other_ [ i, j ].
10513  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10514  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10515  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10516  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10517  *
10518  *  \param [in] other - an array to multiply to \a this one.
10519  *  \throw If \a other is NULL.
10520  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10521  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10522  *         \a other has number of both tuples and components not equal to 1.
10523  */
10524 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10525 {
10526   if(!other)
10527     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10528   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10529   checkAllocated(); other->checkAllocated();
10530   int nbOfTuple=getNumberOfTuples();
10531   int nbOfTuple2=other->getNumberOfTuples();
10532   int nbOfComp=getNumberOfComponents();
10533   int nbOfComp2=other->getNumberOfComponents();
10534   if(nbOfTuple==nbOfTuple2)
10535     {
10536       if(nbOfComp==nbOfComp2)
10537         {
10538           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10539         }
10540       else if(nbOfComp2==1)
10541         {
10542           int *ptr=getPointer();
10543           const int *ptrc=other->getConstPointer();
10544           for(int i=0;i<nbOfTuple;i++)
10545             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10546         }
10547       else
10548         throw INTERP_KERNEL::Exception(msg);
10549     }
10550   else if(nbOfTuple2==1)
10551     {
10552       if(nbOfComp2==nbOfComp)
10553         {
10554           int *ptr=getPointer();
10555           const int *ptrc=other->getConstPointer();
10556           for(int i=0;i<nbOfTuple;i++)
10557             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10558         }
10559       else
10560         throw INTERP_KERNEL::Exception(msg);
10561     }
10562   else
10563     throw INTERP_KERNEL::Exception(msg);
10564   declareAsNew();
10565 }
10566
10567
10568 /*!
10569  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10570  * valid cases.
10571  * 1.  The arrays have same number of tuples and components. Then each value of
10572  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10573  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10574  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10575  *   component. Then
10576  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10577  * 3.  The arrays have same number of components and one array, say _a2_, has one
10578  *   tuple. Then
10579  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10580  *
10581  * Info on components is copied either from the first array (in the first case) or from
10582  * the array with maximal number of elements (getNbOfElems()).
10583  *  \warning No check of division by zero is performed!
10584  *  \param [in] a1 - a numerator array.
10585  *  \param [in] a2 - a denominator array.
10586  *  \return DataArrayInt * - the new instance of DataArrayInt.
10587  *          The caller is to delete this result array using decrRef() as it is no more
10588  *          needed.
10589  *  \throw If either \a a1 or \a a2 is NULL.
10590  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10591  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10592  *         none of them has number of tuples or components equal to 1.
10593  */
10594 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10595 {
10596   if(!a1 || !a2)
10597     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10598   int nbOfTuple1=a1->getNumberOfTuples();
10599   int nbOfTuple2=a2->getNumberOfTuples();
10600   int nbOfComp1=a1->getNumberOfComponents();
10601   int nbOfComp2=a2->getNumberOfComponents();
10602   if(nbOfTuple2==nbOfTuple1)
10603     {
10604       if(nbOfComp1==nbOfComp2)
10605         {
10606           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10607           ret->alloc(nbOfTuple2,nbOfComp1);
10608           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10609           ret->copyStringInfoFrom(*a1);
10610           return ret.retn();
10611         }
10612       else if(nbOfComp2==1)
10613         {
10614           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10615           ret->alloc(nbOfTuple1,nbOfComp1);
10616           const int *a2Ptr=a2->getConstPointer();
10617           const int *a1Ptr=a1->getConstPointer();
10618           int *res=ret->getPointer();
10619           for(int i=0;i<nbOfTuple1;i++)
10620             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10621           ret->copyStringInfoFrom(*a1);
10622           return ret.retn();
10623         }
10624       else
10625         {
10626           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10627           return 0;
10628         }
10629     }
10630   else if(nbOfTuple2==1)
10631     {
10632       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10633       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10634       ret->alloc(nbOfTuple1,nbOfComp1);
10635       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10636       int *pt=ret->getPointer();
10637       for(int i=0;i<nbOfTuple1;i++)
10638         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10639       ret->copyStringInfoFrom(*a1);
10640       return ret.retn();
10641     }
10642   else
10643     {
10644       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10645       return 0;
10646     }
10647 }
10648
10649 /*!
10650  * Divide values of \a this array by values of another DataArrayInt. There are 3
10651  * valid cases.
10652  * 1.  The arrays have same number of tuples and components. Then each value of
10653  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10654  *   _a_ [ i, j ] /= _other_ [ i, j ].
10655  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10656  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10657  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10658  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10659  *
10660  *  \warning No check of division by zero is performed!
10661  *  \param [in] other - an array to divide \a this one by.
10662  *  \throw If \a other is NULL.
10663  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10664  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10665  *         \a other has number of both tuples and components not equal to 1.
10666  */
10667 void DataArrayInt::divideEqual(const DataArrayInt *other)
10668 {
10669   if(!other)
10670     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10671   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10672   checkAllocated(); other->checkAllocated();
10673   int nbOfTuple=getNumberOfTuples();
10674   int nbOfTuple2=other->getNumberOfTuples();
10675   int nbOfComp=getNumberOfComponents();
10676   int nbOfComp2=other->getNumberOfComponents();
10677   if(nbOfTuple==nbOfTuple2)
10678     {
10679       if(nbOfComp==nbOfComp2)
10680         {
10681           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10682         }
10683       else if(nbOfComp2==1)
10684         {
10685           int *ptr=getPointer();
10686           const int *ptrc=other->getConstPointer();
10687           for(int i=0;i<nbOfTuple;i++)
10688             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10689         }
10690       else
10691         throw INTERP_KERNEL::Exception(msg);
10692     }
10693   else if(nbOfTuple2==1)
10694     {
10695       if(nbOfComp2==nbOfComp)
10696         {
10697           int *ptr=getPointer();
10698           const int *ptrc=other->getConstPointer();
10699           for(int i=0;i<nbOfTuple;i++)
10700             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10701         }
10702       else
10703         throw INTERP_KERNEL::Exception(msg);
10704     }
10705   else
10706     throw INTERP_KERNEL::Exception(msg);
10707   declareAsNew();
10708 }
10709
10710
10711 /*!
10712  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10713  * valid cases.
10714  * 1.  The arrays have same number of tuples and components. Then each value of
10715  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10716  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10717  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10718  *   component. Then
10719  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10720  * 3.  The arrays have same number of components and one array, say _a2_, has one
10721  *   tuple. Then
10722  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10723  *
10724  * Info on components is copied either from the first array (in the first case) or from
10725  * the array with maximal number of elements (getNbOfElems()).
10726  *  \warning No check of division by zero is performed!
10727  *  \param [in] a1 - a dividend array.
10728  *  \param [in] a2 - a divisor array.
10729  *  \return DataArrayInt * - the new instance of DataArrayInt.
10730  *          The caller is to delete this result array using decrRef() as it is no more
10731  *          needed.
10732  *  \throw If either \a a1 or \a a2 is NULL.
10733  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10734  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10735  *         none of them has number of tuples or components equal to 1.
10736  */
10737 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10738 {
10739     if(!a1 || !a2)
10740     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10741   int nbOfTuple1=a1->getNumberOfTuples();
10742   int nbOfTuple2=a2->getNumberOfTuples();
10743   int nbOfComp1=a1->getNumberOfComponents();
10744   int nbOfComp2=a2->getNumberOfComponents();
10745   if(nbOfTuple2==nbOfTuple1)
10746     {
10747       if(nbOfComp1==nbOfComp2)
10748         {
10749           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10750           ret->alloc(nbOfTuple2,nbOfComp1);
10751           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10752           ret->copyStringInfoFrom(*a1);
10753           return ret.retn();
10754         }
10755       else if(nbOfComp2==1)
10756         {
10757           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10758           ret->alloc(nbOfTuple1,nbOfComp1);
10759           const int *a2Ptr=a2->getConstPointer();
10760           const int *a1Ptr=a1->getConstPointer();
10761           int *res=ret->getPointer();
10762           for(int i=0;i<nbOfTuple1;i++)
10763             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10764           ret->copyStringInfoFrom(*a1);
10765           return ret.retn();
10766         }
10767       else
10768         {
10769           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10770           return 0;
10771         }
10772     }
10773   else if(nbOfTuple2==1)
10774     {
10775       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10776       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10777       ret->alloc(nbOfTuple1,nbOfComp1);
10778       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10779       int *pt=ret->getPointer();
10780       for(int i=0;i<nbOfTuple1;i++)
10781         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10782       ret->copyStringInfoFrom(*a1);
10783       return ret.retn();
10784     }
10785   else
10786     {
10787       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10788       return 0;
10789     }
10790 }
10791
10792 /*!
10793  * Modify \a this array so that each value becomes a modulus of division of this value by
10794  * a value of another DataArrayInt. There are 3 valid cases.
10795  * 1.  The arrays have same number of tuples and components. Then each value of
10796  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10797  *   _a_ [ i, j ] %= _other_ [ i, j ].
10798  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10799  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10800  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10801  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10802  *
10803  *  \warning No check of division by zero is performed!
10804  *  \param [in] other - a divisor array.
10805  *  \throw If \a other is NULL.
10806  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10807  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10808  *         \a other has number of both tuples and components not equal to 1.
10809  */
10810 void DataArrayInt::modulusEqual(const DataArrayInt *other)
10811 {
10812   if(!other)
10813     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10814   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10815   checkAllocated(); other->checkAllocated();
10816   int nbOfTuple=getNumberOfTuples();
10817   int nbOfTuple2=other->getNumberOfTuples();
10818   int nbOfComp=getNumberOfComponents();
10819   int nbOfComp2=other->getNumberOfComponents();
10820   if(nbOfTuple==nbOfTuple2)
10821     {
10822       if(nbOfComp==nbOfComp2)
10823         {
10824           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10825         }
10826       else if(nbOfComp2==1)
10827         {
10828           if(nbOfComp2==nbOfComp)
10829             {
10830               int *ptr=getPointer();
10831               const int *ptrc=other->getConstPointer();
10832               for(int i=0;i<nbOfTuple;i++)
10833                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10834             }
10835           else
10836             throw INTERP_KERNEL::Exception(msg);
10837         }
10838       else
10839         throw INTERP_KERNEL::Exception(msg);
10840     }
10841   else if(nbOfTuple2==1)
10842     {
10843       int *ptr=getPointer();
10844       const int *ptrc=other->getConstPointer();
10845       for(int i=0;i<nbOfTuple;i++)
10846         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10847     }
10848   else
10849     throw INTERP_KERNEL::Exception(msg);
10850   declareAsNew();
10851 }
10852
10853 /*!
10854  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10855  * valid cases.
10856  *
10857  *  \param [in] a1 - an array to pow up.
10858  *  \param [in] a2 - another array to sum up.
10859  *  \return DataArrayInt * - the new instance of DataArrayInt.
10860  *          The caller is to delete this result array using decrRef() as it is no more
10861  *          needed.
10862  *  \throw If either \a a1 or \a a2 is NULL.
10863  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10864  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10865  *  \throw If there is a negative value in \a a2.
10866  */
10867 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
10868 {
10869   if(!a1 || !a2)
10870     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10871   int nbOfTuple=a1->getNumberOfTuples();
10872   int nbOfTuple2=a2->getNumberOfTuples();
10873   int nbOfComp=a1->getNumberOfComponents();
10874   int nbOfComp2=a2->getNumberOfComponents();
10875   if(nbOfTuple!=nbOfTuple2)
10876     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10877   if(nbOfComp!=1 || nbOfComp2!=1)
10878     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10879   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10880   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10881   int *ptr=ret->getPointer();
10882   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10883     {
10884       if(*ptr2>=0)
10885         {
10886           int tmp=1;
10887           for(int j=0;j<*ptr2;j++)
10888             tmp*=*ptr1;
10889           *ptr=tmp;
10890         }
10891       else
10892         {
10893           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10894           throw INTERP_KERNEL::Exception(oss.str().c_str());
10895         }
10896     }
10897   return ret.retn();
10898 }
10899
10900 /*!
10901  * Apply pow on values of another DataArrayInt to values of \a this one.
10902  *
10903  *  \param [in] other - an array to pow to \a this one.
10904  *  \throw If \a other is NULL.
10905  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10906  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10907  *  \throw If there is a negative value in \a other.
10908  */
10909 void DataArrayInt::powEqual(const DataArrayInt *other)
10910 {
10911   if(!other)
10912     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10913   int nbOfTuple=getNumberOfTuples();
10914   int nbOfTuple2=other->getNumberOfTuples();
10915   int nbOfComp=getNumberOfComponents();
10916   int nbOfComp2=other->getNumberOfComponents();
10917   if(nbOfTuple!=nbOfTuple2)
10918     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10919   if(nbOfComp!=1 || nbOfComp2!=1)
10920     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10921   int *ptr=getPointer();
10922   const int *ptrc=other->begin();
10923   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10924     {
10925       if(*ptrc>=0)
10926         {
10927           int tmp=1;
10928           for(int j=0;j<*ptrc;j++)
10929             tmp*=*ptr;
10930           *ptr=tmp;
10931         }
10932       else
10933         {
10934           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10935           throw INTERP_KERNEL::Exception(oss.str().c_str());
10936         }
10937     }
10938   declareAsNew();
10939 }
10940
10941 /*!
10942  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10943  * This map, if applied to \a start array, would make it sorted. For example, if
10944  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10945  * [5,6,0,3,2,7,1,4].
10946  *  \param [in] start - pointer to the first element of the array for which the
10947  *         permutation map is computed.
10948  *  \param [in] end - pointer specifying the end of the array \a start, so that
10949  *         the last value of \a start is \a end[ -1 ].
10950  *  \return int * - the result permutation array that the caller is to delete as it is no
10951  *         more needed.
10952  *  \throw If there are equal values in the input array.
10953  */
10954 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10955 {
10956   std::size_t sz=std::distance(start,end);
10957   int *ret=(int *)malloc(sz*sizeof(int));
10958   int *work=new int[sz];
10959   std::copy(start,end,work);
10960   std::sort(work,work+sz);
10961   if(std::unique(work,work+sz)!=work+sz)
10962     {
10963       delete [] work;
10964       free(ret);
10965       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10966     }
10967   std::map<int,int> m;
10968   for(int *workPt=work;workPt!=work+sz;workPt++)
10969     m[*workPt]=(int)std::distance(work,workPt);
10970   int *iter2=ret;
10971   for(const int *iter=start;iter!=end;iter++,iter2++)
10972     *iter2=m[*iter];
10973   delete [] work;
10974   return ret;
10975 }
10976
10977 /*!
10978  * Returns a new DataArrayInt containing an arithmetic progression
10979  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10980  * function.
10981  *  \param [in] begin - the start value of the result sequence.
10982  *  \param [in] end - limiting value, so that every value of the result array is less than
10983  *              \a end.
10984  *  \param [in] step - specifies the increment or decrement.
10985  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10986  *          array using decrRef() as it is no more needed.
10987  *  \throw If \a step == 0.
10988  *  \throw If \a end < \a begin && \a step > 0.
10989  *  \throw If \a end > \a begin && \a step < 0.
10990  */
10991 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
10992 {
10993   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10994   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10995   ret->alloc(nbOfTuples,1);
10996   int *ptr=ret->getPointer();
10997   if(step>0)
10998     {
10999       for(int i=begin;i<end;i+=step,ptr++)
11000         *ptr=i;
11001     }
11002   else
11003     {
11004       for(int i=begin;i>end;i+=step,ptr++)
11005         *ptr=i;
11006     }
11007   return ret.retn();
11008 }
11009
11010 /*!
11011  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11012  * Server side.
11013  */
11014 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11015 {
11016   tinyInfo.resize(2);
11017   if(isAllocated())
11018     {
11019       tinyInfo[0]=getNumberOfTuples();
11020       tinyInfo[1]=getNumberOfComponents();
11021     }
11022   else
11023     {
11024       tinyInfo[0]=-1;
11025       tinyInfo[1]=-1;
11026     }
11027 }
11028
11029 /*!
11030  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11031  * Server side.
11032  */
11033 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11034 {
11035   if(isAllocated())
11036     {
11037       int nbOfCompo=getNumberOfComponents();
11038       tinyInfo.resize(nbOfCompo+1);
11039       tinyInfo[0]=getName();
11040       for(int i=0;i<nbOfCompo;i++)
11041         tinyInfo[i+1]=getInfoOnComponent(i);
11042     }
11043   else
11044     {
11045       tinyInfo.resize(1);
11046       tinyInfo[0]=getName();
11047     }
11048 }
11049
11050 /*!
11051  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11052  * This method returns if a feeding is needed.
11053  */
11054 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11055 {
11056   int nbOfTuple=tinyInfoI[0];
11057   int nbOfComp=tinyInfoI[1];
11058   if(nbOfTuple!=-1 || nbOfComp!=-1)
11059     {
11060       alloc(nbOfTuple,nbOfComp);
11061       return true;
11062     }
11063   return false;
11064 }
11065
11066 /*!
11067  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11068  * This method returns if a feeding is needed.
11069  */
11070 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11071 {
11072   setName(tinyInfoS[0].c_str());
11073   if(isAllocated())
11074     {
11075       int nbOfCompo=tinyInfoI[1];
11076       for(int i=0;i<nbOfCompo;i++)
11077         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
11078     }
11079 }
11080
11081 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11082 {
11083   if(_da)
11084     {
11085       _da->incrRef();
11086       if(_da->isAllocated())
11087         {
11088           _nb_comp=da->getNumberOfComponents();
11089           _nb_tuple=da->getNumberOfTuples();
11090           _pt=da->getPointer();
11091         }
11092     }
11093 }
11094
11095 DataArrayIntIterator::~DataArrayIntIterator()
11096 {
11097   if(_da)
11098     _da->decrRef();
11099 }
11100
11101 DataArrayIntTuple *DataArrayIntIterator::nextt()
11102 {
11103   if(_tuple_id<_nb_tuple)
11104     {
11105       _tuple_id++;
11106       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11107       _pt+=_nb_comp;
11108       return ret;
11109     }
11110   else
11111     return 0;
11112 }
11113
11114 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11115 {
11116 }
11117
11118 std::string DataArrayIntTuple::repr() const
11119 {
11120   std::ostringstream oss; oss << "(";
11121   for(int i=0;i<_nb_of_compo-1;i++)
11122     oss << _pt[i] << ", ";
11123   oss << _pt[_nb_of_compo-1] << ")";
11124   return oss.str();
11125 }
11126
11127 int DataArrayIntTuple::intValue() const
11128 {
11129   if(_nb_of_compo==1)
11130     return *_pt;
11131   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11132 }
11133
11134 /*!
11135  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11136  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11137  * 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
11138  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11139  */
11140 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11141 {
11142   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11143     {
11144       DataArrayInt *ret=DataArrayInt::New();
11145       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11146       return ret;
11147     }
11148   else
11149     {
11150       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11151       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11152       throw INTERP_KERNEL::Exception(oss.str().c_str());
11153     }
11154 }