Salome HOME
MEDCouplingUMesh::computePlaneEquationOf3DFaces method to localize warpped faces
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildren() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const char *name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const char *varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
427  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
428  * the number of component in the result array is same as that of each of given arrays.
429  * Info on components is copied from the first of the given arrays. Number of components
430  * in the given arrays must be  the same.
431  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
432  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
433  *          The caller is to delete this result array using decrRef() as it is no more
434  *          needed.
435  *  \throw If all arrays within \a arrs are NULL.
436  *  \throw If all not null arrays in \a arrs have not the same type.
437  *  \throw If getNumberOfComponents() of arrays within \a arrs.
438  */
439 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
440 {
441   std::vector<const DataArray *> arr2;
442   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
443     if(*it)
444       arr2.push_back(*it);
445   if(arr2.empty())
446     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
447   std::vector<const DataArrayDouble *> arrd;
448   std::vector<const DataArrayInt *> arri;
449   std::vector<const DataArrayChar *> arrc;
450   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
451     {
452       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
453       if(a)
454         { arrd.push_back(a); continue; }
455       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
456       if(b)
457         { arri.push_back(b); continue; }
458       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
459       if(c)
460         { arrc.push_back(c); continue; }
461       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
462     }
463   if(arr2.size()==arrd.size())
464     return DataArrayDouble::Aggregate(arrd);
465   if(arr2.size()==arri.size())
466     return DataArrayInt::Aggregate(arri);
467   if(arr2.size()==arrc.size())
468     return DataArrayChar::Aggregate(arrc);
469   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
470 }
471
472 /*!
473  * Sets information on a component specified by an index.
474  * To know more on format of this information
475  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
476  *  \warning Don't pass NULL as \a info!
477  *  \param [in] i - the index (zero based) of the component of interest.
478  *  \param [in] info - the string containing the information.
479  *  \throw If \a i is not a valid component index.
480  */
481 void DataArray::setInfoOnComponent(int i, const char *info)
482 {
483   if(i<(int)_info_on_compo.size() && i>=0)
484     _info_on_compo[i]=info;
485   else
486     {
487       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
488       throw INTERP_KERNEL::Exception(oss.str().c_str());
489     }
490 }
491
492 /*!
493  * Sets information on all components. This method can change number of components
494  * at certain conditions; if the conditions are not respected, an exception is thrown.
495  * The number of components can be changed in \a this only if \a this is not allocated.
496  * The condition of number of components must not be changed.
497  *
498  * To know more on format of the component information see
499  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
500  *  \param [in] info - a vector of component infos.
501  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
502  */
503 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
504 {
505   if(getNumberOfComponents()!=(int)info.size())
506     {
507       if(!isAllocated())
508         _info_on_compo=info;
509       else
510         {
511           std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
512           throw INTERP_KERNEL::Exception(oss.str().c_str());
513         }
514     }
515   else
516     _info_on_compo=info;
517 }
518
519 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const
520 {
521   if(getNumberOfTuples()!=nbOfTuples)
522     {
523       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
524       throw INTERP_KERNEL::Exception(oss.str().c_str());
525     }
526 }
527
528 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const
529 {
530   if(getNumberOfComponents()!=nbOfCompo)
531     {
532       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
533       throw INTERP_KERNEL::Exception(oss.str().c_str());
534     }
535 }
536
537 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const
538 {
539   if(getNbOfElems()!=nbOfElems)
540     {
541       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
542       throw INTERP_KERNEL::Exception(oss.str().c_str());
543     }
544 }
545
546 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const
547 {
548    if(getNumberOfTuples()!=other.getNumberOfTuples())
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553   if(getNumberOfComponents()!=other.getNumberOfComponents())
554     {
555       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
556       throw INTERP_KERNEL::Exception(oss.str().c_str());
557     }
558 }
559
560 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const
561 {
562   checkNbOfTuples(nbOfTuples,msg);
563   checkNbOfComps(nbOfCompo,msg);
564 }
565
566 /*!
567  * Simply this method checks that \b value is in [0,\b ref).
568  */
569 void DataArray::CheckValueInRange(int ref, int value, const char *msg)
570 {
571   if(value<0 || value>=ref)
572     {
573       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
574       throw INTERP_KERNEL::Exception(oss.str().c_str());
575     }
576 }
577
578 /*!
579  * This method checks that [\b start, \b end) is compliant with ref length \b value.
580  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
581  */
582 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg)
583 {
584   if(start<0 || start>=value)
585     {
586       if(value!=start || end!=start)
587         {
588           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
589           throw INTERP_KERNEL::Exception(oss.str().c_str());
590         }
591     }
592   if(end<0 || end>value)
593     {
594       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
595       throw INTERP_KERNEL::Exception(oss.str().c_str());
596     }
597 }
598
599 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg)
600 {
601   if(value<0 || value>ref)
602     {
603       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
604       throw INTERP_KERNEL::Exception(oss.str().c_str());
605     }
606 }
607
608 /*!
609  * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, 
610  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
611  *
612  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
613  *
614  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
615  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
616  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
617  * \param [in] sliceId - the slice id considered
618  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
619  * \param [out] startSlice - the start of the slice considered
620  * \param [out] stopSlice - the stop of the slice consided
621  * 
622  * \throw If \a step == 0
623  * \throw If \a nbOfSlices not > 0
624  * \throw If \a sliceId not in [0,nbOfSlices)
625  */
626 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
627 {
628   if(nbOfSlices<=0)
629     {
630       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633   if(sliceId<0 || sliceId>=nbOfSlices)
634     {
635       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
636       throw INTERP_KERNEL::Exception(oss.str().c_str());
637     }
638   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
639   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
640   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
641   if(sliceId<nbOfSlices-1)
642     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
643   else
644     stopSlice=stop;
645 }
646
647 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg)
648 {
649   if(end<begin)
650     {
651       std::ostringstream oss; oss << msg << " : end before begin !";
652       throw INTERP_KERNEL::Exception(oss.str().c_str());
653     }
654   if(end==begin)
655     return 0;
656   if(step<=0)
657     {
658       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
659       throw INTERP_KERNEL::Exception(oss.str().c_str());
660     }
661   return (end-1-begin)/step+1;
662 }
663
664 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg)
665 {
666   if(step==0)
667     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
668   if(end<begin && step>0)
669     {
670       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   if(begin<end && step<0)
674     {
675       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
676       throw INTERP_KERNEL::Exception(oss.str().c_str());
677     }
678   if(begin!=end)
679     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
680   else
681     return 0;
682 }
683
684 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
685 {
686   if(step!=0)
687     {
688       if(step>0)
689         {
690           if(begin<=value && value<end)
691             {
692               if((value-begin)%step==0)
693                 return (value-begin)/step;
694               else
695                 return -1;
696             }
697           else
698             return -1;
699         }
700       else
701         {
702           if(begin>=value && value>end)
703             {
704               if((begin-value)%(-step)==0)
705                 return (begin-value)/(-step);
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712     }
713   else
714     return -1;
715 }
716
717 /*!
718  * Returns a new instance of DataArrayDouble. The caller is to delete this array
719  * using decrRef() as it is no more needed. 
720  */
721 DataArrayDouble *DataArrayDouble::New()
722 {
723   return new DataArrayDouble;
724 }
725
726 /*!
727  * Checks if raw data is allocated. Read more on the raw data
728  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
729  *  \return bool - \a true if the raw data is allocated, \a false else.
730  */
731 bool DataArrayDouble::isAllocated() const
732 {
733   return getConstPointer()!=0;
734 }
735
736 /*!
737  * Checks if raw data is allocated and throws an exception if it is not the case.
738  *  \throw If the raw data is not allocated.
739  */
740 void DataArrayDouble::checkAllocated() const
741 {
742   if(!isAllocated())
743     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
744 }
745
746 /*!
747  * This method desallocated \a this without modification of informations relative to the components.
748  * After call of this method, DataArrayDouble::isAllocated will return false.
749  * If \a this is already not allocated, \a this is let unchanged.
750  */
751 void DataArrayDouble::desallocate()
752 {
753   _mem.destroy();
754 }
755
756 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
757 {
758   std::size_t sz(_mem.getNbOfElemAllocated());
759   sz*=sizeof(double);
760   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
761 }
762
763 /*!
764  * Returns the only one value in \a this, if and only if number of elements
765  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
766  *  \return double - the sole value stored in \a this array.
767  *  \throw If at least one of conditions stated above is not fulfilled.
768  */
769 double DataArrayDouble::doubleValue() const
770 {
771   if(isAllocated())
772     {
773       if(getNbOfElems()==1)
774         {
775           return *getConstPointer();
776         }
777       else
778         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
779     }
780   else
781     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
782 }
783
784 /*!
785  * Checks the number of tuples.
786  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
787  *  \throw If \a this is not allocated.
788  */
789 bool DataArrayDouble::empty() const
790 {
791   checkAllocated();
792   return getNumberOfTuples()==0;
793 }
794
795 /*!
796  * Returns a full copy of \a this. For more info on copying data arrays see
797  * \ref MEDCouplingArrayBasicsCopyDeep.
798  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
799  *          delete this array using decrRef() as it is no more needed. 
800  */
801 DataArrayDouble *DataArrayDouble::deepCpy() const
802 {
803   return new DataArrayDouble(*this);
804 }
805
806 /*!
807  * Returns either a \a deep or \a shallow copy of this array. For more info see
808  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
809  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
810  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
811  *          == \a true) or \a this instance (if \a dCpy == \a false).
812  */
813 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
814 {
815   if(dCpy)
816     return deepCpy();
817   else
818     {
819       incrRef();
820       return const_cast<DataArrayDouble *>(this);
821     }
822 }
823
824 /*!
825  * Copies all the data from another DataArrayDouble. For more info see
826  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
827  *  \param [in] other - another instance of DataArrayDouble to copy data from.
828  *  \throw If the \a other is not allocated.
829  */
830 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
831 {
832   other.checkAllocated();
833   int nbOfTuples=other.getNumberOfTuples();
834   int nbOfComp=other.getNumberOfComponents();
835   allocIfNecessary(nbOfTuples,nbOfComp);
836   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
837   double *pt=getPointer();
838   const double *ptI=other.getConstPointer();
839   for(std::size_t i=0;i<nbOfElems;i++)
840     pt[i]=ptI[i];
841   copyStringInfoFrom(other);
842 }
843
844 /*!
845  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
846  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
847  * If \a this has not already been allocated, number of components is set to one.
848  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
849  * 
850  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
851  */
852 void DataArrayDouble::reserve(std::size_t nbOfElems)
853 {
854   int nbCompo=getNumberOfComponents();
855   if(nbCompo==1)
856     {
857       _mem.reserve(nbOfElems);
858     }
859   else if(nbCompo==0)
860     {
861       _mem.reserve(nbOfElems);
862       _info_on_compo.resize(1);
863     }
864   else
865     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
866 }
867
868 /*!
869  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
870  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
871  *
872  * \param [in] val the value to be added in \a this
873  * \throw If \a this has already been allocated with number of components different from one.
874  * \sa DataArrayDouble::pushBackValsSilent
875  */
876 void DataArrayDouble::pushBackSilent(double val)
877 {
878   int nbCompo=getNumberOfComponents();
879   if(nbCompo==1)
880     _mem.pushBack(val);
881   else if(nbCompo==0)
882     {
883       _info_on_compo.resize(1);
884       _mem.pushBack(val);
885     }
886   else
887     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
888 }
889
890 /*!
891  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
892  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
893  *
894  *  \param [in] valsBg - an array of values to push at the end of \this.
895  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
896  *              the last value of \a valsBg is \a valsEnd[ -1 ].
897  * \throw If \a this has already been allocated with number of components different from one.
898  * \sa DataArrayDouble::pushBackSilent
899  */
900 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
901 {
902   int nbCompo=getNumberOfComponents();
903   if(nbCompo==1)
904     _mem.insertAtTheEnd(valsBg,valsEnd);
905   else if(nbCompo==0)
906     {
907       _info_on_compo.resize(1);
908       _mem.insertAtTheEnd(valsBg,valsEnd);
909     }
910   else
911     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
912 }
913
914 /*!
915  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
916  * \throw If \a this is already empty.
917  * \throw If \a this has number of components different from one.
918  */
919 double DataArrayDouble::popBackSilent()
920 {
921   if(getNumberOfComponents()==1)
922     return _mem.popBack();
923   else
924     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
925 }
926
927 /*!
928  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
929  *
930  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
931  */
932 void DataArrayDouble::pack() const
933 {
934   _mem.pack();
935 }
936
937 /*!
938  * Allocates the raw data in memory. If exactly same memory as needed already
939  * allocated, it is not re-allocated.
940  *  \param [in] nbOfTuple - number of tuples of data to allocate.
941  *  \param [in] nbOfCompo - number of components of data to allocate.
942  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
943  */
944 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
945 {
946   if(isAllocated())
947     {
948       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
949         alloc(nbOfTuple,nbOfCompo);
950     }
951   else
952     alloc(nbOfTuple,nbOfCompo);
953 }
954
955 /*!
956  * Allocates the raw data in memory. If the memory was already allocated, then it is
957  * freed and re-allocated. See an example of this method use
958  * \ref MEDCouplingArraySteps1WC "here".
959  *  \param [in] nbOfTuple - number of tuples of data to allocate.
960  *  \param [in] nbOfCompo - number of components of data to allocate.
961  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
962  */
963 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
964 {
965   if(nbOfTuple<0 || nbOfCompo<0)
966     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
967   _info_on_compo.resize(nbOfCompo);
968   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
969   declareAsNew();
970 }
971
972 /*!
973  * Assign zero to all values in \a this array. To know more on filling arrays see
974  * \ref MEDCouplingArrayFill.
975  * \throw If \a this is not allocated.
976  */
977 void DataArrayDouble::fillWithZero()
978 {
979   checkAllocated();
980   _mem.fillWithValue(0.);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign \a val to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  *  \param [in] val - the value to fill with.
988  *  \throw If \a this is not allocated.
989  */
990 void DataArrayDouble::fillWithValue(double val)
991 {
992   checkAllocated();
993   _mem.fillWithValue(val);
994   declareAsNew();
995 }
996
997 /*!
998  * Set all values in \a this array so that the i-th element equals to \a init + i
999  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1000  *  \param [in] init - value to assign to the first element of array.
1001  *  \throw If \a this->getNumberOfComponents() != 1
1002  *  \throw If \a this is not allocated.
1003  */
1004 void DataArrayDouble::iota(double init)
1005 {
1006   checkAllocated();
1007   if(getNumberOfComponents()!=1)
1008     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1009   double *ptr=getPointer();
1010   int ntuples=getNumberOfTuples();
1011   for(int i=0;i<ntuples;i++)
1012     ptr[i]=init+double(i);
1013   declareAsNew();
1014 }
1015
1016 /*!
1017  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1018  *  \param [in] val - value to check equality of array values to.
1019  *  \param [in] eps - precision to check the equality.
1020  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1021  *                 \a false else.
1022  *  \throw If \a this->getNumberOfComponents() != 1
1023  *  \throw If \a this is not allocated.
1024  */
1025 bool DataArrayDouble::isUniform(double val, double eps) const
1026 {
1027   checkAllocated();
1028   if(getNumberOfComponents()!=1)
1029     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1030   int nbOfTuples=getNumberOfTuples();
1031   const double *w=getConstPointer();
1032   const double *end2=w+nbOfTuples;
1033   const double vmin=val-eps;
1034   const double vmax=val+eps;
1035   for(;w!=end2;w++)
1036     if(*w<vmin || *w>vmax)
1037       return false;
1038   return true;
1039 }
1040
1041 /*!
1042  * Sorts values of the array.
1043  *  \param [in] asc - \a true means ascending order, \a false, descending.
1044  *  \throw If \a this is not allocated.
1045  *  \throw If \a this->getNumberOfComponents() != 1.
1046  */
1047 void DataArrayDouble::sort(bool asc)
1048 {
1049   checkAllocated();
1050   if(getNumberOfComponents()!=1)
1051     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1052   _mem.sort(asc);
1053   declareAsNew();
1054 }
1055
1056 /*!
1057  * Reverse the array values.
1058  *  \throw If \a this->getNumberOfComponents() < 1.
1059  *  \throw If \a this is not allocated.
1060  */
1061 void DataArrayDouble::reverse()
1062 {
1063   checkAllocated();
1064   _mem.reverse(getNumberOfComponents());
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1070  * with at least absolute difference value of |\a eps| at each step.
1071  * If not an exception is thrown.
1072  *  \param [in] increasing - if \a true, the array values should be increasing.
1073  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1074  *                    the values are considered different.
1075  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1076  *         increasing arg.
1077  *  \throw If \a this->getNumberOfComponents() != 1.
1078  *  \throw If \a this is not allocated.
1079  */
1080 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1081 {
1082   if(!isMonotonic(increasing,eps))
1083     {
1084       if (increasing)
1085         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1086       else
1087         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1088     }
1089 }
1090
1091 /*!
1092  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1093  * with at least absolute difference value of |\a eps| at each step.
1094  *  \param [in] increasing - if \a true, array values should be increasing.
1095  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1096  *                    the values are considered different.
1097  *  \return bool - \a true if values change in accordance with \a increasing arg.
1098  *  \throw If \a this->getNumberOfComponents() != 1.
1099  *  \throw If \a this is not allocated.
1100  */
1101 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1102 {
1103   checkAllocated();
1104   if(getNumberOfComponents()!=1)
1105     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1106   int nbOfElements=getNumberOfTuples();
1107   const double *ptr=getConstPointer();
1108   if(nbOfElements==0)
1109     return true;
1110   double ref=ptr[0];
1111   double absEps=fabs(eps);
1112   if(increasing)
1113     {
1114       for(int i=1;i<nbOfElements;i++)
1115         {
1116           if(ptr[i]<(ref+absEps))
1117             return false;
1118           ref=ptr[i];
1119         }
1120       return true;
1121     }
1122   else
1123     {
1124       for(int i=1;i<nbOfElements;i++)
1125         {
1126           if(ptr[i]>(ref-absEps))
1127             return false;
1128           ref=ptr[i];
1129         }
1130       return true;
1131     }
1132 }
1133
1134 /*!
1135  * Returns a textual and human readable representation of \a this instance of
1136  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1137  *  \return std::string - text describing \a this DataArrayDouble.
1138  */
1139 std::string DataArrayDouble::repr() const
1140 {
1141   std::ostringstream ret;
1142   reprStream(ret);
1143   return ret.str();
1144 }
1145
1146 std::string DataArrayDouble::reprZip() const
1147 {
1148   std::ostringstream ret;
1149   reprZipStream(ret);
1150   return ret.str();
1151 }
1152
1153 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile, DataArrayByte *byteArr) const
1154 {
1155   static const char SPACE[4]={' ',' ',' ',' '};
1156   checkAllocated();
1157   std::string idt(indent,' ');
1158   ofs.precision(17);
1159   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1160   if(byteArr)
1161     {
1162       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1163       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1164       float *pt(tmp);
1165       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1166       for(const double *src=begin();src!=end();src++,pt++)
1167         *pt=float(*src);
1168       const char *data(reinterpret_cast<const char *>((float *)tmp));
1169       std::size_t sz(getNbOfElems()*sizeof(float));
1170       byteArr->insertAtTheEnd(data,data+sz);
1171       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1172     }
1173   else
1174     {
1175       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1176       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1177     }
1178   ofs << std::endl << idt << "</DataArray>\n";
1179 }
1180
1181 void DataArrayDouble::reprStream(std::ostream& stream) const
1182 {
1183   stream << "Name of double array : \"" << _name << "\"\n";
1184   reprWithoutNameStream(stream);
1185 }
1186
1187 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1188 {
1189   stream << "Name of double array : \"" << _name << "\"\n";
1190   reprZipWithoutNameStream(stream);
1191 }
1192
1193 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1194 {
1195   DataArray::reprWithoutNameStream(stream);
1196   stream.precision(17);
1197   _mem.repr(getNumberOfComponents(),stream);
1198 }
1199
1200 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1201 {
1202   DataArray::reprWithoutNameStream(stream);
1203   stream.precision(17);
1204   _mem.reprZip(getNumberOfComponents(),stream);
1205 }
1206
1207 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const
1208 {
1209   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1210   const double *data=getConstPointer();
1211   stream.precision(17);
1212   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1213   if(nbTuples*nbComp>=1)
1214     {
1215       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1216       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1217       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1218       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1219     }
1220   else
1221     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1222   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1223 }
1224
1225 /*!
1226  * Method that gives a quick overvien of \a this for python.
1227  */
1228 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1229 {
1230   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1231   stream << "DataArrayDouble C++ instance at " << this << ". ";
1232   if(isAllocated())
1233     {
1234       int nbOfCompo=(int)_info_on_compo.size();
1235       if(nbOfCompo>=1)
1236         {
1237           int nbOfTuples=getNumberOfTuples();
1238           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1239           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1240         }
1241       else
1242         stream << "Number of components : 0.";
1243     }
1244   else
1245     stream << "*** No data allocated ****";
1246 }
1247
1248 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1249 {
1250   const double *data=begin();
1251   int nbOfTuples=getNumberOfTuples();
1252   int nbOfCompo=(int)_info_on_compo.size();
1253   std::ostringstream oss2; oss2 << "[";
1254   oss2.precision(17);
1255   std::string oss2Str(oss2.str());
1256   bool isFinished=true;
1257   for(int i=0;i<nbOfTuples && isFinished;i++)
1258     {
1259       if(nbOfCompo>1)
1260         {
1261           oss2 << "(";
1262           for(int j=0;j<nbOfCompo;j++,data++)
1263             {
1264               oss2 << *data;
1265               if(j!=nbOfCompo-1) oss2 << ", ";
1266             }
1267           oss2 << ")";
1268         }
1269       else
1270         oss2 << *data++;
1271       if(i!=nbOfTuples-1) oss2 << ", ";
1272       std::string oss3Str(oss2.str());
1273       if(oss3Str.length()<maxNbOfByteInRepr)
1274         oss2Str=oss3Str;
1275       else
1276         isFinished=false;
1277     }
1278   stream << oss2Str;
1279   if(!isFinished)
1280     stream << "... ";
1281   stream << "]";
1282 }
1283
1284 /*!
1285  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1286  * mismatch is given.
1287  * 
1288  * \param [in] other the instance to be compared with \a this
1289  * \param [in] prec the precision to compare numeric data of the arrays.
1290  * \param [out] reason In case of inequality returns the reason.
1291  * \sa DataArrayDouble::isEqual
1292  */
1293 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1294 {
1295   if(!areInfoEqualsIfNotWhy(other,reason))
1296     return false;
1297   return _mem.isEqual(other._mem,prec,reason);
1298 }
1299
1300 /*!
1301  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1302  * \ref MEDCouplingArrayBasicsCompare.
1303  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1304  *  \param [in] prec - precision value to compare numeric data of the arrays.
1305  *  \return bool - \a true if the two arrays are equal, \a false else.
1306  */
1307 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1308 {
1309   std::string tmp;
1310   return isEqualIfNotWhy(other,prec,tmp);
1311 }
1312
1313 /*!
1314  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1315  * \ref MEDCouplingArrayBasicsCompare.
1316  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1317  *  \param [in] prec - precision value to compare numeric data of the arrays.
1318  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1319  */
1320 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1321 {
1322   std::string tmp;
1323   return _mem.isEqual(other._mem,prec,tmp);
1324 }
1325
1326 /*!
1327  * Changes number of tuples in the array. If the new number of tuples is smaller
1328  * than the current number the array is truncated, otherwise the array is extended.
1329  *  \param [in] nbOfTuples - new number of tuples. 
1330  *  \throw If \a this is not allocated.
1331  *  \throw If \a nbOfTuples is negative.
1332  */
1333 void DataArrayDouble::reAlloc(int nbOfTuples)
1334 {
1335   if(nbOfTuples<0)
1336     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1337   checkAllocated();
1338   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1339   declareAsNew();
1340 }
1341
1342 /*!
1343  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1344  * array to the new one.
1345  *  \return DataArrayInt * - the new instance of DataArrayInt.
1346  */
1347 DataArrayInt *DataArrayDouble::convertToIntArr() const
1348 {
1349   DataArrayInt *ret=DataArrayInt::New();
1350   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1351   std::size_t nbOfVals=getNbOfElems();
1352   int *dest=ret->getPointer();
1353   // to make Visual C++ happy : instead of std::copy(src,src+nbOfVals,dest);
1354   for(const double *src=begin();src!=end();src++,dest++)
1355     *dest=(int)*src;
1356   ret->copyStringInfoFrom(*this);
1357   return ret;
1358 }
1359
1360 /*!
1361  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1362  * arranged in memory. If \a this array holds 2 components of 3 values:
1363  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1364  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1365  *  \warning Do not confuse this method with transpose()!
1366  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1367  *          is to delete using decrRef() as it is no more needed.
1368  *  \throw If \a this is not allocated.
1369  */
1370 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1371 {
1372   if(_mem.isNull())
1373     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1374   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1375   DataArrayDouble *ret=DataArrayDouble::New();
1376   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1377   return ret;
1378 }
1379
1380 /*!
1381  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1382  * arranged in memory. If \a this array holds 2 components of 3 values:
1383  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1384  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1385  *  \warning Do not confuse this method with transpose()!
1386  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1387  *          is to delete using decrRef() as it is no more needed.
1388  *  \throw If \a this is not allocated.
1389  */
1390 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1391 {
1392   if(_mem.isNull())
1393     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1394   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1395   DataArrayDouble *ret=DataArrayDouble::New();
1396   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1397   return ret;
1398 }
1399
1400 /*!
1401  * Permutes values of \a this array as required by \a old2New array. The values are
1402  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1403  * the same as in \this one.
1404  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1405  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1406  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1407  *     giving a new position for i-th old value.
1408  */
1409 void DataArrayDouble::renumberInPlace(const int *old2New)
1410 {
1411   checkAllocated();
1412   int nbTuples=getNumberOfTuples();
1413   int nbOfCompo=getNumberOfComponents();
1414   double *tmp=new double[nbTuples*nbOfCompo];
1415   const double *iptr=getConstPointer();
1416   for(int i=0;i<nbTuples;i++)
1417     {
1418       int v=old2New[i];
1419       if(v>=0 && v<nbTuples)
1420         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1421       else
1422         {
1423           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1424           throw INTERP_KERNEL::Exception(oss.str().c_str());
1425         }
1426     }
1427   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1428   delete [] tmp;
1429   declareAsNew();
1430 }
1431
1432 /*!
1433  * Permutes values of \a this array as required by \a new2Old array. The values are
1434  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1435  * the same as in \this one.
1436  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1437  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1438  *     giving a previous position of i-th new value.
1439  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1440  *          is to delete using decrRef() as it is no more needed.
1441  */
1442 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1443 {
1444   checkAllocated();
1445   int nbTuples=getNumberOfTuples();
1446   int nbOfCompo=getNumberOfComponents();
1447   double *tmp=new double[nbTuples*nbOfCompo];
1448   const double *iptr=getConstPointer();
1449   for(int i=0;i<nbTuples;i++)
1450     {
1451       int v=new2Old[i];
1452       if(v>=0 && v<nbTuples)
1453         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1454       else
1455         {
1456           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1457           throw INTERP_KERNEL::Exception(oss.str().c_str());
1458         }
1459     }
1460   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1461   delete [] tmp;
1462   declareAsNew();
1463 }
1464
1465 /*!
1466  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1467  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1468  * Number of tuples in the result array remains the same as in \this one.
1469  * If a permutation reduction is needed, renumberAndReduce() should be used.
1470  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1471  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1472  *          giving a new position for i-th old value.
1473  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1474  *          is to delete using decrRef() as it is no more needed.
1475  *  \throw If \a this is not allocated.
1476  */
1477 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1478 {
1479   checkAllocated();
1480   int nbTuples=getNumberOfTuples();
1481   int nbOfCompo=getNumberOfComponents();
1482   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1483   ret->alloc(nbTuples,nbOfCompo);
1484   ret->copyStringInfoFrom(*this);
1485   const double *iptr=getConstPointer();
1486   double *optr=ret->getPointer();
1487   for(int i=0;i<nbTuples;i++)
1488     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1489   ret->copyStringInfoFrom(*this);
1490   return ret.retn();
1491 }
1492
1493 /*!
1494  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1495  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1496  * tuples in the result array remains the same as in \this one.
1497  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1498  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1499  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1500  *     giving a previous position of i-th new value.
1501  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1502  *          is to delete using decrRef() as it is no more needed.
1503  */
1504 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1505 {
1506   checkAllocated();
1507   int nbTuples=getNumberOfTuples();
1508   int nbOfCompo=getNumberOfComponents();
1509   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1510   ret->alloc(nbTuples,nbOfCompo);
1511   ret->copyStringInfoFrom(*this);
1512   const double *iptr=getConstPointer();
1513   double *optr=ret->getPointer();
1514   for(int i=0;i<nbTuples;i++)
1515     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1516   ret->copyStringInfoFrom(*this);
1517   return ret.retn();
1518 }
1519
1520 /*!
1521  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1522  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1523  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1524  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1525  * \a old2New[ i ] is negative, is missing from the result array.
1526  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1527  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1528  *     giving a new position for i-th old tuple and giving negative position for
1529  *     for i-th old tuple that should be omitted.
1530  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1531  *          is to delete using decrRef() as it is no more needed.
1532  */
1533 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1534 {
1535   checkAllocated();
1536   int nbTuples=getNumberOfTuples();
1537   int nbOfCompo=getNumberOfComponents();
1538   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1539   ret->alloc(newNbOfTuple,nbOfCompo);
1540   const double *iptr=getConstPointer();
1541   double *optr=ret->getPointer();
1542   for(int i=0;i<nbTuples;i++)
1543     {
1544       int w=old2New[i];
1545       if(w>=0)
1546         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1547     }
1548   ret->copyStringInfoFrom(*this);
1549   return ret.retn();
1550 }
1551
1552 /*!
1553  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1554  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1555  * \a new2OldBg array.
1556  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1557  * This method is equivalent to renumberAndReduce() except that convention in input is
1558  * \c new2old and \b not \c old2new.
1559  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1560  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1561  *              tuple index in \a this array to fill the i-th tuple in the new array.
1562  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1563  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1564  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1565  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1566  *          is to delete using decrRef() as it is no more needed.
1567  */
1568 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1569 {
1570   checkAllocated();
1571   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1572   int nbComp=getNumberOfComponents();
1573   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1574   ret->copyStringInfoFrom(*this);
1575   double *pt=ret->getPointer();
1576   const double *srcPt=getConstPointer();
1577   int i=0;
1578   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1579     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1580   ret->copyStringInfoFrom(*this);
1581   return ret.retn();
1582 }
1583
1584 /*!
1585  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1586  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1587  * \a new2OldBg array.
1588  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1589  * This method is equivalent to renumberAndReduce() except that convention in input is
1590  * \c new2old and \b not \c old2new.
1591  * This method is equivalent to selectByTupleId() except that it prevents coping data
1592  * from behind the end of \a this array.
1593  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1594  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1595  *              tuple index in \a this array to fill the i-th tuple in the new array.
1596  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1597  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1598  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1599  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1600  *          is to delete using decrRef() as it is no more needed.
1601  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1602  */
1603 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1604 {
1605   checkAllocated();
1606   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1607   int nbComp=getNumberOfComponents();
1608   int oldNbOfTuples=getNumberOfTuples();
1609   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1610   ret->copyStringInfoFrom(*this);
1611   double *pt=ret->getPointer();
1612   const double *srcPt=getConstPointer();
1613   int i=0;
1614   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1615     if(*w>=0 && *w<oldNbOfTuples)
1616       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1617     else
1618       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1619   ret->copyStringInfoFrom(*this);
1620   return ret.retn();
1621 }
1622
1623 /*!
1624  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1625  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1626  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1627  * command \c range( \a bg, \a end2, \a step ).
1628  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1629  * not constructed explicitly.
1630  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1631  *  \param [in] bg - index of the first tuple to copy from \a this array.
1632  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1633  *  \param [in] step - index increment to get index of the next tuple to copy.
1634  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1635  *          is to delete using decrRef() as it is no more needed.
1636  *  \sa DataArrayDouble::substr.
1637  */
1638 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1639 {
1640   checkAllocated();
1641   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1642   int nbComp=getNumberOfComponents();
1643   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1644   ret->alloc(newNbOfTuples,nbComp);
1645   double *pt=ret->getPointer();
1646   const double *srcPt=getConstPointer()+bg*nbComp;
1647   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1648     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1649   ret->copyStringInfoFrom(*this);
1650   return ret.retn();
1651 }
1652
1653 /*!
1654  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1655  * of tuples specified by \a ranges parameter.
1656  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1657  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1658  *              of tuples in [\c begin,\c end) format.
1659  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1660  *          is to delete using decrRef() as it is no more needed.
1661  *  \throw If \a end < \a begin.
1662  *  \throw If \a end > \a this->getNumberOfTuples().
1663  *  \throw If \a this is not allocated.
1664  */
1665 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1666 {
1667   checkAllocated();
1668   int nbOfComp=getNumberOfComponents();
1669   int nbOfTuplesThis=getNumberOfTuples();
1670   if(ranges.empty())
1671     {
1672       DataArrayDouble *ret=DataArrayDouble::New();
1673       ret->alloc(0,nbOfComp);
1674       ret->copyStringInfoFrom(*this);
1675       return ret;
1676     }
1677   int ref=ranges.front().first;
1678   int nbOfTuples=0;
1679   bool isIncreasing=true;
1680   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1681     {
1682       if((*it).first<=(*it).second)
1683         {
1684           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1685             {
1686               nbOfTuples+=(*it).second-(*it).first;
1687               if(isIncreasing)
1688                 isIncreasing=ref<=(*it).first;
1689               ref=(*it).second;
1690             }
1691           else
1692             {
1693               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1694               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1695               throw INTERP_KERNEL::Exception(oss.str().c_str());
1696             }
1697         }
1698       else
1699         {
1700           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1701           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1702           throw INTERP_KERNEL::Exception(oss.str().c_str());
1703         }
1704     }
1705   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1706     return deepCpy();
1707   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1708   ret->alloc(nbOfTuples,nbOfComp);
1709   ret->copyStringInfoFrom(*this);
1710   const double *src=getConstPointer();
1711   double *work=ret->getPointer();
1712   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1713     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1714   return ret.retn();
1715 }
1716
1717 /*!
1718  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1719  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1720  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1721  * This method is a specialization of selectByTupleId2().
1722  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1723  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1724  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1725  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1726  *          is to delete using decrRef() as it is no more needed.
1727  *  \throw If \a tupleIdBg < 0.
1728  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1729     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1730  *  \sa DataArrayDouble::selectByTupleId2
1731  */
1732 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1733 {
1734   checkAllocated();
1735   int nbt=getNumberOfTuples();
1736   if(tupleIdBg<0)
1737     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1738   if(tupleIdBg>nbt)
1739     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1740   int trueEnd=tupleIdEnd;
1741   if(tupleIdEnd!=-1)
1742     {
1743       if(tupleIdEnd>nbt)
1744         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1745     }
1746   else
1747     trueEnd=nbt;
1748   int nbComp=getNumberOfComponents();
1749   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1750   ret->alloc(trueEnd-tupleIdBg,nbComp);
1751   ret->copyStringInfoFrom(*this);
1752   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1753   return ret.retn();
1754 }
1755
1756 /*!
1757  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1758  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1759  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1760  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1761  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1762  * components.  
1763  *  \param [in] newNbOfComp - number of components for the new array to have.
1764  *  \param [in] dftValue - value assigned to new values added to the new array.
1765  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1766  *          is to delete using decrRef() as it is no more needed.
1767  *  \throw If \a this is not allocated.
1768  */
1769 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1770 {
1771   checkAllocated();
1772   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1773   ret->alloc(getNumberOfTuples(),newNbOfComp);
1774   const double *oldc=getConstPointer();
1775   double *nc=ret->getPointer();
1776   int nbOfTuples=getNumberOfTuples();
1777   int oldNbOfComp=getNumberOfComponents();
1778   int dim=std::min(oldNbOfComp,newNbOfComp);
1779   for(int i=0;i<nbOfTuples;i++)
1780     {
1781       int j=0;
1782       for(;j<dim;j++)
1783         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1784       for(;j<newNbOfComp;j++)
1785         nc[newNbOfComp*i+j]=dftValue;
1786     }
1787   ret->setName(getName().c_str());
1788   for(int i=0;i<dim;i++)
1789     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1790   ret->setName(getName().c_str());
1791   return ret.retn();
1792 }
1793
1794 /*!
1795  * Changes the number of components within \a this array so that its raw data **does
1796  * not** change, instead splitting this data into tuples changes.
1797  *  \warning This method erases all (name and unit) component info set before!
1798  *  \param [in] newNbOfComp - number of components for \a this array to have.
1799  *  \throw If \a this is not allocated
1800  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1801  *  \throw If \a newNbOfCompo is lower than 1.
1802  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1803  *  \warning This method erases all (name and unit) component info set before!
1804  */
1805 void DataArrayDouble::rearrange(int newNbOfCompo)
1806 {
1807   checkAllocated();
1808   if(newNbOfCompo<1)
1809     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1810   std::size_t nbOfElems=getNbOfElems();
1811   if(nbOfElems%newNbOfCompo!=0)
1812     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1813   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1814     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1815   _info_on_compo.clear();
1816   _info_on_compo.resize(newNbOfCompo);
1817   declareAsNew();
1818 }
1819
1820 /*!
1821  * Changes the number of components within \a this array to be equal to its number
1822  * of tuples, and inversely its number of tuples to become equal to its number of 
1823  * components. So that its raw data **does not** change, instead splitting this
1824  * data into tuples changes.
1825  *  \warning This method erases all (name and unit) component info set before!
1826  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1827  *  \throw If \a this is not allocated.
1828  *  \sa rearrange()
1829  */
1830 void DataArrayDouble::transpose()
1831 {
1832   checkAllocated();
1833   int nbOfTuples=getNumberOfTuples();
1834   rearrange(nbOfTuples);
1835 }
1836
1837 /*!
1838  * Returns a copy of \a this array composed of selected components.
1839  * The new DataArrayDouble has the same number of tuples but includes components
1840  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1841  * can be either less, same or more than \a this->getNbOfElems().
1842  *  \param [in] compoIds - sequence of zero based indices of components to include
1843  *              into the new array.
1844  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1845  *          is to delete using decrRef() as it is no more needed.
1846  *  \throw If \a this is not allocated.
1847  *  \throw If a component index (\a i) is not valid: 
1848  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1849  *
1850  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1851  */
1852 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1853 {
1854   checkAllocated();
1855   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1856   std::size_t newNbOfCompo=compoIds.size();
1857   int oldNbOfCompo=getNumberOfComponents();
1858   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1859     if((*it)<0 || (*it)>=oldNbOfCompo)
1860       {
1861         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1862         throw INTERP_KERNEL::Exception(oss.str().c_str());
1863       }
1864   int nbOfTuples=getNumberOfTuples();
1865   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1866   ret->copyPartOfStringInfoFrom(*this,compoIds);
1867   const double *oldc=getConstPointer();
1868   double *nc=ret->getPointer();
1869   for(int i=0;i<nbOfTuples;i++)
1870     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1871       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1872   return ret.retn();
1873 }
1874
1875 /*!
1876  * Appends components of another array to components of \a this one, tuple by tuple.
1877  * So that the number of tuples of \a this array remains the same and the number of 
1878  * components increases.
1879  *  \param [in] other - the DataArrayDouble to append to \a this one.
1880  *  \throw If \a this is not allocated.
1881  *  \throw If \a this and \a other arrays have different number of tuples.
1882  *
1883  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1884  *
1885  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1886  */
1887 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1888 {
1889   checkAllocated();
1890   other->checkAllocated();
1891   int nbOfTuples=getNumberOfTuples();
1892   if(nbOfTuples!=other->getNumberOfTuples())
1893     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1894   int nbOfComp1=getNumberOfComponents();
1895   int nbOfComp2=other->getNumberOfComponents();
1896   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1897   double *w=newArr;
1898   const double *inp1=getConstPointer();
1899   const double *inp2=other->getConstPointer();
1900   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1901     {
1902       w=std::copy(inp1,inp1+nbOfComp1,w);
1903       w=std::copy(inp2,inp2+nbOfComp2,w);
1904     }
1905   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1906   std::vector<int> compIds(nbOfComp2);
1907   for(int i=0;i<nbOfComp2;i++)
1908     compIds[i]=nbOfComp1+i;
1909   copyPartOfStringInfoFrom2(compIds,*other);
1910 }
1911
1912 /*!
1913  * This method checks that all tuples in \a other are in \a this.
1914  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1915  * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this.
1916  *
1917  * \param [in] other - the array having the same number of components than \a this.
1918  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1919  * \sa DataArrayDouble::findCommonTuples
1920  */
1921 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1922 {
1923   if(!other)
1924     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1925   checkAllocated(); other->checkAllocated();
1926   if(getNumberOfComponents()!=other->getNumberOfComponents())
1927     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1928   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1929   DataArrayInt *c=0,*ci=0;
1930   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1932   int newNbOfTuples=-1;
1933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1934   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1935   tupleIds=ret1.retn();
1936   return newNbOfTuples==getNumberOfTuples();
1937 }
1938
1939 /*!
1940  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1941  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1942  * distance separating two points is computed with the infinite norm.
1943  *
1944  * Indices of coincident tuples are stored in output arrays.
1945  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1946  *
1947  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1948  * MEDCouplingUMesh::mergeNodes().
1949  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1950  *              considered not coincident.
1951  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1952  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1953  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1954  *               \a comm->getNumberOfComponents() == 1. 
1955  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1956  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1957  *               groups of (indices of) coincident tuples. Its every value is a tuple
1958  *               index where a next group of tuples begins. For example the second
1959  *               group of tuples in \a comm is described by following range of indices:
1960  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1961  *               gives the number of groups of coincident tuples.
1962  *  \throw If \a this is not allocated.
1963  *  \throw If the number of components is not in [1,2,3].
1964  *
1965  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1966  *
1967  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1968  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1969  */
1970 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1971 {
1972   checkAllocated();
1973   int nbOfCompo=getNumberOfComponents();
1974   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1975     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1976   
1977   int nbOfTuples=getNumberOfTuples();
1978   //
1979   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1980   switch(nbOfCompo)
1981     {
1982     case 3:
1983       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1984       break;
1985     case 2:
1986       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1987       break;
1988     case 1:
1989       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1990       break;
1991     default:
1992       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1993     }
1994   comm=c.retn();
1995   commIndex=cI.retn();
1996 }
1997
1998 /*!
1999  * 
2000  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2001  *             \a nbTimes  should be at least equal to 1.
2002  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2003  * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
2004  */
2005 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2006 {
2007   checkAllocated();
2008   if(getNumberOfComponents()!=1)
2009     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2010   if(nbTimes<1)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2012   int nbTuples=getNumberOfTuples();
2013   const double *inPtr=getConstPointer();
2014   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2015   double *retPtr=ret->getPointer();
2016   for(int i=0;i<nbTuples;i++,inPtr++)
2017     {
2018       double val=*inPtr;
2019       for(int j=0;j<nbTimes;j++,retPtr++)
2020         *retPtr=val;
2021     }
2022   ret->copyStringInfoFrom(*this);
2023   return ret.retn();
2024 }
2025
2026 /*!
2027  * This methods returns the minimal distance between the two set of points \a this and \a other.
2028  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2029  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2030  *
2031  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2032  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2033  * \return the minimal distance between the two set of points \a this and \a other.
2034  * \sa DataArrayDouble::findClosestTupleId
2035  */
2036 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2037 {
2038   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2039   int nbOfCompo(getNumberOfComponents());
2040   int otherNbTuples(other->getNumberOfTuples());
2041   const double *thisPt(begin()),*otherPt(other->begin());
2042   const int *part1Pt(part1->begin());
2043   double ret=std::numeric_limits<double>::max();
2044   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2045     {
2046       double tmp(0.);
2047       for(int j=0;j<nbOfCompo;j++)
2048         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2049       if(tmp<ret)
2050         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2051     }
2052   return sqrt(ret);
2053 }
2054
2055 /*!
2056  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2057  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2058  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2059  *
2060  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2061  * \sa DataArrayDouble::minimalDistanceTo
2062  */
2063 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2064 {
2065   if(!other)
2066     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2067   checkAllocated(); other->checkAllocated();
2068   int nbOfCompo=getNumberOfComponents();
2069   if(nbOfCompo!=other->getNumberOfComponents())
2070     {
2071       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2072       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2073       throw INTERP_KERNEL::Exception(oss.str().c_str());
2074     }
2075   int nbOfTuples=other->getNumberOfTuples();
2076   int thisNbOfTuples=getNumberOfTuples();
2077   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2078   double bounds[6];
2079   getMinMaxPerComponent(bounds);
2080   switch(nbOfCompo)
2081     {
2082     case 3:
2083       {
2084         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2085         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2086         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2087         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2088         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2089         break;
2090       }
2091     case 2:
2092       {
2093         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2094         double delta=std::max(xDelta,yDelta);
2095         double characSize=sqrt(delta/(double)thisNbOfTuples);
2096         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2097         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2098         break;
2099       }
2100     case 1:
2101       {
2102         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2103         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2104         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2105         break;
2106       }
2107     default:
2108       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2109     }
2110   return ret.retn();
2111 }
2112
2113 /*!
2114  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2115  * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this
2116  * how many bounding boxes in \a otherBBoxFrmt.
2117  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2118  *
2119  * \param [in] otherBBoxFrmt - It is an array .
2120  * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched.
2121  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2122  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2123  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2124  */
2125 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2126 {
2127   if(!otherBBoxFrmt)
2128     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2129   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2130     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2131   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2132   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2133     {
2134       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2135       throw INTERP_KERNEL::Exception(oss.str().c_str());
2136     }
2137   if(nbOfComp%2!=0)
2138     {
2139       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2140       throw INTERP_KERNEL::Exception(oss.str().c_str());
2141     }
2142   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2143   const double *thisBBPtr(begin());
2144   int *retPtr(ret->getPointer());
2145   switch(nbOfComp/2)
2146     {
2147     case 3:
2148       {
2149         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2150         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2151           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2152         break;
2153       }
2154     case 2:
2155       {
2156         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2157         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2158           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2159         break;
2160       }
2161     case 1:
2162       {
2163         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2164         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2165           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2166         break;
2167       }
2168     default:
2169       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2170     }
2171   
2172   return ret.retn();
2173 }
2174
2175 /*!
2176  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2177  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2178  * space. The distance between tuples is computed using norm2. If several tuples are
2179  * not far each from other than \a prec, only one of them remains in the result
2180  * array. The order of tuples in the result array is same as in \a this one except
2181  * that coincident tuples are excluded.
2182  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2183  *              considered not coincident.
2184  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2185  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2186  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2187  *          is to delete using decrRef() as it is no more needed.
2188  *  \throw If \a this is not allocated.
2189  *  \throw If the number of components is not in [1,2,3].
2190  *
2191  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2192  */
2193 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2194 {
2195   checkAllocated();
2196   DataArrayInt *c0=0,*cI0=0;
2197   findCommonTuples(prec,limitTupleId,c0,cI0);
2198   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2199   int newNbOfTuples=-1;
2200   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2201   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2202 }
2203
2204 /*!
2205  * Copy all components in a specified order from another DataArrayDouble.
2206  * Both numerical and textual data is copied. The number of tuples in \a this and
2207  * the other array can be different.
2208  *  \param [in] a - the array to copy data from.
2209  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2210  *              to be copied.
2211  *  \throw If \a a is NULL.
2212  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2213  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2214  *
2215  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2216  */
2217 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2218 {
2219   if(!a)
2220     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2221   checkAllocated();
2222   copyPartOfStringInfoFrom2(compoIds,*a);
2223   std::size_t partOfCompoSz=compoIds.size();
2224   int nbOfCompo=getNumberOfComponents();
2225   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2226   const double *ac=a->getConstPointer();
2227   double *nc=getPointer();
2228   for(int i=0;i<nbOfTuples;i++)
2229     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2230       nc[nbOfCompo*i+compoIds[j]]=*ac;
2231 }
2232
2233 /*!
2234  * Copy all values from another DataArrayDouble into specified tuples and components
2235  * of \a this array. Textual data is not copied.
2236  * The tree parameters defining set of indices of tuples and components are similar to
2237  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2238  *  \param [in] a - the array to copy values from.
2239  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2240  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2241  *              are located.
2242  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2243  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2244  *  \param [in] endComp - index of the component before which the components to assign
2245  *              to are located.
2246  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2247  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2248  *              must be equal to the number of columns to assign to, else an
2249  *              exception is thrown; if \a false, then it is only required that \a
2250  *              a->getNbOfElems() equals to number of values to assign to (this condition
2251  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2252  *              values to assign to is given by following Python expression:
2253  *              \a nbTargetValues = 
2254  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2255  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2256  *  \throw If \a a is NULL.
2257  *  \throw If \a a is not allocated.
2258  *  \throw If \a this is not allocated.
2259  *  \throw If parameters specifying tuples and components to assign to do not give a
2260  *            non-empty range of increasing indices.
2261  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2262  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2263  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2264  *
2265  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2266  */
2267 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2268 {
2269   if(!a)
2270     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2271   const char msg[]="DataArrayDouble::setPartOfValues1";
2272   checkAllocated();
2273   a->checkAllocated();
2274   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2275   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2276   int nbComp=getNumberOfComponents();
2277   int nbOfTuples=getNumberOfTuples();
2278   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2279   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2280   bool assignTech=true;
2281   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2282     {
2283       if(strictCompoCompare)
2284         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2285     }
2286   else
2287     {
2288       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2289       assignTech=false;
2290     }
2291   const double *srcPt=a->getConstPointer();
2292   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2293   if(assignTech)
2294     {
2295       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2296         for(int j=0;j<newNbOfComp;j++,srcPt++)
2297           pt[j*stepComp]=*srcPt;
2298     }
2299   else
2300     {
2301       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2302         {
2303           const double *srcPt2=srcPt;
2304           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2305             pt[j*stepComp]=*srcPt2;
2306         }
2307     }
2308 }
2309
2310 /*!
2311  * Assign a given value to values at specified tuples and components of \a this array.
2312  * The tree parameters defining set of indices of tuples and components are similar to
2313  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2314  *  \param [in] a - the value to assign.
2315  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2316  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2317  *              are located.
2318  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2319  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2320  *  \param [in] endComp - index of the component before which the components to assign
2321  *              to are located.
2322  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2323  *  \throw If \a this is not allocated.
2324  *  \throw If parameters specifying tuples and components to assign to, do not give a
2325  *            non-empty range of increasing indices or indices are out of a valid range
2326  *            for \this array.
2327  *
2328  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2329  */
2330 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2331 {
2332   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2333   checkAllocated();
2334   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2335   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2336   int nbComp=getNumberOfComponents();
2337   int nbOfTuples=getNumberOfTuples();
2338   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2339   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2340   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2341   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2342     for(int j=0;j<newNbOfComp;j++)
2343       pt[j*stepComp]=a;
2344 }
2345
2346 /*!
2347  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2348  * components of \a this array. Textual data is not copied.
2349  * The tuples and components to assign to are defined by C arrays of indices.
2350  * There are two *modes of usage*:
2351  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2352  *   of \a a is assigned to its own location within \a this array. 
2353  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2354  *   components of every specified tuple of \a this array. In this mode it is required
2355  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2356  *
2357  *  \param [in] a - the array to copy values from.
2358  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2359  *              assign values of \a a to.
2360  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2361  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2362  *              \a bgTuples <= \a pi < \a endTuples.
2363  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2364  *              assign values of \a a to.
2365  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2366  *              pointer to a component index <em>(pi)</em> varies as this: 
2367  *              \a bgComp <= \a pi < \a endComp.
2368  *  \param [in] strictCompoCompare - this parameter is checked only if the
2369  *               *mode of usage* is the first; if it is \a true (default), 
2370  *               then \a a->getNumberOfComponents() must be equal 
2371  *               to the number of specified columns, else this is not required.
2372  *  \throw If \a a is NULL.
2373  *  \throw If \a a is not allocated.
2374  *  \throw If \a this is not allocated.
2375  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2376  *         out of a valid range for \a this array.
2377  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2378  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2379  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2380  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2381  *
2382  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2383  */
2384 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2385 {
2386   if(!a)
2387     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2388   const char msg[]="DataArrayDouble::setPartOfValues2";
2389   checkAllocated();
2390   a->checkAllocated();
2391   int nbComp=getNumberOfComponents();
2392   int nbOfTuples=getNumberOfTuples();
2393   for(const int *z=bgComp;z!=endComp;z++)
2394     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2395   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2396   int newNbOfComp=(int)std::distance(bgComp,endComp);
2397   bool assignTech=true;
2398   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2399     {
2400       if(strictCompoCompare)
2401         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2402     }
2403   else
2404     {
2405       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2406       assignTech=false;
2407     }
2408   double *pt=getPointer();
2409   const double *srcPt=a->getConstPointer();
2410   if(assignTech)
2411     {    
2412       for(const int *w=bgTuples;w!=endTuples;w++)
2413         {
2414           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2415           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2416             {    
2417               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2418             }
2419         }
2420     }
2421   else
2422     {
2423       for(const int *w=bgTuples;w!=endTuples;w++)
2424         {
2425           const double *srcPt2=srcPt;
2426           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2427           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2428             {    
2429               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2430             }
2431         }
2432     }
2433 }
2434
2435 /*!
2436  * Assign a given value to values at specified tuples and components of \a this array.
2437  * The tuples and components to assign to are defined by C arrays of indices.
2438  *  \param [in] a - the value to assign.
2439  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2440  *              assign \a a to.
2441  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2442  *              pointer to a tuple index (\a pi) varies as this: 
2443  *              \a bgTuples <= \a pi < \a endTuples.
2444  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2445  *              assign \a a to.
2446  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2447  *              pointer to a component index (\a pi) varies as this: 
2448  *              \a bgComp <= \a pi < \a endComp.
2449  *  \throw If \a this is not allocated.
2450  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2451  *         out of a valid range for \a this array.
2452  *
2453  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2454  */
2455 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2456 {
2457   checkAllocated();
2458   int nbComp=getNumberOfComponents();
2459   int nbOfTuples=getNumberOfTuples();
2460   for(const int *z=bgComp;z!=endComp;z++)
2461     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2462   double *pt=getPointer();
2463   for(const int *w=bgTuples;w!=endTuples;w++)
2464     for(const int *z=bgComp;z!=endComp;z++)
2465       {
2466         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2467         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2468       }
2469 }
2470
2471 /*!
2472  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2473  * components of \a this array. Textual data is not copied.
2474  * The tuples to assign to are defined by a C array of indices.
2475  * The components to assign to are defined by three values similar to parameters of
2476  * the Python function \c range(\c start,\c stop,\c step).
2477  * There are two *modes of usage*:
2478  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2479  *   of \a a is assigned to its own location within \a this array. 
2480  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2481  *   components of every specified tuple of \a this array. In this mode it is required
2482  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2483  *
2484  *  \param [in] a - the array to copy values from.
2485  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2486  *              assign values of \a a to.
2487  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2488  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2489  *              \a bgTuples <= \a pi < \a endTuples.
2490  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2491  *  \param [in] endComp - index of the component before which the components to assign
2492  *              to are located.
2493  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2494  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2495  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2496  *               then \a a->getNumberOfComponents() must be equal 
2497  *               to the number of specified columns, else this is not required.
2498  *  \throw If \a a is NULL.
2499  *  \throw If \a a is not allocated.
2500  *  \throw If \a this is not allocated.
2501  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2502  *         \a this array.
2503  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2504  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2505  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2506  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2507  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2508  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2509  *  \throw If parameters specifying components to assign to, do not give a
2510  *            non-empty range of increasing indices or indices are out of a valid range
2511  *            for \this array.
2512  *
2513  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2514  */
2515 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2516 {
2517   if(!a)
2518     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2519   const char msg[]="DataArrayDouble::setPartOfValues3";
2520   checkAllocated();
2521   a->checkAllocated();
2522   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2523   int nbComp=getNumberOfComponents();
2524   int nbOfTuples=getNumberOfTuples();
2525   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2526   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2527   bool assignTech=true;
2528   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2529     {
2530       if(strictCompoCompare)
2531         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2532     }
2533   else
2534     {
2535       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2536       assignTech=false;
2537     }
2538   double *pt=getPointer()+bgComp;
2539   const double *srcPt=a->getConstPointer();
2540   if(assignTech)
2541     {
2542       for(const int *w=bgTuples;w!=endTuples;w++)
2543         for(int j=0;j<newNbOfComp;j++,srcPt++)
2544           {
2545             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2546             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2547           }
2548     }
2549   else
2550     {
2551       for(const int *w=bgTuples;w!=endTuples;w++)
2552         {
2553           const double *srcPt2=srcPt;
2554           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2555             {
2556               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2557               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2558             }
2559         }
2560     }
2561 }
2562
2563 /*!
2564  * Assign a given value to values at specified tuples and components of \a this array.
2565  * The tuples to assign to are defined by a C array of indices.
2566  * The components to assign to are defined by three values similar to parameters of
2567  * the Python function \c range(\c start,\c stop,\c step).
2568  *  \param [in] a - the value to assign.
2569  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2570  *              assign \a a to.
2571  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2572  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2573  *              \a bgTuples <= \a pi < \a endTuples.
2574  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2575  *  \param [in] endComp - index of the component before which the components to assign
2576  *              to are located.
2577  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2578  *  \throw If \a this is not allocated.
2579  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2580  *         \a this array.
2581  *  \throw If parameters specifying components to assign to, do not give a
2582  *            non-empty range of increasing indices or indices are out of a valid range
2583  *            for \this array.
2584  *
2585  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2586  */
2587 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2588 {
2589   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2590   checkAllocated();
2591   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2592   int nbComp=getNumberOfComponents();
2593   int nbOfTuples=getNumberOfTuples();
2594   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2595   double *pt=getPointer()+bgComp;
2596   for(const int *w=bgTuples;w!=endTuples;w++)
2597     for(int j=0;j<newNbOfComp;j++)
2598       {
2599         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2600         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2601       }
2602 }
2603
2604 /*!
2605  * Copy all values from another DataArrayDouble into specified tuples and components
2606  * of \a this array. Textual data is not copied.
2607  * The tree parameters defining set of indices of tuples and components are similar to
2608  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2609  *  \param [in] a - the array to copy values from.
2610  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2611  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2612  *              are located.
2613  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2614  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2615  *              assign \a a to.
2616  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2617  *              pointer to a component index (\a pi) varies as this: 
2618  *              \a bgComp <= \a pi < \a endComp.
2619  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2620  *              must be equal to the number of columns to assign to, else an
2621  *              exception is thrown; if \a false, then it is only required that \a
2622  *              a->getNbOfElems() equals to number of values to assign to (this condition
2623  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2624  *              values to assign to is given by following Python expression:
2625  *              \a nbTargetValues = 
2626  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2627  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2628  *  \throw If \a a is NULL.
2629  *  \throw If \a a is not allocated.
2630  *  \throw If \a this is not allocated.
2631  *  \throw If parameters specifying tuples and components to assign to do not give a
2632  *            non-empty range of increasing indices.
2633  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2634  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2635  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2636  *
2637  */
2638 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2639 {
2640   if(!a)
2641     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2642   const char msg[]="DataArrayDouble::setPartOfValues4";
2643   checkAllocated();
2644   a->checkAllocated();
2645   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2646   int newNbOfComp=(int)std::distance(bgComp,endComp);
2647   int nbComp=getNumberOfComponents();
2648   for(const int *z=bgComp;z!=endComp;z++)
2649     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2650   int nbOfTuples=getNumberOfTuples();
2651   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2652   bool assignTech=true;
2653   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2654     {
2655       if(strictCompoCompare)
2656         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2657     }
2658   else
2659     {
2660       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2661       assignTech=false;
2662     }
2663   const double *srcPt=a->getConstPointer();
2664   double *pt=getPointer()+bgTuples*nbComp;
2665   if(assignTech)
2666     {
2667       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2668         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2669           pt[*z]=*srcPt;
2670     }
2671   else
2672     {
2673       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2674         {
2675           const double *srcPt2=srcPt;
2676           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2677             pt[*z]=*srcPt2;
2678         }
2679     }
2680 }
2681
2682 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2683 {
2684   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2685   checkAllocated();
2686   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2687   int nbComp=getNumberOfComponents();
2688   for(const int *z=bgComp;z!=endComp;z++)
2689     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2690   int nbOfTuples=getNumberOfTuples();
2691   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2692   double *pt=getPointer()+bgTuples*nbComp;
2693   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2694     for(const int *z=bgComp;z!=endComp;z++)
2695       pt[*z]=a;
2696 }
2697
2698 /*!
2699  * Copy some tuples from another DataArrayDouble into specified tuples
2700  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2701  * components.
2702  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2703  * All components of selected tuples are copied.
2704  *  \param [in] a - the array to copy values from.
2705  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2706  *              target tuples of \a this. \a tuplesSelec has two components, and the
2707  *              first component specifies index of the source tuple and the second
2708  *              one specifies index of the target tuple.
2709  *  \throw If \a this is not allocated.
2710  *  \throw If \a a is NULL.
2711  *  \throw If \a a is not allocated.
2712  *  \throw If \a tuplesSelec is NULL.
2713  *  \throw If \a tuplesSelec is not allocated.
2714  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2715  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2716  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2717  *         the corresponding (\a this or \a a) array.
2718  */
2719 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2720 {
2721   if(!a || !tuplesSelec)
2722     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2723   checkAllocated();
2724   a->checkAllocated();
2725   tuplesSelec->checkAllocated();
2726   int nbOfComp=getNumberOfComponents();
2727   if(nbOfComp!=a->getNumberOfComponents())
2728     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2729   if(tuplesSelec->getNumberOfComponents()!=2)
2730     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2731   int thisNt=getNumberOfTuples();
2732   int aNt=a->getNumberOfTuples();
2733   double *valsToSet=getPointer();
2734   const double *valsSrc=a->getConstPointer();
2735   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2736     {
2737       if(tuple[1]>=0 && tuple[1]<aNt)
2738         {
2739           if(tuple[0]>=0 && tuple[0]<thisNt)
2740             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2741           else
2742             {
2743               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2744               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2745               throw INTERP_KERNEL::Exception(oss.str().c_str());
2746             }
2747         }
2748       else
2749         {
2750           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2751           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2752           throw INTERP_KERNEL::Exception(oss.str().c_str());
2753         }
2754     }
2755 }
2756
2757 /*!
2758  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2759  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2760  * components.
2761  * The tuples to assign to are defined by index of the first tuple, and
2762  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2763  * The tuples to copy are defined by values of a DataArrayInt.
2764  * All components of selected tuples are copied.
2765  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2766  *              values to.
2767  *  \param [in] aBase - the array to copy values from.
2768  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2769  *  \throw If \a this is not allocated.
2770  *  \throw If \a aBase is NULL.
2771  *  \throw If \a aBase is not allocated.
2772  *  \throw If \a tuplesSelec is NULL.
2773  *  \throw If \a tuplesSelec is not allocated.
2774  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2775  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2776  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2777  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2778  *         \a aBase array.
2779  */
2780 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2781 {
2782   if(!aBase || !tuplesSelec)
2783     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2784   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2785   if(!a)
2786     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2787   checkAllocated();
2788   a->checkAllocated();
2789   tuplesSelec->checkAllocated();
2790   int nbOfComp=getNumberOfComponents();
2791   if(nbOfComp!=a->getNumberOfComponents())
2792     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2793   if(tuplesSelec->getNumberOfComponents()!=1)
2794     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2795   int thisNt=getNumberOfTuples();
2796   int aNt=a->getNumberOfTuples();
2797   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2798   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2799   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2800     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2801   const double *valsSrc=a->getConstPointer();
2802   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2803     {
2804       if(*tuple>=0 && *tuple<aNt)
2805         {
2806           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2807         }
2808       else
2809         {
2810           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2811           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2812           throw INTERP_KERNEL::Exception(oss.str().c_str());
2813         }
2814     }
2815 }
2816
2817 /*!
2818  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2819  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2820  * components.
2821  * The tuples to copy are defined by three values similar to parameters of
2822  * the Python function \c range(\c start,\c stop,\c step).
2823  * The tuples to assign to are defined by index of the first tuple, and
2824  * their number is defined by number of tuples to copy.
2825  * All components of selected tuples are copied.
2826  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2827  *              values to.
2828  *  \param [in] aBase - the array to copy values from.
2829  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2830  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2831  *              are located.
2832  *  \param [in] step - index increment to get index of the next tuple to copy.
2833  *  \throw If \a this is not allocated.
2834  *  \throw If \a aBase is NULL.
2835  *  \throw If \a aBase is not allocated.
2836  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2837  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2838  *  \throw If parameters specifying tuples to copy, do not give a
2839  *            non-empty range of increasing indices or indices are out of a valid range
2840  *            for the array \a aBase.
2841  */
2842 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2843 {
2844   if(!aBase)
2845     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2846   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2847   if(!a)
2848     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2849   checkAllocated();
2850   a->checkAllocated();
2851   int nbOfComp=getNumberOfComponents();
2852   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2853   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2854   if(nbOfComp!=a->getNumberOfComponents())
2855     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2856   int thisNt=getNumberOfTuples();
2857   int aNt=a->getNumberOfTuples();
2858   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2859   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2860     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2861   if(end2>aNt)
2862     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2863   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2864   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2865     {
2866       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2867     }
2868 }
2869
2870 /*!
2871  * Returns a value located at specified tuple and component.
2872  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2873  * parameters is checked. So this method is safe but expensive if used to go through
2874  * all values of \a this.
2875  *  \param [in] tupleId - index of tuple of interest.
2876  *  \param [in] compoId - index of component of interest.
2877  *  \return double - value located by \a tupleId and \a compoId.
2878  *  \throw If \a this is not allocated.
2879  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2880  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2881  */
2882 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2883 {
2884   checkAllocated();
2885   if(tupleId<0 || tupleId>=getNumberOfTuples())
2886     {
2887       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2888       throw INTERP_KERNEL::Exception(oss.str().c_str());
2889     }
2890   if(compoId<0 || compoId>=getNumberOfComponents())
2891     {
2892       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2893       throw INTERP_KERNEL::Exception(oss.str().c_str());
2894     }
2895   return _mem[tupleId*_info_on_compo.size()+compoId];
2896 }
2897
2898 /*!
2899  * Returns the first value of \a this. 
2900  *  \return double - the last value of \a this array.
2901  *  \throw If \a this is not allocated.
2902  *  \throw If \a this->getNumberOfComponents() != 1.
2903  *  \throw If \a this->getNumberOfTuples() < 1.
2904  */
2905 double DataArrayDouble::front() const
2906 {
2907   checkAllocated();
2908   if(getNumberOfComponents()!=1)
2909     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2910   int nbOfTuples=getNumberOfTuples();
2911   if(nbOfTuples<1)
2912     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2913   return *(getConstPointer());
2914 }
2915
2916 /*!
2917  * Returns the last value of \a this. 
2918  *  \return double - the last value of \a this array.
2919  *  \throw If \a this is not allocated.
2920  *  \throw If \a this->getNumberOfComponents() != 1.
2921  *  \throw If \a this->getNumberOfTuples() < 1.
2922  */
2923 double DataArrayDouble::back() const
2924 {
2925   checkAllocated();
2926   if(getNumberOfComponents()!=1)
2927     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2928   int nbOfTuples=getNumberOfTuples();
2929   if(nbOfTuples<1)
2930     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2931   return *(getConstPointer()+nbOfTuples-1);
2932 }
2933
2934 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2935 {
2936   if(newArray!=arrayToSet)
2937     {
2938       if(arrayToSet)
2939         arrayToSet->decrRef();
2940       arrayToSet=newArray;
2941       if(arrayToSet)
2942         arrayToSet->incrRef();
2943     }
2944 }
2945
2946 /*!
2947  * Sets a C array to be used as raw data of \a this. The previously set info
2948  *  of components is retained and re-sized. 
2949  * For more info see \ref MEDCouplingArraySteps1.
2950  *  \param [in] array - the C array to be used as raw data of \a this.
2951  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2952  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2953  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2954  *                     \c free(\c array ) will be called.
2955  *  \param [in] nbOfTuple - new number of tuples in \a this.
2956  *  \param [in] nbOfCompo - new number of components in \a this.
2957  */
2958 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2959 {
2960   _info_on_compo.resize(nbOfCompo);
2961   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2962   declareAsNew();
2963 }
2964
2965 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
2966 {
2967   _info_on_compo.resize(nbOfCompo);
2968   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2969   declareAsNew();
2970 }
2971
2972 /*!
2973  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2974  * is thrown.
2975  * \throw If zero is found in \a this array.
2976  */
2977 void DataArrayDouble::checkNoNullValues() const
2978 {
2979   const double *tmp=getConstPointer();
2980   std::size_t nbOfElems=getNbOfElems();
2981   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2982   if(where!=tmp+nbOfElems)
2983     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2984 }
2985
2986 /*!
2987  * Computes minimal and maximal value in each component. An output array is filled
2988  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2989  * enough memory before calling this method.
2990  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2991  *               It is filled as follows:<br>
2992  *               \a bounds[0] = \c min_of_component_0 <br>
2993  *               \a bounds[1] = \c max_of_component_0 <br>
2994  *               \a bounds[2] = \c min_of_component_1 <br>
2995  *               \a bounds[3] = \c max_of_component_1 <br>
2996  *               ...
2997  */
2998 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
2999 {
3000   checkAllocated();
3001   int dim=getNumberOfComponents();
3002   for (int idim=0; idim<dim; idim++)
3003     {
3004       bounds[idim*2]=std::numeric_limits<double>::max();
3005       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3006     } 
3007   const double *ptr=getConstPointer();
3008   int nbOfTuples=getNumberOfTuples();
3009   for(int i=0;i<nbOfTuples;i++)
3010     {
3011       for(int idim=0;idim<dim;idim++)
3012         {
3013           if(bounds[idim*2]>ptr[i*dim+idim])
3014             {
3015               bounds[idim*2]=ptr[i*dim+idim];
3016             }
3017           if(bounds[idim*2+1]<ptr[i*dim+idim])
3018             {
3019               bounds[idim*2+1]=ptr[i*dim+idim];
3020             }
3021         }
3022     }
3023 }
3024
3025 /*!
3026  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3027  * to store both the min and max per component of each tuples. 
3028  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3029  *
3030  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3031  *
3032  * \throw If \a this is not allocated yet.
3033  */
3034 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3035 {
3036   checkAllocated();
3037   const double *dataPtr=getConstPointer();
3038   int nbOfCompo=getNumberOfComponents();
3039   int nbTuples=getNumberOfTuples();
3040   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3041   bbox->alloc(nbTuples,2*nbOfCompo);
3042   double *bboxPtr=bbox->getPointer();
3043   for(int i=0;i<nbTuples;i++)
3044     {
3045       for(int j=0;j<nbOfCompo;j++)
3046         {
3047           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3048           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3049         }
3050     }
3051   return bbox.retn();
3052 }
3053
3054 /*!
3055  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3056  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3057  * 
3058  * \param [in] other a DataArrayDouble having same number of components than \a this.
3059  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3060  * \param [out] c will contain the set of tuple ids in \a this that are equal to to the tuple ids in \a other contiguously.
3061  *             \a cI allows to extract information in \a c.
3062  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3063  *
3064  * \throw In case of:
3065  *  - \a this is not allocated
3066  *  - \a other is not allocated or null
3067  *  - \a this and \a other do not have the same number of components
3068  *  - if number of components of \a this is not in [1,2,3]
3069  *
3070  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3071  */
3072 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3073 {
3074   if(!other)
3075     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3076   checkAllocated();
3077   other->checkAllocated();
3078   int nbOfCompo=getNumberOfComponents();
3079   int otherNbOfCompo=other->getNumberOfComponents();
3080   if(nbOfCompo!=otherNbOfCompo)
3081     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3082   int nbOfTuplesOther=other->getNumberOfTuples();
3083   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3084   switch(nbOfCompo)
3085     {
3086     case 3:
3087       {
3088         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3089         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3090         break;
3091       }
3092     case 2:
3093       {
3094         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3095         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3096         break;
3097       }
3098     case 1:
3099       {
3100         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3101         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3102         break;
3103       }
3104     default:
3105       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3106     }
3107   c=cArr.retn(); cI=cIArr.retn();
3108 }
3109
3110 /*!
3111  * This method recenter tuples in \b this in order to be centered at the origin to benefit about the advantages of maximal precision to be around the box
3112  * around origin of 'radius' 1.
3113  * 
3114  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3115  */
3116 void DataArrayDouble::recenterForMaxPrecision(double eps)
3117 {
3118   checkAllocated();
3119   int dim=getNumberOfComponents();
3120   std::vector<double> bounds(2*dim);
3121   getMinMaxPerComponent(&bounds[0]);
3122   for(int i=0;i<dim;i++)
3123     {
3124       double delta=bounds[2*i+1]-bounds[2*i];
3125       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3126       if(delta>eps)
3127         applyLin(1./delta,-offset/delta,i);
3128       else
3129         applyLin(1.,-offset,i);
3130     }
3131 }
3132
3133 /*!
3134  * Returns the maximal value and its location within \a this one-dimensional array.
3135  *  \param [out] tupleId - index of the tuple holding the maximal value.
3136  *  \return double - the maximal value among all values of \a this array.
3137  *  \throw If \a this->getNumberOfComponents() != 1
3138  *  \throw If \a this->getNumberOfTuples() < 1
3139  */
3140 double DataArrayDouble::getMaxValue(int& tupleId) const
3141 {
3142   checkAllocated();
3143   if(getNumberOfComponents()!=1)
3144     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !");
3145   int nbOfTuples=getNumberOfTuples();
3146   if(nbOfTuples<=0)
3147     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3148   const double *vals=getConstPointer();
3149   const double *loc=std::max_element(vals,vals+nbOfTuples);
3150   tupleId=(int)std::distance(vals,loc);
3151   return *loc;
3152 }
3153
3154 /*!
3155  * Returns the maximal value within \a this array that is allowed to have more than
3156  *  one component.
3157  *  \return double - the maximal value among all values of \a this array.
3158  *  \throw If \a this is not allocated.
3159  */
3160 double DataArrayDouble::getMaxValueInArray() const
3161 {
3162   checkAllocated();
3163   const double *loc=std::max_element(begin(),end());
3164   return *loc;
3165 }
3166
3167 /*!
3168  * Returns the maximal value and all its locations within \a this one-dimensional array.
3169  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3170  *               tuples holding the maximal value. The caller is to delete it using
3171  *               decrRef() as it is no more needed.
3172  *  \return double - the maximal value among all values of \a this array.
3173  *  \throw If \a this->getNumberOfComponents() != 1
3174  *  \throw If \a this->getNumberOfTuples() < 1
3175  */
3176 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3177 {
3178   int tmp;
3179   tupleIds=0;
3180   double ret=getMaxValue(tmp);
3181   tupleIds=getIdsInRange(ret,ret);
3182   return ret;
3183 }
3184
3185 /*!
3186  * Returns the minimal value and its location within \a this one-dimensional array.
3187  *  \param [out] tupleId - index of the tuple holding the minimal value.
3188  *  \return double - the minimal value among all values of \a this array.
3189  *  \throw If \a this->getNumberOfComponents() != 1
3190  *  \throw If \a this->getNumberOfTuples() < 1
3191  */
3192 double DataArrayDouble::getMinValue(int& tupleId) const
3193 {
3194   checkAllocated();
3195   if(getNumberOfComponents()!=1)
3196     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3197   int nbOfTuples=getNumberOfTuples();
3198   if(nbOfTuples<=0)
3199     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3200   const double *vals=getConstPointer();
3201   const double *loc=std::min_element(vals,vals+nbOfTuples);
3202   tupleId=(int)std::distance(vals,loc);
3203   return *loc;
3204 }
3205
3206 /*!
3207  * Returns the minimal value within \a this array that is allowed to have more than
3208  *  one component.
3209  *  \return double - the minimal value among all values of \a this array.
3210  *  \throw If \a this is not allocated.
3211  */
3212 double DataArrayDouble::getMinValueInArray() const
3213 {
3214   checkAllocated();
3215   const double *loc=std::min_element(begin(),end());
3216   return *loc;
3217 }
3218
3219 /*!
3220  * Returns the minimal value and all its locations within \a this one-dimensional array.
3221  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3222  *               tuples holding the minimal value. The caller is to delete it using
3223  *               decrRef() as it is no more needed.
3224  *  \return double - the minimal value among all values of \a this array.
3225  *  \throw If \a this->getNumberOfComponents() != 1
3226  *  \throw If \a this->getNumberOfTuples() < 1
3227  */
3228 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3229 {
3230   int tmp;
3231   tupleIds=0;
3232   double ret=getMinValue(tmp);
3233   tupleIds=getIdsInRange(ret,ret);
3234   return ret;
3235 }
3236
3237 /*!
3238  * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value.
3239  * This method only works for single component array.
3240  *
3241  * \return a value in [ 0, \c this->getNumberOfTuples() )
3242  *
3243  * \throw If \a this is not allocated
3244  *
3245  */
3246 int DataArrayDouble::count(double value, double eps) const
3247 {
3248   int ret=0;
3249   checkAllocated();
3250   if(getNumberOfComponents()!=1)
3251     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3252   const double *vals=begin();
3253   int nbOfTuples=getNumberOfTuples();
3254   for(int i=0;i<nbOfTuples;i++,vals++)
3255     if(fabs(*vals-value)<=eps)
3256       ret++;
3257   return ret;
3258 }
3259
3260 /*!
3261  * Returns the average value of \a this one-dimensional array.
3262  *  \return double - the average value over all values of \a this array.
3263  *  \throw If \a this->getNumberOfComponents() != 1
3264  *  \throw If \a this->getNumberOfTuples() < 1
3265  */
3266 double DataArrayDouble::getAverageValue() const
3267 {
3268   if(getNumberOfComponents()!=1)
3269     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3270   int nbOfTuples=getNumberOfTuples();
3271   if(nbOfTuples<=0)
3272     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3273   const double *vals=getConstPointer();
3274   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3275   return ret/nbOfTuples;
3276 }
3277
3278 /*!
3279  * Returns the Euclidean norm of the vector defined by \a this array.
3280  *  \return double - the value of the Euclidean norm, i.e.
3281  *          the square root of the inner product of vector.
3282  *  \throw If \a this is not allocated.
3283  */
3284 double DataArrayDouble::norm2() const
3285 {
3286   checkAllocated();
3287   double ret=0.;
3288   std::size_t nbOfElems=getNbOfElems();
3289   const double *pt=getConstPointer();
3290   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3291     ret+=(*pt)*(*pt);
3292   return sqrt(ret);
3293 }
3294
3295 /*!
3296  * Returns the maximum norm of the vector defined by \a this array.
3297  *  \return double - the value of the maximum norm, i.e.
3298  *          the maximal absolute value among values of \a this array.
3299  *  \throw If \a this is not allocated.
3300  */
3301 double DataArrayDouble::normMax() const
3302 {
3303   checkAllocated();
3304   double ret=-1.;
3305   std::size_t nbOfElems=getNbOfElems();
3306   const double *pt=getConstPointer();
3307   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3308     {
3309       double val=std::abs(*pt);
3310       if(val>ret)
3311         ret=val;
3312     }
3313   return ret;
3314 }
3315
3316 /*!
3317  * Accumulates values of each component of \a this array.
3318  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3319  *         by the caller, that is filled by this method with sum value for each
3320  *         component.
3321  *  \throw If \a this is not allocated.
3322  */
3323 void DataArrayDouble::accumulate(double *res) const
3324 {
3325   checkAllocated();
3326   const double *ptr=getConstPointer();
3327   int nbTuple=getNumberOfTuples();
3328   int nbComps=getNumberOfComponents();
3329   std::fill(res,res+nbComps,0.);
3330   for(int i=0;i<nbTuple;i++)
3331     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3332 }
3333
3334 /*!
3335  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3336  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3337  *
3338  *
3339  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3340  * \a tupleEnd. If not an exception will be thrown.
3341  *
3342  * \param [in] tupleBg start pointer (included) of input external tuple
3343  * \param [in] tupleEnd end pointer (not included) of input external tuple
3344  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3345  * \return the min distance.
3346  * \sa MEDCouplingUMesh::distanceToPoint
3347  */
3348 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3349 {
3350   checkAllocated();
3351   int nbTuple=getNumberOfTuples();
3352   int nbComps=getNumberOfComponents();
3353   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3354     { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
3355   if(nbTuple==0)
3356     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3357   double ret0=std::numeric_limits<double>::max();
3358   tupleId=-1;
3359   const double *work=getConstPointer();
3360   for(int i=0;i<nbTuple;i++)
3361     {
3362       double val=0.;
3363       for(int j=0;j<nbComps;j++,work++) 
3364         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3365       if(val>=ret0)
3366         continue;
3367       else
3368         { ret0=val; tupleId=i; }
3369     }
3370   return sqrt(ret0);
3371 }
3372
3373 /*!
3374  * Accumulate values of the given component of \a this array.
3375  *  \param [in] compId - the index of the component of interest.
3376  *  \return double - a sum value of \a compId-th component.
3377  *  \throw If \a this is not allocated.
3378  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3379  *         not respected.
3380  */
3381 double DataArrayDouble::accumulate(int compId) const
3382 {
3383   checkAllocated();
3384   const double *ptr=getConstPointer();
3385   int nbTuple=getNumberOfTuples();
3386   int nbComps=getNumberOfComponents();
3387   if(compId<0 || compId>=nbComps)
3388     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3389   double ret=0.;
3390   for(int i=0;i<nbTuple;i++)
3391     ret+=ptr[i*nbComps+compId];
3392   return ret;
3393 }
3394
3395 /*!
3396  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3397  * The returned array will have same number of components than \a this and number of tuples equal to
3398  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3399  *
3400  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3401  * This method is quite useful for users that need to put a field on cells to field on nodes on the same mesh without a need of conservation.
3402  *
3403  * \param [in] bgOfIndex - begin (included) of the input index array.
3404  * \param [in] endOfIndex - end (excluded) of the input index array.
3405  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3406  * 
3407  * \throw If bgOfIndex or end is NULL.
3408  * \throw If input index array is not ascendingly sorted.
3409  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3410  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3411  */
3412 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3413 {
3414   if(!bgOfIndex || !endOfIndex)
3415     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3416   checkAllocated();
3417   int nbCompo=getNumberOfComponents();
3418   int nbOfTuples=getNumberOfTuples();
3419   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3420   if(sz<1)
3421     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3422   sz--;
3423   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3424   const int *w=bgOfIndex;
3425   if(*w<0 || *w>=nbOfTuples)
3426     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3427   const double *srcPt=begin()+(*w)*nbCompo;
3428   double *tmp=ret->getPointer();
3429   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3430     {
3431       std::fill(tmp,tmp+nbCompo,0.);
3432       if(w[1]>=w[0])
3433         {
3434           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3435             {
3436               if(j>=0 && j<nbOfTuples)
3437                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3438               else
3439                 {
3440                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3441                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3442                 }
3443             }
3444         }
3445       else
3446         {
3447           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3448           throw INTERP_KERNEL::Exception(oss.str().c_str());
3449         }
3450     }
3451   ret->copyStringInfoFrom(*this);
3452   return ret.retn();
3453 }
3454
3455 /*!
3456  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3457  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3458  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3459  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3460  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3461  *          is to delete this array using decrRef() as it is no more needed. The array
3462  *          does not contain any textual info on components.
3463  *  \throw If \a this->getNumberOfComponents() != 2.
3464  */
3465 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3466 {
3467   checkAllocated();
3468   int nbOfComp=getNumberOfComponents();
3469   if(nbOfComp!=2)
3470     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3471   int nbOfTuple=getNumberOfTuples();
3472   DataArrayDouble *ret=DataArrayDouble::New();
3473   ret->alloc(nbOfTuple,2);
3474   double *w=ret->getPointer();
3475   const double *wIn=getConstPointer();
3476   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3477     {
3478       w[0]=wIn[0]*cos(wIn[1]);
3479       w[1]=wIn[0]*sin(wIn[1]);
3480     }
3481   return ret;
3482 }
3483
3484 /*!
3485  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3486  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3487  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3488  * the Cylindrical CS.
3489  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3490  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3491  *          on the third component is copied from \a this array. The caller
3492  *          is to delete this array using decrRef() as it is no more needed. 
3493  *  \throw If \a this->getNumberOfComponents() != 3.
3494  */
3495 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3496 {
3497   checkAllocated();
3498   int nbOfComp=getNumberOfComponents();
3499   if(nbOfComp!=3)
3500     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3501   int nbOfTuple=getNumberOfTuples();
3502   DataArrayDouble *ret=DataArrayDouble::New();
3503   ret->alloc(getNumberOfTuples(),3);
3504   double *w=ret->getPointer();
3505   const double *wIn=getConstPointer();
3506   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3507     {
3508       w[0]=wIn[0]*cos(wIn[1]);
3509       w[1]=wIn[0]*sin(wIn[1]);
3510       w[2]=wIn[2];
3511     }
3512   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3513   return ret;
3514 }
3515
3516 /*!
3517  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3518  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3519  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3520  * point in the Cylindrical CS.
3521  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3522  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3523  *          on the third component is copied from \a this array. The caller
3524  *          is to delete this array using decrRef() as it is no more needed.
3525  *  \throw If \a this->getNumberOfComponents() != 3.
3526  */
3527 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3528 {
3529   checkAllocated();
3530   int nbOfComp=getNumberOfComponents();
3531   if(nbOfComp!=3)
3532     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3533   int nbOfTuple=getNumberOfTuples();
3534   DataArrayDouble *ret=DataArrayDouble::New();
3535   ret->alloc(getNumberOfTuples(),3);
3536   double *w=ret->getPointer();
3537   const double *wIn=getConstPointer();
3538   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3539     {
3540       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3541       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3542       w[2]=wIn[0]*cos(wIn[1]);
3543     }
3544   return ret;
3545 }
3546
3547 /*!
3548  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3549  * array contating 6 components.
3550  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3551  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3552  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3553  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3554  *  \throw If \a this->getNumberOfComponents() != 6.
3555  */
3556 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3557 {
3558   checkAllocated();
3559   int nbOfComp=getNumberOfComponents();
3560   if(nbOfComp!=6)
3561     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3562   DataArrayDouble *ret=DataArrayDouble::New();
3563   int nbOfTuple=getNumberOfTuples();
3564   ret->alloc(nbOfTuple,1);
3565   const double *src=getConstPointer();
3566   double *dest=ret->getPointer();
3567   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3568     *dest=src[0]*src[0]+src[1]*src[1]+src[2]*src[2]+2.*src[3]*src[3]+2.*src[4]*src[4]+2.*src[5]*src[5];
3569   return ret;
3570 }
3571
3572 /*!
3573  * Computes the determinant of every square matrix defined by the tuple of \a this
3574  * array, which contains either 4, 6 or 9 components. The case of 6 components
3575  * corresponds to that of the upper triangular matrix.
3576  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3577  *          is the determinant of matrix of the corresponding tuple of \a this array.
3578  *          The caller is to delete this result array using decrRef() as it is no more
3579  *          needed. 
3580  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3581  */
3582 DataArrayDouble *DataArrayDouble::determinant() const
3583 {
3584   checkAllocated();
3585   DataArrayDouble *ret=DataArrayDouble::New();
3586   int nbOfTuple=getNumberOfTuples();
3587   ret->alloc(nbOfTuple,1);
3588   const double *src=getConstPointer();
3589   double *dest=ret->getPointer();
3590   switch(getNumberOfComponents())
3591     {
3592     case 6:
3593       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3594         *dest=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
3595       return ret;
3596     case 4:
3597       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3598         *dest=src[0]*src[3]-src[1]*src[2];
3599       return ret;
3600     case 9:
3601       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3602         *dest=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6];
3603       return ret;
3604     default:
3605       ret->decrRef();
3606       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3607     }
3608 }
3609
3610 /*!
3611  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3612  * \a this array, which contains 6 components.
3613  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3614  *          components, whose each tuple contains the eigenvalues of the matrix of
3615  *          corresponding tuple of \a this array. 
3616  *          The caller is to delete this result array using decrRef() as it is no more
3617  *          needed. 
3618  *  \throw If \a this->getNumberOfComponents() != 6.
3619  */
3620 DataArrayDouble *DataArrayDouble::eigenValues() const
3621 {
3622   checkAllocated();
3623   int nbOfComp=getNumberOfComponents();
3624   if(nbOfComp!=6)
3625     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3626   DataArrayDouble *ret=DataArrayDouble::New();
3627   int nbOfTuple=getNumberOfTuples();
3628   ret->alloc(nbOfTuple,3);
3629   const double *src=getConstPointer();
3630   double *dest=ret->getPointer();
3631   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3632     INTERP_KERNEL::computeEigenValues6(src,dest);
3633   return ret;
3634 }
3635
3636 /*!
3637  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3638  * \a this array, which contains 6 components.
3639  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3640  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3641  *          corresponding tuple of \a this array.
3642  *          The caller is to delete this result array using decrRef() as it is no more
3643  *          needed.
3644  *  \throw If \a this->getNumberOfComponents() != 6.
3645  */
3646 DataArrayDouble *DataArrayDouble::eigenVectors() const
3647 {
3648   checkAllocated();
3649   int nbOfComp=getNumberOfComponents();
3650   if(nbOfComp!=6)
3651     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3652   DataArrayDouble *ret=DataArrayDouble::New();
3653   int nbOfTuple=getNumberOfTuples();
3654   ret->alloc(nbOfTuple,9);
3655   const double *src=getConstPointer();
3656   double *dest=ret->getPointer();
3657   for(int i=0;i<nbOfTuple;i++,src+=6)
3658     {
3659       double tmp[3];
3660       INTERP_KERNEL::computeEigenValues6(src,tmp);
3661       for(int j=0;j<3;j++,dest+=3)
3662         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3663     }
3664   return ret;
3665 }
3666
3667 /*!
3668  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3669  * array, which contains either 4, 6 or 9 components. The case of 6 components
3670  * corresponds to that of the upper triangular matrix.
3671  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3672  *          same number of components as \a this one, whose each tuple is the inverse
3673  *          matrix of the matrix of corresponding tuple of \a this array. 
3674  *          The caller is to delete this result array using decrRef() as it is no more
3675  *          needed. 
3676  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3677  */
3678 DataArrayDouble *DataArrayDouble::inverse() const
3679 {
3680   checkAllocated();
3681   int nbOfComp=getNumberOfComponents();
3682   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3683     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3684   DataArrayDouble *ret=DataArrayDouble::New();
3685   int nbOfTuple=getNumberOfTuples();
3686   ret->alloc(nbOfTuple,nbOfComp);
3687   const double *src=getConstPointer();
3688   double *dest=ret->getPointer();
3689 if(nbOfComp==6)
3690     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3691       {
3692         double det=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
3693         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3694         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3695         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3696         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3697         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3698         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3699       }
3700   else if(nbOfComp==4)
3701     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3702       {
3703         double det=src[0]*src[3]-src[1]*src[2];
3704         dest[0]=src[3]/det;
3705         dest[1]=-src[1]/det;
3706         dest[2]=-src[2]/det;
3707         dest[3]=src[0]/det;
3708       }
3709   else
3710     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3711       {
3712         double det=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6];
3713         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3714         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3715         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3716         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3717         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3718         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3719         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3720         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3721         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3722       }
3723   return ret;
3724 }
3725
3726 /*!
3727  * Computes the trace of every matrix defined by the tuple of \a this
3728  * array, which contains either 4, 6 or 9 components. The case of 6 components
3729  * corresponds to that of the upper triangular matrix.
3730  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3731  *          1 component, whose each tuple is the trace of
3732  *          the matrix of corresponding tuple of \a this array. 
3733  *          The caller is to delete this result array using decrRef() as it is no more
3734  *          needed. 
3735  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3736  */
3737 DataArrayDouble *DataArrayDouble::trace() const
3738 {
3739   checkAllocated();
3740   int nbOfComp=getNumberOfComponents();
3741   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3742     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3743   DataArrayDouble *ret=DataArrayDouble::New();
3744   int nbOfTuple=getNumberOfTuples();
3745   ret->alloc(nbOfTuple,1);
3746   const double *src=getConstPointer();
3747   double *dest=ret->getPointer();
3748   if(nbOfComp==6)
3749     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3750       *dest=src[0]+src[1]+src[2];
3751   else if(nbOfComp==4)
3752     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3753       *dest=src[0]+src[3];
3754   else
3755     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3756       *dest=src[0]+src[4]+src[8];
3757   return ret;
3758 }
3759
3760 /*!
3761  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3762  * \a this array, which contains 6 components.
3763  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3764  *          same number of components and tuples as \a this array.
3765  *          The caller is to delete this result array using decrRef() as it is no more
3766  *          needed.
3767  *  \throw If \a this->getNumberOfComponents() != 6.
3768  */
3769 DataArrayDouble *DataArrayDouble::deviator() const
3770 {
3771   checkAllocated();
3772   int nbOfComp=getNumberOfComponents();
3773   if(nbOfComp!=6)
3774     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3775   DataArrayDouble *ret=DataArrayDouble::New();
3776   int nbOfTuple=getNumberOfTuples();
3777   ret->alloc(nbOfTuple,6);
3778   const double *src=getConstPointer();
3779   double *dest=ret->getPointer();
3780   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3781     {
3782       double tr=(src[0]+src[1]+src[2])/3.;
3783       dest[0]=src[0]-tr;
3784       dest[1]=src[1]-tr;
3785       dest[2]=src[2]-tr;
3786       dest[3]=src[3];
3787       dest[4]=src[4];
3788       dest[5]=src[5];
3789     }
3790   return ret;
3791 }
3792
3793 /*!
3794  * Computes the magnitude of every vector defined by the tuple of
3795  * \a this array.
3796  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3797  *          same number of tuples as \a this array and one component.
3798  *          The caller is to delete this result array using decrRef() as it is no more
3799  *          needed.
3800  *  \throw If \a this is not allocated.
3801  */
3802 DataArrayDouble *DataArrayDouble::magnitude() const
3803 {
3804   checkAllocated();
3805   int nbOfComp=getNumberOfComponents();
3806   DataArrayDouble *ret=DataArrayDouble::New();
3807   int nbOfTuple=getNumberOfTuples();
3808   ret->alloc(nbOfTuple,1);
3809   const double *src=getConstPointer();
3810   double *dest=ret->getPointer();
3811   for(int i=0;i<nbOfTuple;i++,dest++)
3812     {
3813       double sum=0.;
3814       for(int j=0;j<nbOfComp;j++,src++)
3815         sum+=(*src)*(*src);
3816       *dest=sqrt(sum);
3817     }
3818   return ret;
3819 }
3820
3821 /*!
3822  * Computes for each tuple the sum of number of components values in the tuple and return it.
3823  * 
3824  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3825  *          same number of tuples as \a this array and one component.
3826  *          The caller is to delete this result array using decrRef() as it is no more
3827  *          needed.
3828  *  \throw If \a this is not allocated.
3829  */
3830 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3831 {
3832   checkAllocated();
3833   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3834   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3835   ret->alloc(nbOfTuple,1);
3836   const double *src(getConstPointer());
3837   double *dest(ret->getPointer());
3838   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3839     *dest=std::accumulate(src,src+nbOfComp,0.);
3840   return ret.retn();
3841 }
3842
3843 /*!
3844  * Computes the maximal value within every tuple of \a this array.
3845  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3846  *          same number of tuples as \a this array and one component.
3847  *          The caller is to delete this result array using decrRef() as it is no more
3848  *          needed.
3849  *  \throw If \a this is not allocated.
3850  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3851  */
3852 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3853 {
3854   checkAllocated();
3855   int nbOfComp=getNumberOfComponents();
3856   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3857   int nbOfTuple=getNumberOfTuples();
3858   ret->alloc(nbOfTuple,1);
3859   const double *src=getConstPointer();
3860   double *dest=ret->getPointer();
3861   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3862     *dest=*std::max_element(src,src+nbOfComp);
3863   return ret.retn();
3864 }
3865
3866 /*!
3867  * Computes the maximal value within every tuple of \a this array and it returns the first component
3868  * id for each tuple that corresponds to the maximal value within the tuple.
3869  * 
3870  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3871  *          same number of tuples and only one component.
3872  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3873  *          same number of tuples as \a this array and one component.
3874  *          The caller is to delete this result array using decrRef() as it is no more
3875  *          needed.
3876  *  \throw If \a this is not allocated.
3877  *  \sa DataArrayDouble::maxPerTuple
3878  */
3879 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3880 {
3881   checkAllocated();
3882   int nbOfComp=getNumberOfComponents();
3883   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3884   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3885   int nbOfTuple=getNumberOfTuples();
3886   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3887   const double *src=getConstPointer();
3888   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3889   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3890     {
3891       const double *loc=std::max_element(src,src+nbOfComp);
3892       *dest=*loc;
3893       *dest1=(int)std::distance(src,loc);
3894     }
3895   compoIdOfMaxPerTuple=ret1.retn();
3896   return ret0.retn();
3897 }
3898
3899 /*!
3900  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3901  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3902  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3903  * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble)
3904  *
3905  * \warning use this method with care because it can leads to big amount of consumed memory !
3906  * 
3907  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3908  *
3909  * \throw If \a this is not allocated.
3910  *
3911  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3912  */
3913 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3914 {
3915   checkAllocated();
3916   int nbOfComp=getNumberOfComponents();
3917   int nbOfTuples=getNumberOfTuples();
3918   const double *inData=getConstPointer();
3919   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3920   ret->alloc(nbOfTuples*nbOfTuples,1);
3921   double *outData=ret->getPointer();
3922   for(int i=0;i<nbOfTuples;i++)
3923     {
3924       outData[i*nbOfTuples+i]=0.;
3925       for(int j=i+1;j<nbOfTuples;j++)
3926         {
3927           double dist=0.;
3928           for(int k=0;k<nbOfComp;k++)
3929             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3930           dist=sqrt(dist);
3931           outData[i*nbOfTuples+j]=dist;
3932           outData[j*nbOfTuples+i]=dist;
3933         }
3934     }
3935   return ret.retn();
3936 }
3937
3938 /*!
3939  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3940  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3941  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3942  * \n Output rectangular matrix is sorted along rows.
3943  * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble)
3944  *
3945  * \warning use this method with care because it can leads to big amount of consumed memory !
3946  * 
3947  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3948  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3949  *
3950  * \throw If \a this is not allocated, or if \a other is null or if \a other is not allocated, or if number of components of \a other and \a this differs.
3951  *
3952  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3953  */
3954 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
3955 {
3956   if(!other)
3957     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3958   checkAllocated();
3959   other->checkAllocated();
3960   int nbOfComp=getNumberOfComponents();
3961   int otherNbOfComp=other->getNumberOfComponents();
3962   if(nbOfComp!=otherNbOfComp)
3963     {
3964       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3965       throw INTERP_KERNEL::Exception(oss.str().c_str());
3966     }
3967   int nbOfTuples=getNumberOfTuples();
3968   int otherNbOfTuples=other->getNumberOfTuples();
3969   const double *inData=getConstPointer();
3970   const double *inDataOther=other->getConstPointer();
3971   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3972   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3973   double *outData=ret->getPointer();
3974   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3975     {
3976       for(int j=0;j<nbOfTuples;j++)
3977         {
3978           double dist=0.;
3979           for(int k=0;k<nbOfComp;k++)
3980             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3981           dist=sqrt(dist);
3982           outData[i*nbOfTuples+j]=dist;
3983         }
3984     }
3985   return ret.retn();
3986 }
3987
3988 /*!
3989  * Sorts value within every tuple of \a this array.
3990  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3991  *              in descending order.
3992  *  \throw If \a this is not allocated.
3993  */
3994 void DataArrayDouble::sortPerTuple(bool asc)
3995 {
3996   checkAllocated();
3997   double *pt=getPointer();
3998   int nbOfTuple=getNumberOfTuples();
3999   int nbOfComp=getNumberOfComponents();
4000   if(asc)
4001     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4002       std::sort(pt,pt+nbOfComp);
4003   else
4004     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4005       std::sort(pt,pt+nbOfComp,std::greater<double>());
4006   declareAsNew();
4007 }
4008
4009 /*!
4010  * Converts every value of \a this array to its absolute value.
4011  *  \throw If \a this is not allocated.
4012  */
4013 void DataArrayDouble::abs()
4014 {
4015   checkAllocated();
4016   double *ptr=getPointer();
4017   std::size_t nbOfElems=getNbOfElems();
4018   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4019   declareAsNew();
4020 }
4021
4022 /*!
4023  * Apply a liner function to a given component of \a this array, so that
4024  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4025  *  \param [in] a - the first coefficient of the function.
4026  *  \param [in] b - the second coefficient of the function.
4027  *  \param [in] compoId - the index of component to modify.
4028  *  \throw If \a this is not allocated.
4029  */
4030 void DataArrayDouble::applyLin(double a, double b, int compoId)
4031 {
4032   checkAllocated();
4033   double *ptr=getPointer()+compoId;
4034   int nbOfComp=getNumberOfComponents();
4035   int nbOfTuple=getNumberOfTuples();
4036   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4037     *ptr=a*(*ptr)+b;
4038   declareAsNew();
4039 }
4040
4041 /*!
4042  * Apply a liner function to all elements of \a this array, so that
4043  * an element _x_ becomes \f$ a * x + b \f$.
4044  *  \param [in] a - the first coefficient of the function.
4045  *  \param [in] b - the second coefficient of the function.
4046  *  \throw If \a this is not allocated.
4047  */
4048 void DataArrayDouble::applyLin(double a, double b)
4049 {
4050   checkAllocated();
4051   double *ptr=getPointer();
4052   std::size_t nbOfElems=getNbOfElems();
4053   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4054     *ptr=a*(*ptr)+b;
4055   declareAsNew();
4056 }
4057
4058 /*!
4059  * Modify all elements of \a this array, so that
4060  * an element _x_ becomes \f$ numerator / x \f$.
4061  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4062  *           array, all elements processed before detection of the zero element remain
4063  *           modified.
4064  *  \param [in] numerator - the numerator used to modify array elements.
4065  *  \throw If \a this is not allocated.
4066  *  \throw If there is an element equal to 0.0 in \a this array.
4067  */
4068 void DataArrayDouble::applyInv(double numerator)
4069 {
4070   checkAllocated();
4071   double *ptr=getPointer();
4072   std::size_t nbOfElems=getNbOfElems();
4073   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4074     {
4075       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4076         {
4077           *ptr=numerator/(*ptr);
4078         }
4079       else
4080         {
4081           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4082           oss << " !";
4083           throw INTERP_KERNEL::Exception(oss.str().c_str());
4084         }
4085     }
4086   declareAsNew();
4087 }
4088
4089 /*!
4090  * Returns a full copy of \a this array except that sign of all elements is reversed.
4091  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4092  *          same number of tuples and component as \a this array.
4093  *          The caller is to delete this result array using decrRef() as it is no more
4094  *          needed.
4095  *  \throw If \a this is not allocated.
4096  */
4097 DataArrayDouble *DataArrayDouble::negate() const
4098 {
4099   checkAllocated();
4100   DataArrayDouble *newArr=DataArrayDouble::New();
4101   int nbOfTuples=getNumberOfTuples();
4102   int nbOfComp=getNumberOfComponents();
4103   newArr->alloc(nbOfTuples,nbOfComp);
4104   const double *cptr=getConstPointer();
4105   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4106   newArr->copyStringInfoFrom(*this);
4107   return newArr;
4108 }
4109
4110 /*!
4111  * Modify all elements of \a this array, so that
4112  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4113  * all values in \a this have to be >= 0 if val is \b not integer.
4114  *  \param [in] val - the value used to apply pow on all array elements.
4115  *  \throw If \a this is not allocated.
4116  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4117  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4118  *           modified.
4119  */
4120 void DataArrayDouble::applyPow(double val)
4121 {
4122   checkAllocated();
4123   double *ptr=getPointer();
4124   std::size_t nbOfElems=getNbOfElems();
4125   int val2=(int)val;
4126   bool isInt=((double)val2)==val;
4127   if(!isInt)
4128     {
4129       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4130         {
4131           if(*ptr>=0)
4132             *ptr=pow(*ptr,val);
4133           else
4134             {
4135               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4136               throw INTERP_KERNEL::Exception(oss.str().c_str());
4137             }
4138         }
4139     }
4140   else
4141     {
4142       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4143         *ptr=pow(*ptr,val2);
4144     }
4145   declareAsNew();
4146 }
4147
4148 /*!
4149  * Modify all elements of \a this array, so that
4150  * an element _x_ becomes \f$ val ^ x \f$.
4151  *  \param [in] val - the value used to apply pow on all array elements.
4152  *  \throw If \a this is not allocated.
4153  *  \throw If \a val < 0.
4154  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4155  *           array, all elements processed before detection of the zero element remain
4156  *           modified.
4157  */
4158 void DataArrayDouble::applyRPow(double val)
4159 {
4160   checkAllocated();
4161   if(val<0.)
4162     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4163   double *ptr=getPointer();
4164   std::size_t nbOfElems=getNbOfElems();
4165   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4166     *ptr=pow(val,*ptr);
4167   declareAsNew();
4168 }
4169
4170 /*!
4171  * Returns a new DataArrayDouble created from \a this one by applying \a
4172  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4173  * For more info see \ref MEDCouplingArrayApplyFunc
4174  *  \param [in] nbOfComp - number of components in the result array.
4175  *  \param [in] func - the \a FunctionToEvaluate declared as 
4176  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4177  *              where \a pos points to the first component of a tuple of \a this array
4178  *              and \a res points to the first component of a tuple of the result array.
4179  *              Note that length (number of components) of \a pos can differ from
4180  *              that of \a res.
4181  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4182  *          same number of tuples as \a this array.
4183  *          The caller is to delete this result array using decrRef() as it is no more
4184  *          needed.
4185  *  \throw If \a this is not allocated.
4186  *  \throw If \a func returns \a false.
4187  */
4188 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4189 {
4190   checkAllocated();
4191   DataArrayDouble *newArr=DataArrayDouble::New();
4192   int nbOfTuples=getNumberOfTuples();
4193   int oldNbOfComp=getNumberOfComponents();
4194   newArr->alloc(nbOfTuples,nbOfComp);
4195   const double *ptr=getConstPointer();
4196   double *ptrToFill=newArr->getPointer();
4197   for(int i=0;i<nbOfTuples;i++)
4198     {
4199       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4200         {
4201           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4202           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4203           oss << ") : Evaluation of function failed !";
4204           newArr->decrRef();
4205           throw INTERP_KERNEL::Exception(oss.str().c_str());
4206         }
4207     }
4208   return newArr;
4209 }
4210
4211 /*!
4212  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4213  * tuple of \a this array. Textual data is not copied.
4214  * For more info see \ref MEDCouplingArrayApplyFunc1.
4215  *  \param [in] nbOfComp - number of components in the result array.
4216  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4217  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4218  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4219  *          same number of tuples as \a this array and \a nbOfComp components.
4220  *          The caller is to delete this result array using decrRef() as it is no more
4221  *          needed.
4222  *  \throw If \a this is not allocated.
4223  *  \throw If computing \a func fails.
4224  */
4225 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const
4226 {
4227   checkAllocated();
4228   INTERP_KERNEL::ExprParser expr(func);
4229   expr.parse();
4230   std::set<std::string> vars;
4231   expr.getTrueSetOfVars(vars);
4232   int oldNbOfComp=getNumberOfComponents();
4233   if((int)vars.size()>oldNbOfComp)
4234     {
4235       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4236       oss << vars.size() << " variables : ";
4237       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4238       throw INTERP_KERNEL::Exception(oss.str().c_str());
4239     }
4240   std::vector<std::string> varsV(vars.begin(),vars.end());
4241   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4242   //
4243   DataArrayDouble *newArr=DataArrayDouble::New();
4244   int nbOfTuples=getNumberOfTuples();
4245   newArr->alloc(nbOfTuples,nbOfComp);
4246   const double *ptr=getConstPointer();
4247   double *ptrToFill=newArr->getPointer();
4248   for(int i=0;i<nbOfTuples;i++)
4249     {
4250       try
4251         {
4252           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4253         }
4254       catch(INTERP_KERNEL::Exception& e)
4255         {
4256           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4257           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4258           oss << ") : Evaluation of function failed !" << e.what();
4259           newArr->decrRef();
4260           throw INTERP_KERNEL::Exception(oss.str().c_str());
4261         }
4262     }
4263   return newArr;
4264 }
4265
4266 /*!
4267  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4268  * tuple of \a this array. Textual data is not copied.
4269  * For more info see \ref MEDCouplingArrayApplyFunc0.
4270  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4271  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4272  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4273  *          same number of tuples and components as \a this array.
4274  *          The caller is to delete this result array using decrRef() as it is no more
4275  *          needed.
4276  *  \throw If \a this is not allocated.
4277  *  \throw If computing \a func fails.
4278  */
4279 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const
4280 {
4281   checkAllocated();
4282   INTERP_KERNEL::ExprParser expr(func);
4283   expr.parse();
4284   expr.prepareExprEvaluationVec();
4285   //
4286   DataArrayDouble *newArr=DataArrayDouble::New();
4287   int nbOfTuples=getNumberOfTuples();
4288   int nbOfComp=getNumberOfComponents();
4289   newArr->alloc(nbOfTuples,nbOfComp);
4290   const double *ptr=getConstPointer();
4291   double *ptrToFill=newArr->getPointer();
4292   for(int i=0;i<nbOfTuples;i++)
4293     {
4294       try
4295         {
4296           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4297         }
4298       catch(INTERP_KERNEL::Exception& e)
4299         {
4300           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4301           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4302           oss << ") : Evaluation of function failed ! " << e.what();
4303           newArr->decrRef();
4304           throw INTERP_KERNEL::Exception(oss.str().c_str());
4305         }
4306     }
4307   return newArr;
4308 }
4309
4310 /*!
4311  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4312  * tuple of \a this array. Textual data is not copied.
4313  * For more info see \ref MEDCouplingArrayApplyFunc2.
4314  *  \param [in] nbOfComp - number of components in the result array.
4315  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4316  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4317  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4318  *          same number of tuples as \a this array.
4319  *          The caller is to delete this result array using decrRef() as it is no more
4320  *          needed.
4321  *  \throw If \a this is not allocated.
4322  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4323  *  \throw If computing \a func fails.
4324  */
4325 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const
4326 {
4327   checkAllocated();
4328   INTERP_KERNEL::ExprParser expr(func);
4329   expr.parse();
4330   std::set<std::string> vars;
4331   expr.getTrueSetOfVars(vars);
4332   int oldNbOfComp=getNumberOfComponents();
4333   if((int)vars.size()>oldNbOfComp)
4334     {
4335       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4336       oss << vars.size() << " variables : ";
4337       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4338       throw INTERP_KERNEL::Exception(oss.str().c_str());
4339     }
4340   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4341   //
4342   DataArrayDouble *newArr=DataArrayDouble::New();
4343   int nbOfTuples=getNumberOfTuples();
4344   newArr->alloc(nbOfTuples,nbOfComp);
4345   const double *ptr=getConstPointer();
4346   double *ptrToFill=newArr->getPointer();
4347   for(int i=0;i<nbOfTuples;i++)
4348     {
4349       try
4350         {
4351           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4352         }
4353       catch(INTERP_KERNEL::Exception& e)
4354         {
4355           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4356           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4357           oss << ") : Evaluation of function failed !" << e.what();
4358           newArr->decrRef();
4359           throw INTERP_KERNEL::Exception(oss.str().c_str());
4360         }
4361     }
4362   return newArr;
4363 }
4364
4365 /*!
4366  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4367  * tuple of \a this array. Textual data is not copied.
4368  * For more info see \ref MEDCouplingArrayApplyFunc3.
4369  *  \param [in] nbOfComp - number of components in the result array.
4370  *  \param [in] varsOrder - sequence of vars defining their order.
4371  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4372  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4373  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4374  *          same number of tuples as \a this array.
4375  *          The caller is to delete this result array using decrRef() as it is no more
4376  *          needed.
4377  *  \throw If \a this is not allocated.
4378  *  \throw If \a func contains vars not in \a varsOrder.
4379  *  \throw If computing \a func fails.
4380  */
4381 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
4382 {
4383   checkAllocated();
4384   INTERP_KERNEL::ExprParser expr(func);
4385   expr.parse();
4386   std::set<std::string> vars;
4387   expr.getTrueSetOfVars(vars);
4388   int oldNbOfComp=getNumberOfComponents();
4389   if((int)vars.size()>oldNbOfComp)
4390     {
4391       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4392       oss << vars.size() << " variables : ";
4393       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4394       throw INTERP_KERNEL::Exception(oss.str().c_str());
4395     }
4396   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4397   //
4398   DataArrayDouble *newArr=DataArrayDouble::New();
4399   int nbOfTuples=getNumberOfTuples();
4400   newArr->alloc(nbOfTuples,nbOfComp);
4401   const double *ptr=getConstPointer();
4402   double *ptrToFill=newArr->getPointer();
4403   for(int i=0;i<nbOfTuples;i++)
4404     {
4405       try
4406         {
4407           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4408         }
4409       catch(INTERP_KERNEL::Exception& e)
4410         {
4411           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4412           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4413           oss << ") : Evaluation of function failed !" << e.what();
4414           newArr->decrRef();
4415           throw INTERP_KERNEL::Exception(oss.str().c_str());
4416         }
4417     }
4418   return newArr;
4419 }
4420
4421 void DataArrayDouble::applyFuncFast32(const char *func)
4422 {
4423   checkAllocated();
4424   INTERP_KERNEL::ExprParser expr(func);
4425   expr.parse();
4426   char *funcStr=expr.compileX86();
4427   MYFUNCPTR funcPtr;
4428   *((void **)&funcPtr)=funcStr;//he he...
4429   //
4430   double *ptr=getPointer();
4431   int nbOfComp=getNumberOfComponents();
4432   int nbOfTuples=getNumberOfTuples();
4433   int nbOfElems=nbOfTuples*nbOfComp;
4434   for(int i=0;i<nbOfElems;i++,ptr++)
4435     *ptr=funcPtr(*ptr);
4436   declareAsNew();
4437 }
4438
4439 void DataArrayDouble::applyFuncFast64(const char *func)
4440 {
4441   checkAllocated();
4442   INTERP_KERNEL::ExprParser expr(func);
4443   expr.parse();
4444   char *funcStr=expr.compileX86_64();
4445   MYFUNCPTR funcPtr;
4446   *((void **)&funcPtr)=funcStr;//he he...
4447   //
4448   double *ptr=getPointer();
4449   int nbOfComp=getNumberOfComponents();
4450   int nbOfTuples=getNumberOfTuples();
4451   int nbOfElems=nbOfTuples*nbOfComp;
4452   for(int i=0;i<nbOfElems;i++,ptr++)
4453     *ptr=funcPtr(*ptr);
4454   declareAsNew();
4455 }
4456
4457 DataArrayDoubleIterator *DataArrayDouble::iterator()
4458 {
4459   return new DataArrayDoubleIterator(this);
4460 }
4461
4462 /*!
4463  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4464  * array whose values are within a given range. Textual data is not copied.
4465  *  \param [in] vmin - a lowest acceptable value (included).
4466  *  \param [in] vmax - a greatest acceptable value (included).
4467  *  \return DataArrayInt * - the new instance of DataArrayInt.
4468  *          The caller is to delete this result array using decrRef() as it is no more
4469  *          needed.
4470  *  \throw If \a this->getNumberOfComponents() != 1.
4471  *
4472  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4473  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4474  */
4475 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4476 {
4477   checkAllocated();
4478   if(getNumberOfComponents()!=1)
4479     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4480   const double *cptr=getConstPointer();
4481   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4482   int nbOfTuples=getNumberOfTuples();
4483   for(int i=0;i<nbOfTuples;i++,cptr++)
4484     if(*cptr>=vmin && *cptr<=vmax)
4485       ret->pushBackSilent(i);
4486   return ret.retn();
4487 }
4488
4489 /*!
4490  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4491  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4492  * the number of component in the result array is same as that of each of given arrays.
4493  * Info on components is copied from the first of the given arrays. Number of components
4494  * in the given arrays must be  the same.
4495  *  \param [in] a1 - an array to include in the result array.
4496  *  \param [in] a2 - another array to include in the result array.
4497  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4498  *          The caller is to delete this result array using decrRef() as it is no more
4499  *          needed.
4500  *  \throw If both \a a1 and \a a2 are NULL.
4501  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4502  */
4503 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4504 {
4505   std::vector<const DataArrayDouble *> tmp(2);
4506   tmp[0]=a1; tmp[1]=a2;
4507   return Aggregate(tmp);
4508 }
4509
4510 /*!
4511  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4512  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4513  * the number of component in the result array is same as that of each of given arrays.
4514  * Info on components is copied from the first of the given arrays. Number of components
4515  * in the given arrays must be  the same.
4516  *  \param [in] arr - a sequence of arrays to include in the result array.
4517  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4518  *          The caller is to delete this result array using decrRef() as it is no more
4519  *          needed.
4520  *  \throw If all arrays within \a arr are NULL.
4521  *  \throw If getNumberOfComponents() of arrays within \a arr.
4522  */
4523 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4524 {
4525   std::vector<const DataArrayDouble *> a;
4526   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4527     if(*it4)
4528       a.push_back(*it4);
4529   if(a.empty())
4530     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4531   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4532   int nbOfComp=(*it)->getNumberOfComponents();
4533   int nbt=(*it++)->getNumberOfTuples();
4534   for(int i=1;it!=a.end();it++,i++)
4535     {
4536       if((*it)->getNumberOfComponents()!=nbOfComp)
4537         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4538       nbt+=(*it)->getNumberOfTuples();
4539     }
4540   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4541   ret->alloc(nbt,nbOfComp);
4542   double *pt=ret->getPointer();
4543   for(it=a.begin();it!=a.end();it++)
4544     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4545   ret->copyStringInfoFrom(*(a[0]));
4546   return ret.retn();
4547 }
4548
4549 /*!
4550  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4551  * of components in the result array is a sum of the number of components of given arrays
4552  * and (2) the number of tuples in the result array is same as that of each of given
4553  * arrays. In other words the i-th tuple of result array includes all components of
4554  * i-th tuples of all given arrays.
4555  * Number of tuples in the given arrays must be  the same.
4556  *  \param [in] a1 - an array to include in the result array.
4557  *  \param [in] a2 - another array to include in the result array.
4558  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4559  *          The caller is to delete this result array using decrRef() as it is no more
4560  *          needed.
4561  *  \throw If both \a a1 and \a a2 are NULL.
4562  *  \throw If any given array is not allocated.
4563  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4564  */
4565 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4566 {
4567   std::vector<const DataArrayDouble *> arr(2);
4568   arr[0]=a1; arr[1]=a2;
4569   return Meld(arr);
4570 }
4571
4572 /*!
4573  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4574  * of components in the result array is a sum of the number of components of given arrays
4575  * and (2) the number of tuples in the result array is same as that of each of given
4576  * arrays. In other words the i-th tuple of result array includes all components of
4577  * i-th tuples of all given arrays.
4578  * Number of tuples in the given arrays must be  the same.
4579  *  \param [in] arr - a sequence of arrays to include in the result array.
4580  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4581  *          The caller is to delete this result array using decrRef() as it is no more
4582  *          needed.
4583  *  \throw If all arrays within \a arr are NULL.
4584  *  \throw If any given array is not allocated.
4585  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4586  */
4587 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4588 {
4589   std::vector<const DataArrayDouble *> a;
4590   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4591     if(*it4)
4592       a.push_back(*it4);
4593   if(a.empty())
4594     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4595   std::vector<const DataArrayDouble *>::const_iterator it;
4596   for(it=a.begin();it!=a.end();it++)
4597     (*it)->checkAllocated();
4598   it=a.begin();
4599   int nbOfTuples=(*it)->getNumberOfTuples();
4600   std::vector<int> nbc(a.size());
4601   std::vector<const double *> pts(a.size());
4602   nbc[0]=(*it)->getNumberOfComponents();
4603   pts[0]=(*it++)->getConstPointer();
4604   for(int i=1;it!=a.end();it++,i++)
4605     {
4606       if(nbOfTuples!=(*it)->getNumberOfTuples())
4607         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4608       nbc[i]=(*it)->getNumberOfComponents();
4609       pts[i]=(*it)->getConstPointer();
4610     }
4611   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4612   DataArrayDouble *ret=DataArrayDouble::New();
4613   ret->alloc(nbOfTuples,totalNbOfComp);
4614   double *retPtr=ret->getPointer();
4615   for(int i=0;i<nbOfTuples;i++)
4616     for(int j=0;j<(int)a.size();j++)
4617       {
4618         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4619         pts[j]+=nbc[j];
4620       }
4621   int k=0;
4622   for(int i=0;i<(int)a.size();i++)
4623     for(int j=0;j<nbc[i];j++,k++)
4624       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4625   return ret;
4626 }
4627
4628 /*!
4629  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4630  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4631  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4632  * Info on components and name is copied from the first of the given arrays.
4633  * Number of tuples and components in the given arrays must be the same.
4634  *  \param [in] a1 - a given array.
4635  *  \param [in] a2 - another given array.
4636  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4637  *          The caller is to delete this result array using decrRef() as it is no more
4638  *          needed.
4639  *  \throw If either \a a1 or \a a2 is NULL.
4640  *  \throw If any given array is not allocated.
4641  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4642  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4643  */
4644 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4645 {
4646   if(!a1 || !a2)
4647     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4648   a1->checkAllocated();
4649   a2->checkAllocated();
4650   int nbOfComp=a1->getNumberOfComponents();
4651   if(nbOfComp!=a2->getNumberOfComponents())
4652     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4653   int nbOfTuple=a1->getNumberOfTuples();
4654   if(nbOfTuple!=a2->getNumberOfTuples())
4655     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4656   DataArrayDouble *ret=DataArrayDouble::New();
4657   ret->alloc(nbOfTuple,1);
4658   double *retPtr=ret->getPointer();
4659   const double *a1Ptr=a1->getConstPointer();
4660   const double *a2Ptr=a2->getConstPointer();
4661   for(int i=0;i<nbOfTuple;i++)
4662     {
4663       double sum=0.;
4664       for(int j=0;j<nbOfComp;j++)
4665         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4666       retPtr[i]=sum;
4667     }
4668   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4669   ret->setName(a1->getName().c_str());
4670   return ret;
4671 }
4672
4673 /*!
4674  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4675  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4676  * product of two vectors defined by the i-th tuples of given arrays.
4677  * Info on components is copied from the first of the given arrays.
4678  * Number of tuples in the given arrays must be the same.
4679  * Number of components in the given arrays must be 3.
4680  *  \param [in] a1 - a given array.
4681  *  \param [in] a2 - another given array.
4682  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4683  *          The caller is to delete this result array using decrRef() as it is no more
4684  *          needed.
4685  *  \throw If either \a a1 or \a a2 is NULL.
4686  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4687  *  \throw If \a a1->getNumberOfComponents() != 3
4688  *  \throw If \a a2->getNumberOfComponents() != 3
4689  */
4690 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4691 {
4692   if(!a1 || !a2)
4693     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4694   int nbOfComp=a1->getNumberOfComponents();
4695   if(nbOfComp!=a2->getNumberOfComponents())
4696     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4697   if(nbOfComp!=3)
4698     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4699   int nbOfTuple=a1->getNumberOfTuples();
4700   if(nbOfTuple!=a2->getNumberOfTuples())
4701     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4702   DataArrayDouble *ret=DataArrayDouble::New();
4703   ret->alloc(nbOfTuple,3);
4704   double *retPtr=ret->getPointer();
4705   const double *a1Ptr=a1->getConstPointer();
4706   const double *a2Ptr=a2->getConstPointer();
4707   for(int i=0;i<nbOfTuple;i++)
4708     {
4709       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4710       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4711       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4712     }
4713   ret->copyStringInfoFrom(*a1);
4714   return ret;
4715 }
4716
4717 /*!
4718  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4719  * Info on components is copied from the first of the given arrays.
4720  * Number of tuples and components in the given arrays must be the same.
4721  *  \param [in] a1 - an array to compare values with another one.
4722  *  \param [in] a2 - another array to compare values with the first one.
4723  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4724  *          The caller is to delete this result array using decrRef() as it is no more
4725  *          needed.
4726  *  \throw If either \a a1 or \a a2 is NULL.
4727  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4728  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4729  */
4730 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4731 {
4732   if(!a1 || !a2)
4733     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4734   int nbOfComp=a1->getNumberOfComponents();
4735   if(nbOfComp!=a2->getNumberOfComponents())
4736     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4737   int nbOfTuple=a1->getNumberOfTuples();
4738   if(nbOfTuple!=a2->getNumberOfTuples())
4739     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4740   DataArrayDouble *ret=DataArrayDouble::New();
4741   ret->alloc(nbOfTuple,nbOfComp);
4742   double *retPtr=ret->getPointer();
4743   const double *a1Ptr=a1->getConstPointer();
4744   const double *a2Ptr=a2->getConstPointer();
4745   int nbElem=nbOfTuple*nbOfComp;
4746   for(int i=0;i<nbElem;i++)
4747     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4748   ret->copyStringInfoFrom(*a1);
4749   return ret;
4750 }
4751
4752 /*!
4753  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4754  * Info on components is copied from the first of the given arrays.
4755  * Number of tuples and components in the given arrays must be the same.
4756  *  \param [in] a1 - an array to compare values with another one.
4757  *  \param [in] a2 - another array to compare values with the first one.
4758  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4759  *          The caller is to delete this result array using decrRef() as it is no more
4760  *          needed.
4761  *  \throw If either \a a1 or \a a2 is NULL.
4762  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4763  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4764  */
4765 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4766 {
4767   if(!a1 || !a2)
4768     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4769   int nbOfComp=a1->getNumberOfComponents();
4770   if(nbOfComp!=a2->getNumberOfComponents())
4771     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4772   int nbOfTuple=a1->getNumberOfTuples();
4773   if(nbOfTuple!=a2->getNumberOfTuples())
4774     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4775   DataArrayDouble *ret=DataArrayDouble::New();
4776   ret->alloc(nbOfTuple,nbOfComp);
4777   double *retPtr=ret->getPointer();
4778   const double *a1Ptr=a1->getConstPointer();
4779   const double *a2Ptr=a2->getConstPointer();
4780   int nbElem=nbOfTuple*nbOfComp;
4781   for(int i=0;i<nbElem;i++)
4782     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4783   ret->copyStringInfoFrom(*a1);
4784   return ret;
4785 }
4786
4787 /*!
4788  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4789  * valid cases.
4790  * 1.  The arrays have same number of tuples and components. Then each value of
4791  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4792  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4793  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4794  *   component. Then
4795  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4796  * 3.  The arrays have same number of components and one array, say _a2_, has one
4797  *   tuple. Then
4798  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4799  *
4800  * Info on components is copied either from the first array (in the first case) or from
4801  * the array with maximal number of elements (getNbOfElems()).
4802  *  \param [in] a1 - an array to sum up.
4803  *  \param [in] a2 - another array to sum up.
4804  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4805  *          The caller is to delete this result array using decrRef() as it is no more
4806  *          needed.
4807  *  \throw If either \a a1 or \a a2 is NULL.
4808  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4809  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4810  *         none of them has number of tuples or components equal to 1.
4811  */
4812 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4813 {
4814   if(!a1 || !a2)
4815     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4816   int nbOfTuple=a1->getNumberOfTuples();
4817   int nbOfTuple2=a2->getNumberOfTuples();
4818   int nbOfComp=a1->getNumberOfComponents();
4819   int nbOfComp2=a2->getNumberOfComponents();
4820   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4821   if(nbOfTuple==nbOfTuple2)
4822     {
4823       if(nbOfComp==nbOfComp2)
4824         {
4825           ret=DataArrayDouble::New();
4826           ret->alloc(nbOfTuple,nbOfComp);
4827           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4828           ret->copyStringInfoFrom(*a1);
4829         }
4830       else
4831         {
4832           int nbOfCompMin,nbOfCompMax;
4833           const DataArrayDouble *aMin, *aMax;
4834           if(nbOfComp>nbOfComp2)
4835             {
4836               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4837               aMin=a2; aMax=a1;
4838             }
4839           else
4840             {
4841               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4842               aMin=a1; aMax=a2;
4843             }
4844           if(nbOfCompMin==1)
4845             {
4846               ret=DataArrayDouble::New();
4847               ret->alloc(nbOfTuple,nbOfCompMax);
4848               const double *aMinPtr=aMin->getConstPointer();
4849               const double *aMaxPtr=aMax->getConstPointer();
4850               double *res=ret->getPointer();
4851               for(int i=0;i<nbOfTuple;i++)
4852                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4853               ret->copyStringInfoFrom(*aMax);
4854             }
4855           else
4856             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4857         }
4858     }
4859   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4860     {
4861       if(nbOfComp==nbOfComp2)
4862         {
4863           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4864           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4865           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4866           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4867           ret=DataArrayDouble::New();
4868           ret->alloc(nbOfTupleMax,nbOfComp);
4869           double *res=ret->getPointer();
4870           for(int i=0;i<nbOfTupleMax;i++)
4871             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4872           ret->copyStringInfoFrom(*aMax);
4873         }
4874       else
4875         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4876     }
4877   else
4878     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4879   return ret.retn();
4880 }
4881
4882 /*!
4883  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4884  * valid cases.
4885  * 1.  The arrays have same number of tuples and components. Then each value of
4886  *   \a other array is added to the corresponding value of \a this array, i.e.:
4887  *   _a_ [ i, j ] += _other_ [ i, j ].
4888  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4889  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4890  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4891  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4892  *
4893  *  \param [in] other - an array to add to \a this one.
4894  *  \throw If \a other is NULL.
4895  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4896  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4897  *         \a other has number of both tuples and components not equal to 1.
4898  */
4899 void DataArrayDouble::addEqual(const DataArrayDouble *other)
4900 {
4901   if(!other)
4902     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4903   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4904   checkAllocated();
4905   other->checkAllocated();
4906   int nbOfTuple=getNumberOfTuples();
4907   int nbOfTuple2=other->getNumberOfTuples();
4908   int nbOfComp=getNumberOfComponents();
4909   int nbOfComp2=other->getNumberOfComponents();
4910   if(nbOfTuple==nbOfTuple2)
4911     {
4912       if(nbOfComp==nbOfComp2)
4913         {
4914           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4915         }
4916       else if(nbOfComp2==1)
4917         {
4918           double *ptr=getPointer();
4919           const double *ptrc=other->getConstPointer();
4920           for(int i=0;i<nbOfTuple;i++)
4921             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4922         }
4923       else
4924         throw INTERP_KERNEL::Exception(msg);
4925     }
4926   else if(nbOfTuple2==1)
4927     {
4928       if(nbOfComp2==nbOfComp)
4929         {
4930           double *ptr=getPointer();
4931           const double *ptrc=other->getConstPointer();
4932           for(int i=0;i<nbOfTuple;i++)
4933             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4934         }
4935       else
4936         throw INTERP_KERNEL::Exception(msg);
4937     }
4938   else
4939     throw INTERP_KERNEL::Exception(msg);
4940   declareAsNew();
4941 }
4942
4943 /*!
4944  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4945  * valid cases.
4946  * 1.  The arrays have same number of tuples and components. Then each value of
4947  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4948  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4949  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4950  *   component. Then
4951  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4952  * 3.  The arrays have same number of components and one array, say _a2_, has one
4953  *   tuple. Then
4954  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4955  *
4956  * Info on components is copied either from the first array (in the first case) or from
4957  * the array with maximal number of elements (getNbOfElems()).
4958  *  \param [in] a1 - an array to subtract from.
4959  *  \param [in] a2 - an array to subtract.
4960  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4961  *          The caller is to delete this result array using decrRef() as it is no more
4962  *          needed.
4963  *  \throw If either \a a1 or \a a2 is NULL.
4964  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4965  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4966  *         none of them has number of tuples or components equal to 1.
4967  */
4968 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
4969 {
4970   if(!a1 || !a2)
4971     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4972   int nbOfTuple1=a1->getNumberOfTuples();
4973   int nbOfTuple2=a2->getNumberOfTuples();
4974   int nbOfComp1=a1->getNumberOfComponents();
4975   int nbOfComp2=a2->getNumberOfComponents();
4976   if(nbOfTuple2==nbOfTuple1)
4977     {
4978       if(nbOfComp1==nbOfComp2)
4979         {
4980           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4981           ret->alloc(nbOfTuple2,nbOfComp1);
4982           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4983           ret->copyStringInfoFrom(*a1);
4984           return ret.retn();
4985         }
4986       else if(nbOfComp2==1)
4987         {
4988           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4989           ret->alloc(nbOfTuple1,nbOfComp1);
4990           const double *a2Ptr=a2->getConstPointer();
4991           const double *a1Ptr=a1->getConstPointer();
4992           double *res=ret->getPointer();
4993           for(int i=0;i<nbOfTuple1;i++)
4994             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4995           ret->copyStringInfoFrom(*a1);
4996           return ret.retn();
4997         }
4998       else
4999         {
5000           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5001           return 0;
5002         }
5003     }
5004   else if(nbOfTuple2==1)
5005     {
5006       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5007       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5008       ret->alloc(nbOfTuple1,nbOfComp1);
5009       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5010       double *pt=ret->getPointer();
5011       for(int i=0;i<nbOfTuple1;i++)
5012         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5013       ret->copyStringInfoFrom(*a1);
5014       return ret.retn();
5015     }
5016   else
5017     {
5018       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5019       return 0;
5020     }
5021 }
5022
5023 /*!
5024  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5025  * valid cases.
5026  * 1.  The arrays have same number of tuples and components. Then each value of
5027  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5028  *   _a_ [ i, j ] -= _other_ [ i, j ].
5029  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5030  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5031  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5032  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5033  *
5034  *  \param [in] other - an array to subtract from \a this one.
5035  *  \throw If \a other is NULL.
5036  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5037  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5038  *         \a other has number of both tuples and components not equal to 1.
5039  */
5040 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5041 {
5042   if(!other)
5043     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5044   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5045   checkAllocated();
5046   other->checkAllocated();
5047   int nbOfTuple=getNumberOfTuples();
5048   int nbOfTuple2=other->getNumberOfTuples();
5049   int nbOfComp=getNumberOfComponents();
5050   int nbOfComp2=other->getNumberOfComponents();
5051   if(nbOfTuple==nbOfTuple2)
5052     {
5053       if(nbOfComp==nbOfComp2)
5054         {
5055           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5056         }
5057       else if(nbOfComp2==1)
5058         {
5059           double *ptr=getPointer();
5060           const double *ptrc=other->getConstPointer();
5061           for(int i=0;i<nbOfTuple;i++)
5062             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5063         }
5064       else
5065         throw INTERP_KERNEL::Exception(msg);
5066     }
5067   else if(nbOfTuple2==1)
5068     {
5069       if(nbOfComp2==nbOfComp)
5070         {
5071           double *ptr=getPointer();
5072           const double *ptrc=other->getConstPointer();
5073           for(int i=0;i<nbOfTuple;i++)
5074             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5075         }
5076       else
5077         throw INTERP_KERNEL::Exception(msg);
5078     }
5079   else
5080     throw INTERP_KERNEL::Exception(msg);
5081   declareAsNew();
5082 }
5083
5084 /*!
5085  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5086  * valid cases.
5087  * 1.  The arrays have same number of tuples and components. Then each value of
5088  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5089  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5090  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5091  *   component. Then
5092  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5093  * 3.  The arrays have same number of components and one array, say _a2_, has one
5094  *   tuple. Then
5095  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5096  *
5097  * Info on components is copied either from the first array (in the first case) or from
5098  * the array with maximal number of elements (getNbOfElems()).
5099  *  \param [in] a1 - a factor array.
5100  *  \param [in] a2 - another factor array.
5101  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5102  *          The caller is to delete this result array using decrRef() as it is no more
5103  *          needed.
5104  *  \throw If either \a a1 or \a a2 is NULL.
5105  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5106  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5107  *         none of them has number of tuples or components equal to 1.
5108  */
5109 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5110 {
5111   if(!a1 || !a2)
5112     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5113   int nbOfTuple=a1->getNumberOfTuples();
5114   int nbOfTuple2=a2->getNumberOfTuples();
5115   int nbOfComp=a1->getNumberOfComponents();
5116   int nbOfComp2=a2->getNumberOfComponents();
5117   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5118   if(nbOfTuple==nbOfTuple2)
5119     {
5120       if(nbOfComp==nbOfComp2)
5121         {
5122           ret=DataArrayDouble::New();
5123           ret->alloc(nbOfTuple,nbOfComp);
5124           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5125           ret->copyStringInfoFrom(*a1);
5126         }
5127       else
5128         {
5129           int nbOfCompMin,nbOfCompMax;
5130           const DataArrayDouble *aMin, *aMax;
5131           if(nbOfComp>nbOfComp2)
5132             {
5133               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5134               aMin=a2; aMax=a1;
5135             }
5136           else
5137             {
5138               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5139               aMin=a1; aMax=a2;
5140             }
5141           if(nbOfCompMin==1)
5142             {
5143               ret=DataArrayDouble::New();
5144               ret->alloc(nbOfTuple,nbOfCompMax);
5145               const double *aMinPtr=aMin->getConstPointer();
5146               const double *aMaxPtr=aMax->getConstPointer();
5147               double *res=ret->getPointer();
5148               for(int i=0;i<nbOfTuple;i++)
5149                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5150               ret->copyStringInfoFrom(*aMax);
5151             }
5152           else
5153             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5154         }
5155     }
5156   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5157     {
5158       if(nbOfComp==nbOfComp2)
5159         {
5160           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5161           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5162           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5163           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5164           ret=DataArrayDouble::New();
5165           ret->alloc(nbOfTupleMax,nbOfComp);
5166           double *res=ret->getPointer();
5167           for(int i=0;i<nbOfTupleMax;i++)
5168             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5169           ret->copyStringInfoFrom(*aMax);
5170         }
5171       else
5172         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5173     }
5174   else
5175     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5176   return ret.retn();
5177 }
5178
5179 /*!
5180  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5181  * valid cases.
5182  * 1.  The arrays have same number of tuples and components. Then each value of
5183  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5184  *   _this_ [ i, j ] *= _other_ [ i, j ].
5185  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5186  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5187  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5188  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5189  *
5190  *  \param [in] other - an array to multiply to \a this one.
5191  *  \throw If \a other is NULL.
5192  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5193  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5194  *         \a other has number of both tuples and components not equal to 1.
5195  */
5196 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5197 {
5198   if(!other)
5199     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5200   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5201   checkAllocated();
5202   other->checkAllocated();
5203   int nbOfTuple=getNumberOfTuples();
5204   int nbOfTuple2=other->getNumberOfTuples();
5205   int nbOfComp=getNumberOfComponents();
5206   int nbOfComp2=other->getNumberOfComponents();
5207   if(nbOfTuple==nbOfTuple2)
5208     {
5209       if(nbOfComp==nbOfComp2)
5210         {
5211           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5212         }
5213       else if(nbOfComp2==1)
5214         {
5215           double *ptr=getPointer();
5216           const double *ptrc=other->getConstPointer();
5217           for(int i=0;i<nbOfTuple;i++)
5218             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5219         }
5220       else
5221         throw INTERP_KERNEL::Exception(msg);
5222     }
5223   else if(nbOfTuple2==1)
5224     {
5225       if(nbOfComp2==nbOfComp)
5226         {
5227           double *ptr=getPointer();
5228           const double *ptrc=other->getConstPointer();
5229           for(int i=0;i<nbOfTuple;i++)
5230             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5231         }
5232       else
5233         throw INTERP_KERNEL::Exception(msg);
5234     }
5235   else
5236     throw INTERP_KERNEL::Exception(msg);
5237   declareAsNew();
5238 }
5239
5240 /*!
5241  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5242  * valid cases.
5243  * 1.  The arrays have same number of tuples and components. Then each value of
5244  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5245  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5246  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5247  *   component. Then
5248  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5249  * 3.  The arrays have same number of components and one array, say _a2_, has one
5250  *   tuple. Then
5251  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5252  *
5253  * Info on components is copied either from the first array (in the first case) or from
5254  * the array with maximal number of elements (getNbOfElems()).
5255  *  \warning No check of division by zero is performed!
5256  *  \param [in] a1 - a numerator array.
5257  *  \param [in] a2 - a denominator array.
5258  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5259  *          The caller is to delete this result array using decrRef() as it is no more
5260  *          needed.
5261  *  \throw If either \a a1 or \a a2 is NULL.
5262  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5263  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5264  *         none of them has number of tuples or components equal to 1.
5265  */
5266 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5267 {
5268   if(!a1 || !a2)
5269     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5270   int nbOfTuple1=a1->getNumberOfTuples();
5271   int nbOfTuple2=a2->getNumberOfTuples();
5272   int nbOfComp1=a1->getNumberOfComponents();
5273   int nbOfComp2=a2->getNumberOfComponents();
5274   if(nbOfTuple2==nbOfTuple1)
5275     {
5276       if(nbOfComp1==nbOfComp2)
5277         {
5278           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5279           ret->alloc(nbOfTuple2,nbOfComp1);
5280           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5281           ret->copyStringInfoFrom(*a1);
5282           return ret.retn();
5283         }
5284       else if(nbOfComp2==1)
5285         {
5286           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5287           ret->alloc(nbOfTuple1,nbOfComp1);
5288           const double *a2Ptr=a2->getConstPointer();
5289           const double *a1Ptr=a1->getConstPointer();
5290           double *res=ret->getPointer();
5291           for(int i=0;i<nbOfTuple1;i++)
5292             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5293           ret->copyStringInfoFrom(*a1);
5294           return ret.retn();
5295         }
5296       else
5297         {
5298           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5299           return 0;
5300         }
5301     }
5302   else if(nbOfTuple2==1)
5303     {
5304       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5305       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5306       ret->alloc(nbOfTuple1,nbOfComp1);
5307       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5308       double *pt=ret->getPointer();
5309       for(int i=0;i<nbOfTuple1;i++)
5310         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5311       ret->copyStringInfoFrom(*a1);
5312       return ret.retn();
5313     }
5314   else
5315     {
5316       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5317       return 0;
5318     }
5319 }
5320
5321 /*!
5322  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5323  * valid cases.
5324  * 1.  The arrays have same number of tuples and components. Then each value of
5325  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5326  *   _a_ [ i, j ] /= _other_ [ i, j ].
5327  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5328  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5329  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5330  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5331  *
5332  *  \warning No check of division by zero is performed!
5333  *  \param [in] other - an array to divide \a this one by.
5334  *  \throw If \a other is NULL.
5335  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5336  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5337  *         \a other has number of both tuples and components not equal to 1.
5338  */
5339 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5340 {
5341   if(!other)
5342     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5343   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5344   checkAllocated();
5345   other->checkAllocated();
5346   int nbOfTuple=getNumberOfTuples();
5347   int nbOfTuple2=other->getNumberOfTuples();
5348   int nbOfComp=getNumberOfComponents();
5349   int nbOfComp2=other->getNumberOfComponents();
5350   if(nbOfTuple==nbOfTuple2)
5351     {
5352       if(nbOfComp==nbOfComp2)
5353         {
5354           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5355         }
5356       else if(nbOfComp2==1)
5357         {
5358           double *ptr=getPointer();
5359           const double *ptrc=other->getConstPointer();
5360           for(int i=0;i<nbOfTuple;i++)
5361             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5362         }
5363       else
5364         throw INTERP_KERNEL::Exception(msg);
5365     }
5366   else if(nbOfTuple2==1)
5367     {
5368       if(nbOfComp2==nbOfComp)
5369         {
5370           double *ptr=getPointer();
5371           const double *ptrc=other->getConstPointer();
5372           for(int i=0;i<nbOfTuple;i++)
5373             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5374         }
5375       else
5376         throw INTERP_KERNEL::Exception(msg);
5377     }
5378   else
5379     throw INTERP_KERNEL::Exception(msg);
5380   declareAsNew();
5381 }
5382
5383 /*!
5384  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5385  * valid cases.
5386  *
5387  *  \param [in] a1 - an array to pow up.
5388  *  \param [in] a2 - another array to sum up.
5389  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5390  *          The caller is to delete this result array using decrRef() as it is no more
5391  *          needed.
5392  *  \throw If either \a a1 or \a a2 is NULL.
5393  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5394  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5395  *  \throw If there is a negative value in \a a1.
5396  */
5397 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5398 {
5399   if(!a1 || !a2)
5400     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5401   int nbOfTuple=a1->getNumberOfTuples();
5402   int nbOfTuple2=a2->getNumberOfTuples();
5403   int nbOfComp=a1->getNumberOfComponents();
5404   int nbOfComp2=a2->getNumberOfComponents();
5405   if(nbOfTuple!=nbOfTuple2)
5406     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5407   if(nbOfComp!=1 || nbOfComp2!=1)
5408     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5409   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5410   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5411   double *ptr=ret->getPointer();
5412   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5413     {
5414       if(*ptr1>=0)
5415         {
5416           *ptr=pow(*ptr1,*ptr2);
5417         }
5418       else
5419         {
5420           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5421           throw INTERP_KERNEL::Exception(oss.str().c_str());
5422         }
5423     }
5424   return ret.retn();
5425 }
5426
5427 /*!
5428  * Apply pow on values of another DataArrayDouble to values of \a this one.
5429  *
5430  *  \param [in] other - an array to pow to \a this one.
5431  *  \throw If \a other is NULL.
5432  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5433  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5434  *  \throw If there is a negative value in \a this.
5435  */
5436 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5437 {
5438   if(!other)
5439     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5440   int nbOfTuple=getNumberOfTuples();
5441   int nbOfTuple2=other->getNumberOfTuples();
5442   int nbOfComp=getNumberOfComponents();
5443   int nbOfComp2=other->getNumberOfComponents();
5444   if(nbOfTuple!=nbOfTuple2)
5445     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5446   if(nbOfComp!=1 || nbOfComp2!=1)
5447     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5448   double *ptr=getPointer();
5449   const double *ptrc=other->begin();
5450   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5451     {
5452       if(*ptr>=0)
5453         *ptr=pow(*ptr,*ptrc);
5454       else
5455         {
5456           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5457           throw INTERP_KERNEL::Exception(oss.str().c_str());
5458         }
5459     }
5460   declareAsNew();
5461 }
5462
5463 /*!
5464  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5465  * Server side.
5466  */
5467 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5468 {
5469   tinyInfo.resize(2);
5470   if(isAllocated())
5471     {
5472       tinyInfo[0]=getNumberOfTuples();
5473       tinyInfo[1]=getNumberOfComponents();
5474     }
5475   else
5476     {
5477       tinyInfo[0]=-1;
5478       tinyInfo[1]=-1;
5479     }
5480 }
5481
5482 /*!
5483  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5484  * Server side.
5485  */
5486 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5487 {
5488   if(isAllocated())
5489     {
5490       int nbOfCompo=getNumberOfComponents();
5491       tinyInfo.resize(nbOfCompo+1);
5492       tinyInfo[0]=getName();
5493       for(int i=0;i<nbOfCompo;i++)
5494         tinyInfo[i+1]=getInfoOnComponent(i);
5495     }
5496   else
5497     {
5498       tinyInfo.resize(1);
5499       tinyInfo[0]=getName();
5500     }
5501 }
5502
5503 /*!
5504  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5505  * This method returns if a feeding is needed.
5506  */
5507 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5508 {
5509   int nbOfTuple=tinyInfoI[0];
5510   int nbOfComp=tinyInfoI[1];
5511   if(nbOfTuple!=-1 || nbOfComp!=-1)
5512     {
5513       alloc(nbOfTuple,nbOfComp);
5514       return true;
5515     }
5516   return false;
5517 }
5518
5519 /*!
5520  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5521  */
5522 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5523 {
5524   setName(tinyInfoS[0].c_str());
5525   if(isAllocated())
5526     {
5527       int nbOfCompo=getNumberOfComponents();
5528       for(int i=0;i<nbOfCompo;i++)
5529         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5530     }
5531 }
5532
5533 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5534 {
5535   if(_da)
5536     {
5537       _da->incrRef();
5538       if(_da->isAllocated())
5539         {
5540           _nb_comp=da->getNumberOfComponents();
5541           _nb_tuple=da->getNumberOfTuples();
5542           _pt=da->getPointer();
5543         }
5544     }
5545 }
5546
5547 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5548 {
5549   if(_da)
5550     _da->decrRef();
5551 }
5552
5553 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5554 {
5555   if(_tuple_id<_nb_tuple)
5556     {
5557       _tuple_id++;
5558       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5559       _pt+=_nb_comp;
5560       return ret;
5561     }
5562   else
5563     return 0;
5564 }
5565
5566 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5567 {
5568 }
5569
5570
5571 std::string DataArrayDoubleTuple::repr() const
5572 {
5573   std::ostringstream oss; oss.precision(17); oss << "(";
5574   for(int i=0;i<_nb_of_compo-1;i++)
5575     oss << _pt[i] << ", ";
5576   oss << _pt[_nb_of_compo-1] << ")";
5577   return oss.str();
5578 }
5579
5580 double DataArrayDoubleTuple::doubleValue() const
5581 {
5582   if(_nb_of_compo==1)
5583     return *_pt;
5584   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5585 }
5586
5587 /*!
5588  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5589  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5590  * 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
5591  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5592  */
5593 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5594 {
5595   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5596     {
5597       DataArrayDouble *ret=DataArrayDouble::New();
5598       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5599       return ret;
5600     }
5601   else
5602     {
5603       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5604       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5605       throw INTERP_KERNEL::Exception(oss.str().c_str());
5606     }
5607 }
5608
5609 /*!
5610  * Returns a new instance of DataArrayInt. The caller is to delete this array
5611  * using decrRef() as it is no more needed. 
5612  */
5613 DataArrayInt *DataArrayInt::New()
5614 {
5615   return new DataArrayInt;
5616 }
5617
5618 /*!
5619  * Checks if raw data is allocated. Read more on the raw data
5620  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5621  *  \return bool - \a true if the raw data is allocated, \a false else.
5622  */
5623 bool DataArrayInt::isAllocated() const
5624 {
5625   return getConstPointer()!=0;
5626 }
5627
5628 /*!
5629  * Checks if raw data is allocated and throws an exception if it is not the case.
5630  *  \throw If the raw data is not allocated.
5631  */
5632 void DataArrayInt::checkAllocated() const
5633 {
5634   if(!isAllocated())
5635     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5636 }
5637
5638 /*!
5639  * This method desallocated \a this without modification of informations relative to the components.
5640  * After call of this method, DataArrayInt::isAllocated will return false.
5641  * If \a this is already not allocated, \a this is let unchanged.
5642  */
5643 void DataArrayInt::desallocate()
5644 {
5645   _mem.destroy();
5646 }
5647
5648 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5649 {
5650   std::size_t sz(_mem.getNbOfElemAllocated());
5651   sz*=sizeof(int);
5652   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5653 }
5654
5655 /*!
5656  * Returns the only one value in \a this, if and only if number of elements
5657  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5658  *  \return double - the sole value stored in \a this array.
5659  *  \throw If at least one of conditions stated above is not fulfilled.
5660  */
5661 int DataArrayInt::intValue() const
5662 {
5663   if(isAllocated())
5664     {
5665       if(getNbOfElems()==1)
5666         {
5667           return *getConstPointer();
5668         }
5669       else
5670         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5671     }
5672   else
5673     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5674 }
5675
5676 /*!
5677  * Returns an integer value characterizing \a this array, which is useful for a quick
5678  * comparison of many instances of DataArrayInt.
5679  *  \return int - the hash value.
5680  *  \throw If \a this is not allocated.
5681  */
5682 int DataArrayInt::getHashCode() const
5683 {
5684   checkAllocated();
5685   std::size_t nbOfElems=getNbOfElems();
5686   int ret=nbOfElems*65536;
5687   int delta=3;
5688   if(nbOfElems>48)
5689     delta=nbOfElems/8;
5690   int ret0=0;
5691   const int *pt=begin();
5692   for(std::size_t i=0;i<nbOfElems;i+=delta)
5693     ret0+=pt[i] & 0x1FFF;
5694   return ret+ret0;
5695 }
5696
5697 /*!
5698  * Checks the number of tuples.
5699  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5700  *  \throw If \a this is not allocated.
5701  */
5702 bool DataArrayInt::empty() const
5703 {
5704   checkAllocated();
5705   return getNumberOfTuples()==0;
5706 }
5707
5708 /*!
5709  * Returns a full copy of \a this. For more info on copying data arrays see
5710  * \ref MEDCouplingArrayBasicsCopyDeep.
5711  *  \return DataArrayInt * - a new instance of DataArrayInt.
5712  */
5713 DataArrayInt *DataArrayInt::deepCpy() const
5714 {
5715   return new DataArrayInt(*this);
5716 }
5717
5718 /*!
5719  * Returns either a \a deep or \a shallow copy of this array. For more info see
5720  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5721  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5722  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5723  *          == \a true) or \a this instance (if \a dCpy == \a false).
5724  */
5725 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5726 {
5727   if(dCpy)
5728     return deepCpy();
5729   else
5730     {
5731       incrRef();
5732       return const_cast<DataArrayInt *>(this);
5733     }
5734 }
5735
5736 /*!
5737  * Copies all the data from another DataArrayInt. For more info see
5738  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5739  *  \param [in] other - another instance of DataArrayInt to copy data from.
5740  *  \throw If the \a other is not allocated.
5741  */
5742 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5743 {
5744   other.checkAllocated();
5745   int nbOfTuples=other.getNumberOfTuples();
5746   int nbOfComp=other.getNumberOfComponents();
5747   allocIfNecessary(nbOfTuples,nbOfComp);
5748   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5749   int *pt=getPointer();
5750   const int *ptI=other.getConstPointer();
5751   for(std::size_t i=0;i<nbOfElems;i++)
5752     pt[i]=ptI[i];
5753   copyStringInfoFrom(other);
5754 }
5755
5756 /*!
5757  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5758  * 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.
5759  * If \a this has not already been allocated, number of components is set to one.
5760  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5761  * 
5762  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5763  */
5764 void DataArrayInt::reserve(std::size_t nbOfElems)
5765 {
5766   int nbCompo=getNumberOfComponents();
5767   if(nbCompo==1)
5768     {
5769       _mem.reserve(nbOfElems);
5770     }
5771   else if(nbCompo==0)
5772     {
5773       _mem.reserve(nbOfElems);
5774       _info_on_compo.resize(1);
5775     }
5776   else
5777     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5778 }
5779
5780 /*!
5781  * 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
5782  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5783  *
5784  * \param [in] val the value to be added in \a this
5785  * \throw If \a this has already been allocated with number of components different from one.
5786  * \sa DataArrayInt::pushBackValsSilent
5787  */
5788 void DataArrayInt::pushBackSilent(int val)
5789 {
5790   int nbCompo=getNumberOfComponents();
5791   if(nbCompo==1)
5792     _mem.pushBack(val);
5793   else if(nbCompo==0)
5794     {
5795       _info_on_compo.resize(1);
5796       _mem.pushBack(val);
5797     }
5798   else
5799     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5800 }
5801
5802 /*!
5803  * 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
5804  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5805  *
5806  *  \param [in] valsBg - an array of values to push at the end of \this.
5807  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5808  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5809  * \throw If \a this has already been allocated with number of components different from one.
5810  * \sa DataArrayInt::pushBackSilent
5811  */
5812 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5813 {
5814   int nbCompo=getNumberOfComponents();
5815   if(nbCompo==1)
5816     _mem.insertAtTheEnd(valsBg,valsEnd);
5817   else if(nbCompo==0)
5818     {
5819       _info_on_compo.resize(1);
5820       _mem.insertAtTheEnd(valsBg,valsEnd);
5821     }
5822   else
5823     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5824 }
5825
5826 /*!
5827  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5828  * \throw If \a this is already empty.
5829  * \throw If \a this has number of components different from one.
5830  */
5831 int DataArrayInt::popBackSilent()
5832 {
5833   if(getNumberOfComponents()==1)
5834     return _mem.popBack();
5835   else
5836     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5837 }
5838
5839 /*!
5840  * 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.
5841  *
5842  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5843  */
5844 void DataArrayInt::pack() const
5845 {
5846   _mem.pack();
5847 }
5848
5849 /*!
5850  * Allocates the raw data in memory. If exactly as same memory as needed already
5851  * allocated, it is not re-allocated.
5852  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5853  *  \param [in] nbOfCompo - number of components of data to allocate.
5854  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5855  */
5856 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5857 {
5858   if(isAllocated())
5859     {
5860       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5861         alloc(nbOfTuple,nbOfCompo);
5862     }
5863   else
5864     alloc(nbOfTuple,nbOfCompo);
5865 }
5866
5867 /*!
5868  * Allocates the raw data in memory. If the memory was already allocated, then it is
5869  * freed and re-allocated. See an example of this method use
5870  * \ref MEDCouplingArraySteps1WC "here".
5871  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5872  *  \param [in] nbOfCompo - number of components of data to allocate.
5873  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5874  */
5875 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
5876 {
5877   if(nbOfTuple<0 || nbOfCompo<0)
5878     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5879   _info_on_compo.resize(nbOfCompo);
5880   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5881   declareAsNew();
5882 }
5883
5884 /*!
5885  * Assign zero to all values in \a this array. To know more on filling arrays see
5886  * \ref MEDCouplingArrayFill.
5887  * \throw If \a this is not allocated.
5888  */
5889 void DataArrayInt::fillWithZero()
5890 {
5891   checkAllocated();
5892   _mem.fillWithValue(0);
5893   declareAsNew();
5894 }
5895
5896 /*!
5897  * Assign \a val to all values in \a this array. To know more on filling arrays see
5898  * \ref MEDCouplingArrayFill.
5899  *  \param [in] val - the value to fill with.
5900  *  \throw If \a this is not allocated.
5901  */
5902 void DataArrayInt::fillWithValue(int val)
5903 {
5904   checkAllocated();
5905   _mem.fillWithValue(val);
5906   declareAsNew();
5907 }
5908
5909 /*!
5910  * Set all values in \a this array so that the i-th element equals to \a init + i
5911  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5912  *  \param [in] init - value to assign to the first element of array.
5913  *  \throw If \a this->getNumberOfComponents() != 1
5914  *  \throw If \a this is not allocated.
5915  */
5916 void DataArrayInt::iota(int init)
5917 {
5918   checkAllocated();
5919   if(getNumberOfComponents()!=1)
5920     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5921   int *ptr=getPointer();
5922   int ntuples=getNumberOfTuples();
5923   for(int i=0;i<ntuples;i++)
5924     ptr[i]=init+i;
5925   declareAsNew();
5926 }
5927
5928 /*!
5929  * Returns a textual and human readable representation of \a this instance of
5930  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5931  *  \return std::string - text describing \a this DataArrayInt.
5932  */
5933 std::string DataArrayInt::repr() const
5934 {
5935   std::ostringstream ret;
5936   reprStream(ret);
5937   return ret.str();
5938 }
5939
5940 std::string DataArrayInt::reprZip() const
5941 {
5942   std::ostringstream ret;
5943   reprZipStream(ret);
5944   return ret.str();
5945 }
5946
5947 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
5948 {
5949   static const char SPACE[4]={' ',' ',' ',' '};
5950   checkAllocated();
5951   std::string idt(indent,' ');
5952   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5953   if(byteArr)
5954     {
5955       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5956       if(std::string(type)=="Int32")
5957         {
5958           const char *data(reinterpret_cast<const char *>(begin()));
5959           std::size_t sz(getNbOfElems()*sizeof(int));
5960           byteArr->insertAtTheEnd(data,data+sz);
5961           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5962         }
5963       else if(std::string(type)=="Int8")
5964         {
5965           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5966           std::copy(begin(),end(),(char *)tmp);
5967           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5968           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5969         }
5970       else if(std::string(type)=="UInt8")
5971         {
5972           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
5973           std::copy(begin(),end(),(unsigned char *)tmp);
5974           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
5975           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5976         }
5977       else
5978         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
5979     }
5980   else
5981     {
5982       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
5983       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5984     }
5985   ofs << std::endl << idt << "</DataArray>\n";
5986 }
5987
5988 void DataArrayInt::reprStream(std::ostream& stream) const
5989 {
5990   stream << "Name of int array : \"" << _name << "\"\n";
5991   reprWithoutNameStream(stream);
5992 }
5993
5994 void DataArrayInt::reprZipStream(std::ostream& stream) const
5995 {
5996   stream << "Name of int array : \"" << _name << "\"\n";
5997   reprZipWithoutNameStream(stream);
5998 }
5999
6000 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6001 {
6002   DataArray::reprWithoutNameStream(stream);
6003   _mem.repr(getNumberOfComponents(),stream);
6004 }
6005
6006 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6007 {
6008   DataArray::reprWithoutNameStream(stream);
6009   _mem.reprZip(getNumberOfComponents(),stream);
6010 }
6011
6012 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
6013 {
6014   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6015   const int *data=getConstPointer();
6016   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6017   if(nbTuples*nbComp>=1)
6018     {
6019       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6020       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6021       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6022       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6023     }
6024   else
6025     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6026   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6027 }
6028
6029 /*!
6030  * Method that gives a quick overvien of \a this for python.
6031  */
6032 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6033 {
6034   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6035   stream << "DataArrayInt C++ instance at " << this << ". ";
6036   if(isAllocated())
6037     {
6038       int nbOfCompo=(int)_info_on_compo.size();
6039       if(nbOfCompo>=1)
6040         {
6041           int nbOfTuples=getNumberOfTuples();
6042           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6043           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6044         }
6045       else
6046         stream << "Number of components : 0.";
6047     }
6048   else
6049     stream << "*** No data allocated ****";
6050 }
6051
6052 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6053 {
6054   const int *data=begin();
6055   int nbOfTuples=getNumberOfTuples();
6056   int nbOfCompo=(int)_info_on_compo.size();
6057   std::ostringstream oss2; oss2 << "[";
6058   std::string oss2Str(oss2.str());
6059   bool isFinished=true;
6060   for(int i=0;i<nbOfTuples && isFinished;i++)
6061     {
6062       if(nbOfCompo>1)
6063         {
6064           oss2 << "(";
6065           for(int j=0;j<nbOfCompo;j++,data++)
6066             {
6067               oss2 << *data;
6068               if(j!=nbOfCompo-1) oss2 << ", ";
6069             }
6070           oss2 << ")";
6071         }
6072       else
6073         oss2 << *data++;
6074       if(i!=nbOfTuples-1) oss2 << ", ";
6075       std::string oss3Str(oss2.str());
6076       if(oss3Str.length()<maxNbOfByteInRepr)
6077         oss2Str=oss3Str;
6078       else
6079         isFinished=false;
6080     }
6081   stream << oss2Str;
6082   if(!isFinished)
6083     stream << "... ";
6084   stream << "]";
6085 }
6086
6087 /*!
6088  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6089  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6090  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6091  *         to \a this array.
6092  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6093  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6094  *  \throw If \a this->getNumberOfComponents() != 1
6095  *  \throw If any value of \a this can't be used as a valid index for 
6096  *         [\a indArrBg, \a indArrEnd).
6097  */
6098 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6099 {
6100   checkAllocated();
6101   if(getNumberOfComponents()!=1)
6102     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6103   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6104   int nbOfTuples=getNumberOfTuples();
6105   int *pt=getPointer();
6106   for(int i=0;i<nbOfTuples;i++,pt++)
6107     {
6108       if(*pt>=0 && *pt<nbElemsIn)
6109         *pt=indArrBg[*pt];
6110       else
6111         {
6112           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6113           throw INTERP_KERNEL::Exception(oss.str().c_str());
6114         }
6115     }
6116   declareAsNew();
6117 }
6118
6119 /*!
6120  * Computes distribution of values of \a this one-dimensional array between given value
6121  * ranges (casts). This method is typically useful for entity number spliting by types,
6122  * for example. 
6123  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6124  *           check of this is be done. If not, the result is not warranted. 
6125  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6126  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6127  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6128  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6129  *         should be more than every value in \a this array.
6130  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6131  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6132  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6133  *         (same number of tuples and components), the caller is to delete 
6134  *         using decrRef() as it is no more needed.
6135  *         This array contains indices of ranges for every value of \a this array. I.e.
6136  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6137  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6138  *         this in which cast it holds.
6139  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6140  *         array, the caller is to delete using decrRef() as it is no more needed.
6141  *         This array contains ranks of values of \a this array within ranges
6142  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6143  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6144  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6145  *         for each tuple its rank inside its cast. The rank is computed as difference
6146  *         between the value and the lowest value of range.
6147  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6148  *         ranges (casts) to which at least one value of \a this array belongs.
6149  *         Or, in other words, this param contains the casts that \a this contains.
6150  *         The caller is to delete this array using decrRef() as it is no more needed.
6151  *
6152  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6153  *            the output of this method will be : 
6154  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6155  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6156  * - \a castsPresent  : [0,1]
6157  *
6158  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6159  * range #1 and its rank within this range is 2; etc.
6160  *
6161  *  \throw If \a this->getNumberOfComponents() != 1.
6162  *  \throw If \a arrEnd - arrBg < 2.
6163  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6164  */
6165 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6166                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6167 {
6168   checkAllocated();
6169   if(getNumberOfComponents()!=1)
6170     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6171   int nbOfTuples=getNumberOfTuples();
6172   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6173   if(nbOfCast<2)
6174     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6175   nbOfCast--;
6176   const int *work=getConstPointer();
6177   typedef std::reverse_iterator<const int *> rintstart;
6178   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6179   rintstart end2(arrBg);
6180   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6181   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6182   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6183   ret1->alloc(nbOfTuples,1);
6184   ret2->alloc(nbOfTuples,1);
6185   int *ret1Ptr=ret1->getPointer();
6186   int *ret2Ptr=ret2->getPointer();
6187   std::set<std::size_t> castsDetected;
6188   for(int i=0;i<nbOfTuples;i++)
6189     {
6190       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6191       std::size_t pos=std::distance(bg,res);
6192       std::size_t pos2=nbOfCast-pos;
6193       if(pos2<nbOfCast)
6194         {
6195           ret1Ptr[i]=(int)pos2;
6196           ret2Ptr[i]=work[i]-arrBg[pos2];
6197           castsDetected.insert(pos2);
6198         }
6199       else
6200         {
6201           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6202           throw INTERP_KERNEL::Exception(oss.str().c_str());
6203         }
6204     }
6205   ret3->alloc((int)castsDetected.size(),1);
6206   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6207   castArr=ret1.retn();
6208   rankInsideCast=ret2.retn();
6209   castsPresent=ret3.retn();
6210 }
6211
6212 /*!
6213  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6214  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6215  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6216  * new value in place \a indArr[ \a v ] is i.
6217  *  \param [in] indArrBg - the array holding indices within the result array to assign
6218  *         indices of values of \a this array pointing to values of \a indArrBg.
6219  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6220  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6221  *  \return DataArrayInt * - the new instance of DataArrayInt.
6222  *          The caller is to delete this result array using decrRef() as it is no more
6223  *          needed.
6224  *  \throw If \a this->getNumberOfComponents() != 1.
6225  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6226  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6227  */
6228 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6229 {
6230   checkAllocated();
6231   if(getNumberOfComponents()!=1)
6232     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6233   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6234   int nbOfTuples=getNumberOfTuples();
6235   const int *pt=getConstPointer();
6236   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6237   ret->alloc(nbOfTuples,1);
6238   ret->fillWithValue(-1);
6239   int *tmp=ret->getPointer();
6240   for(int i=0;i<nbOfTuples;i++,pt++)
6241     {
6242       if(*pt>=0 && *pt<nbElemsIn)
6243         {
6244           int pos=indArrBg[*pt];
6245           if(pos>=0 && pos<nbOfTuples)
6246             tmp[pos]=i;
6247           else
6248             {
6249               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6250               throw INTERP_KERNEL::Exception(oss.str().c_str());
6251             }
6252         }
6253       else
6254         {
6255           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6256           throw INTERP_KERNEL::Exception(oss.str().c_str());
6257         }
6258     }
6259   return ret.retn();
6260 }
6261
6262 /*!
6263  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6264  * from values of \a this array, which is supposed to contain a renumbering map in 
6265  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6266  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6267  *  \param [in] newNbOfElem - the number of tuples in the result array.
6268  *  \return DataArrayInt * - the new instance of DataArrayInt.
6269  *          The caller is to delete this result array using decrRef() as it is no more
6270  *          needed.
6271  * 
6272  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6273  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6274  */
6275 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6276 {
6277   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6278   ret->alloc(newNbOfElem,1);
6279   int nbOfOldNodes=getNumberOfTuples();
6280   const int *old2New=getConstPointer();
6281   int *pt=ret->getPointer();
6282   for(int i=0;i!=nbOfOldNodes;i++)
6283     {
6284       int newp(old2New[i]);
6285       if(newp!=-1)
6286         {
6287           if(newp>=0 && newp<newNbOfElem)
6288             pt[newp]=i;
6289           else
6290             {
6291               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6292               throw INTERP_KERNEL::Exception(oss.str().c_str());
6293             }
6294         }
6295     }
6296   return ret.retn();
6297 }
6298
6299 /*!
6300  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6301  * 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]
6302  */
6303 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6304 {
6305   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6306   ret->alloc(newNbOfElem,1);
6307   int nbOfOldNodes=getNumberOfTuples();
6308   const int *old2New=getConstPointer();
6309   int *pt=ret->getPointer();
6310   for(int i=nbOfOldNodes-1;i>=0;i--)
6311     {
6312       int newp(old2New[i]);
6313       if(newp!=-1)
6314         {
6315           if(newp>=0 && newp<newNbOfElem)
6316             pt[newp]=i;
6317           else
6318             {
6319               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6320               throw INTERP_KERNEL::Exception(oss.str().c_str());
6321             }
6322         }
6323     }
6324   return ret.retn();
6325 }
6326
6327 /*!
6328  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6329  * from values of \a this array, which is supposed to contain a renumbering map in 
6330  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6331  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6332  *  \param [in] newNbOfElem - the number of tuples in the result array.
6333  *  \return DataArrayInt * - the new instance of DataArrayInt.
6334  *          The caller is to delete this result array using decrRef() as it is no more
6335  *          needed.
6336  * 
6337  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6338  *
6339  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6340  */
6341 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6342 {
6343   checkAllocated();
6344   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6345   ret->alloc(oldNbOfElem,1);
6346   const int *new2Old=getConstPointer();
6347   int *pt=ret->getPointer();
6348   std::fill(pt,pt+oldNbOfElem,-1);
6349   int nbOfNewElems=getNumberOfTuples();
6350   for(int i=0;i<nbOfNewElems;i++)
6351     {
6352       int v(new2Old[i]);
6353       if(v>=0 && v<oldNbOfElem)
6354          pt[v]=i;
6355       else
6356         {
6357           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6358           throw INTERP_KERNEL::Exception(oss.str().c_str());
6359         }
6360     }
6361   return ret.retn();
6362 }
6363
6364 /*!
6365  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6366  * mismatch is given.
6367  * 
6368  * \param [in] other the instance to be compared with \a this
6369  * \param [out] reason In case of inequality returns the reason.
6370  * \sa DataArrayInt::isEqual
6371  */
6372 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6373 {
6374   if(!areInfoEqualsIfNotWhy(other,reason))
6375     return false;
6376   return _mem.isEqual(other._mem,0,reason);
6377 }
6378
6379 /*!
6380  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6381  * \ref MEDCouplingArrayBasicsCompare.
6382  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6383  *  \return bool - \a true if the two arrays are equal, \a false else.
6384  */
6385 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6386 {
6387   std::string tmp;
6388   return isEqualIfNotWhy(other,tmp);
6389 }
6390
6391 /*!
6392  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6393  * \ref MEDCouplingArrayBasicsCompare.
6394  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6395  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6396  */
6397 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6398 {
6399   std::string tmp;
6400   return _mem.isEqual(other._mem,0,tmp);
6401 }
6402
6403 /*!
6404  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6405  * performed on sorted value sequences.
6406  * For more info see\ref MEDCouplingArrayBasicsCompare.
6407  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6408  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6409  */
6410 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6411 {
6412   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6413   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6414   a->sort();
6415   b->sort();
6416   return a->isEqualWithoutConsideringStr(*b);
6417 }
6418
6419 /*!
6420  * This method compares content of input vector \a v and \a this.
6421  * 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.
6422  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6423  *
6424  * \param [in] v - the vector of 'flags' to be compared with \a this.
6425  *
6426  * \throw If \a this is not sorted ascendingly.
6427  * \throw If \a this has not exactly one component.
6428  * \throw If \a this is not allocated.
6429  */
6430 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6431 {
6432   checkAllocated();
6433   if(getNumberOfComponents()!=1)
6434     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6435   int nbOfTuples(getNumberOfTuples());
6436   const int *w(begin()),*end2(end());
6437   int refVal=-std::numeric_limits<int>::max();
6438   int i=0;
6439   std::vector<bool>::const_iterator it(v.begin());
6440   for(;it!=v.end();it++,i++)
6441     {
6442       if(*it)
6443         {
6444           if(w!=end2)
6445             {
6446               if(*w++==i)
6447                 {
6448                   if(i>refVal)
6449                     refVal=i;
6450                   else
6451                     {
6452                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6453                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6454                     }
6455                 }
6456               else
6457                 return false;
6458             }
6459           else
6460             return false;
6461         }
6462     }
6463   return w==end2;
6464 }
6465
6466 /*!
6467  * Sorts values of the array.
6468  *  \param [in] asc - \a true means ascending order, \a false, descending.
6469  *  \throw If \a this is not allocated.
6470  *  \throw If \a this->getNumberOfComponents() != 1.
6471  */
6472 void DataArrayInt::sort(bool asc)
6473 {
6474   checkAllocated();
6475   if(getNumberOfComponents()!=1)
6476     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6477   _mem.sort(asc);
6478   declareAsNew();
6479 }
6480
6481 /*!
6482  * Computes for each tuple the sum of number of components values in the tuple and return it.
6483  * 
6484  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6485  *          same number of tuples as \a this array and one component.
6486  *          The caller is to delete this result array using decrRef() as it is no more
6487  *          needed.
6488  *  \throw If \a this is not allocated.
6489  */
6490 DataArrayInt *DataArrayInt::sumPerTuple() const
6491 {
6492   checkAllocated();
6493   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6494   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6495   ret->alloc(nbOfTuple,1);
6496   const int *src(getConstPointer());
6497   int *dest(ret->getPointer());
6498   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6499     *dest=std::accumulate(src,src+nbOfComp,0);
6500   return ret.retn();
6501 }
6502
6503 /*!
6504  * Reverse the array values.
6505  *  \throw If \a this->getNumberOfComponents() < 1.
6506  *  \throw If \a this is not allocated.
6507  */
6508 void DataArrayInt::reverse()
6509 {
6510   checkAllocated();
6511   _mem.reverse(getNumberOfComponents());
6512   declareAsNew();
6513 }
6514
6515 /*!
6516  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6517  * If not an exception is thrown.
6518  *  \param [in] increasing - if \a true, the array values should be increasing.
6519  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6520  *         increasing arg.
6521  *  \throw If \a this->getNumberOfComponents() != 1.
6522  *  \throw If \a this is not allocated.
6523  */
6524 void DataArrayInt::checkMonotonic(bool increasing) const
6525 {
6526   if(!isMonotonic(increasing))
6527     {
6528       if (increasing)
6529         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6530       else
6531         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6532     }
6533 }
6534
6535 /*!
6536  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6537  *  \param [in] increasing - if \a true, array values should be increasing.
6538  *  \return bool - \a true if values change in accordance with \a increasing arg.
6539  *  \throw If \a this->getNumberOfComponents() != 1.
6540  *  \throw If \a this is not allocated.
6541  */
6542 bool DataArrayInt::isMonotonic(bool increasing) const
6543 {
6544   checkAllocated();
6545   if(getNumberOfComponents()!=1)
6546     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6547   int nbOfElements=getNumberOfTuples();
6548   const int *ptr=getConstPointer();
6549   if(nbOfElements==0)
6550     return true;
6551   int ref=ptr[0];
6552   if(increasing)
6553     {
6554       for(int i=1;i<nbOfElements;i++)
6555         {
6556           if(ptr[i]>=ref)
6557             ref=ptr[i];
6558           else
6559             return false;
6560         }
6561     }
6562   else
6563     {
6564       for(int i=1;i<nbOfElements;i++)
6565         {
6566           if(ptr[i]<=ref)
6567             ref=ptr[i];
6568           else
6569             return false;
6570         }
6571     }
6572   return true;
6573 }
6574
6575 /*!
6576  * This method check that array consistently INCREASING or DECREASING in value.
6577  */
6578 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6579 {
6580   checkAllocated();
6581   if(getNumberOfComponents()!=1)
6582     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6583   int nbOfElements=getNumberOfTuples();
6584   const int *ptr=getConstPointer();
6585   if(nbOfElements==0)
6586     return true;
6587   int ref=ptr[0];
6588   if(increasing)
6589     {
6590       for(int i=1;i<nbOfElements;i++)
6591         {
6592           if(ptr[i]>ref)
6593             ref=ptr[i];
6594           else
6595             return false;
6596         }
6597     }
6598   else
6599     {
6600       for(int i=1;i<nbOfElements;i++)
6601         {
6602           if(ptr[i]<ref)
6603             ref=ptr[i];
6604           else
6605             return false;
6606         }
6607     }
6608   return true;
6609 }
6610
6611 /*!
6612  * This method check that array consistently INCREASING or DECREASING in value.
6613  */
6614 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6615 {
6616   if(!isStrictlyMonotonic(increasing))
6617     {
6618       if (increasing)
6619         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6620       else
6621         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6622     }
6623 }
6624
6625 /*!
6626  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6627  * one-dimensional arrays that must be of the same length. The result array describes
6628  * correspondence between \a this and \a other arrays, so that 
6629  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6630  * not possible because some element in \a other is not in \a this, an exception is thrown.
6631  *  \param [in] other - an array to compute permutation to.
6632  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6633  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6634  * no more needed.
6635  *  \throw If \a this->getNumberOfComponents() != 1.
6636  *  \throw If \a other->getNumberOfComponents() != 1.
6637  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6638  *  \throw If \a other includes a value which is not in \a this array.
6639  * 
6640  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6641  *
6642  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6643  */
6644 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6645 {
6646   checkAllocated();
6647   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6648     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6649   int nbTuple=getNumberOfTuples();
6650   other.checkAllocated();
6651   if(nbTuple!=other.getNumberOfTuples())
6652     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6653   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6654   ret->alloc(nbTuple,1);
6655   ret->fillWithValue(-1);
6656   const int *pt=getConstPointer();
6657   std::map<int,int> mm;
6658   for(int i=0;i<nbTuple;i++)
6659     mm[pt[i]]=i;
6660   pt=other.getConstPointer();
6661   int *retToFill=ret->getPointer();
6662   for(int i=0;i<nbTuple;i++)
6663     {
6664       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6665       if(it==mm.end())
6666         {
6667           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6668           throw INTERP_KERNEL::Exception(oss.str().c_str());
6669         }
6670       retToFill[i]=(*it).second;
6671     }
6672   return ret.retn();
6673 }
6674
6675 /*!
6676  * Sets a C array to be used as raw data of \a this. The previously set info
6677  *  of components is retained and re-sized. 
6678  * For more info see \ref MEDCouplingArraySteps1.
6679  *  \param [in] array - the C array to be used as raw data of \a this.
6680  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6681  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6682  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6683  *                     \c free(\c array ) will be called.
6684  *  \param [in] nbOfTuple - new number of tuples in \a this.
6685  *  \param [in] nbOfCompo - new number of components in \a this.
6686  */
6687 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6688 {
6689   _info_on_compo.resize(nbOfCompo);
6690   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6691   declareAsNew();
6692 }
6693
6694 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6695 {
6696   _info_on_compo.resize(nbOfCompo);
6697   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6698   declareAsNew();
6699 }
6700
6701 /*!
6702  * Returns a new DataArrayInt holding the same values as \a this array but differently
6703  * arranged in memory. If \a this array holds 2 components of 3 values:
6704  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6705  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6706  *  \warning Do not confuse this method with transpose()!
6707  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6708  *          is to delete using decrRef() as it is no more needed.
6709  *  \throw If \a this is not allocated.
6710  */
6711 DataArrayInt *DataArrayInt::fromNoInterlace() const
6712 {
6713   checkAllocated();
6714   if(_mem.isNull())
6715     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6716   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6717   DataArrayInt *ret=DataArrayInt::New();
6718   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6719   return ret;
6720 }
6721
6722 /*!
6723  * Returns a new DataArrayInt holding the same values as \a this array but differently
6724  * arranged in memory. If \a this array holds 2 components of 3 values:
6725  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6726  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6727  *  \warning Do not confuse this method with transpose()!
6728  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6729  *          is to delete using decrRef() as it is no more needed.
6730  *  \throw If \a this is not allocated.
6731  */
6732 DataArrayInt *DataArrayInt::toNoInterlace() const
6733 {
6734   checkAllocated();
6735   if(_mem.isNull())
6736     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6737   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6738   DataArrayInt *ret=DataArrayInt::New();
6739   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6740   return ret;
6741 }
6742
6743 /*!
6744  * Permutes values of \a this array as required by \a old2New array. The values are
6745  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6746  * the same as in \this one.
6747  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6748  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6749  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6750  *     giving a new position for i-th old value.
6751  */
6752 void DataArrayInt::renumberInPlace(const int *old2New)
6753 {
6754   checkAllocated();
6755   int nbTuples=getNumberOfTuples();
6756   int nbOfCompo=getNumberOfComponents();
6757   int *tmp=new int[nbTuples*nbOfCompo];
6758   const int *iptr=getConstPointer();
6759   for(int i=0;i<nbTuples;i++)
6760     {
6761       int v=old2New[i];
6762       if(v>=0 && v<nbTuples)
6763         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6764       else
6765         {
6766           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6767           throw INTERP_KERNEL::Exception(oss.str().c_str());
6768         }
6769     }
6770   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6771   delete [] tmp;
6772   declareAsNew();
6773 }
6774
6775 /*!
6776  * Permutes values of \a this array as required by \a new2Old array. The values are
6777  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6778  * the same as in \this one.
6779  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6780  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6781  *     giving a previous position of i-th new value.
6782  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6783  *          is to delete using decrRef() as it is no more needed.
6784  */
6785 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6786 {
6787   checkAllocated();
6788   int nbTuples=getNumberOfTuples();
6789   int nbOfCompo=getNumberOfComponents();
6790   int *tmp=new int[nbTuples*nbOfCompo];
6791   const int *iptr=getConstPointer();
6792   for(int i=0;i<nbTuples;i++)
6793     {
6794       int v=new2Old[i];
6795       if(v>=0 && v<nbTuples)
6796         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6797       else
6798         {
6799           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6800           throw INTERP_KERNEL::Exception(oss.str().c_str());
6801         }
6802     }
6803   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6804   delete [] tmp;
6805   declareAsNew();
6806 }
6807
6808 /*!
6809  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6810  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6811  * Number of tuples in the result array remains the same as in \this one.
6812  * If a permutation reduction is needed, renumberAndReduce() should be used.
6813  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6814  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6815  *          giving a new position for i-th old value.
6816  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6817  *          is to delete using decrRef() as it is no more needed.
6818  *  \throw If \a this is not allocated.
6819  */
6820 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6821 {
6822   checkAllocated();
6823   int nbTuples=getNumberOfTuples();
6824   int nbOfCompo=getNumberOfComponents();
6825   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6826   ret->alloc(nbTuples,nbOfCompo);
6827   ret->copyStringInfoFrom(*this);
6828   const int *iptr=getConstPointer();
6829   int *optr=ret->getPointer();
6830   for(int i=0;i<nbTuples;i++)
6831     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6832   ret->copyStringInfoFrom(*this);
6833   return ret.retn();
6834 }
6835
6836 /*!
6837  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6838  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6839  * tuples in the result array remains the same as in \this one.
6840  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6841  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6842  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6843  *     giving a previous position of i-th new value.
6844  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6845  *          is to delete using decrRef() as it is no more needed.
6846  */
6847 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6848 {
6849   checkAllocated();
6850   int nbTuples=getNumberOfTuples();
6851   int nbOfCompo=getNumberOfComponents();
6852   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6853   ret->alloc(nbTuples,nbOfCompo);
6854   ret->copyStringInfoFrom(*this);
6855   const int *iptr=getConstPointer();
6856   int *optr=ret->getPointer();
6857   for(int i=0;i<nbTuples;i++)
6858     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6859   ret->copyStringInfoFrom(*this);
6860   return ret.retn();
6861 }
6862
6863 /*!
6864  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6865  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6866  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6867  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6868  * \a old2New[ i ] is negative, is missing from the result array.
6869  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6870  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6871  *     giving a new position for i-th old tuple and giving negative position for
6872  *     for i-th old tuple that should be omitted.
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::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6877 {
6878   checkAllocated();
6879   int nbTuples=getNumberOfTuples();
6880   int nbOfCompo=getNumberOfComponents();
6881   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6882   ret->alloc(newNbOfTuple,nbOfCompo);
6883   const int *iptr=getConstPointer();
6884   int *optr=ret->getPointer();
6885   for(int i=0;i<nbTuples;i++)
6886     {
6887       int w=old2New[i];
6888       if(w>=0)
6889         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6890     }
6891   ret->copyStringInfoFrom(*this);
6892   return ret.retn();
6893 }
6894
6895 /*!
6896  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6897  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6898  * \a new2OldBg array.
6899  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6900  * This method is equivalent to renumberAndReduce() except that convention in input is
6901  * \c new2old and \b not \c old2new.
6902  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6903  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6904  *              tuple index in \a this array to fill the i-th tuple in the new array.
6905  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6906  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6907  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6908  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6909  *          is to delete using decrRef() as it is no more needed.
6910  */
6911 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6912 {
6913   checkAllocated();
6914   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6915   int nbComp=getNumberOfComponents();
6916   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6917   ret->copyStringInfoFrom(*this);
6918   int *pt=ret->getPointer();
6919   const int *srcPt=getConstPointer();
6920   int i=0;
6921   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6922     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6923   ret->copyStringInfoFrom(*this);
6924   return ret.retn();
6925 }
6926
6927 /*!
6928  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6929  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6930  * \a new2OldBg array.
6931  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6932  * This method is equivalent to renumberAndReduce() except that convention in input is
6933  * \c new2old and \b not \c old2new.
6934  * This method is equivalent to selectByTupleId() except that it prevents coping data
6935  * from behind the end of \a this array.
6936  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6937  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6938  *              tuple index in \a this array to fill the i-th tuple in the new array.
6939  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6940  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6941  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6942  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6943  *          is to delete using decrRef() as it is no more needed.
6944  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6945  */
6946 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
6947 {
6948   checkAllocated();
6949   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6950   int nbComp=getNumberOfComponents();
6951   int oldNbOfTuples=getNumberOfTuples();
6952   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6953   ret->copyStringInfoFrom(*this);
6954   int *pt=ret->getPointer();
6955   const int *srcPt=getConstPointer();
6956   int i=0;
6957   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6958     if(*w>=0 && *w<oldNbOfTuples)
6959       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6960     else
6961       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6962   ret->copyStringInfoFrom(*this);
6963   return ret.retn();
6964 }
6965
6966 /*!
6967  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6968  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6969  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6970  * command \c range( \a bg, \a end2, \a step ).
6971  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6972  * not constructed explicitly.
6973  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6974  *  \param [in] bg - index of the first tuple to copy from \a this array.
6975  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6976  *  \param [in] step - index increment to get index of the next tuple to copy.
6977  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6978  *          is to delete using decrRef() as it is no more needed.
6979  *  \sa DataArrayInt::substr.
6980  */
6981 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
6982 {
6983   checkAllocated();
6984   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6985   int nbComp=getNumberOfComponents();
6986   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6987   ret->alloc(newNbOfTuples,nbComp);
6988   int *pt=ret->getPointer();
6989   const int *srcPt=getConstPointer()+bg*nbComp;
6990   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6991     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6992   ret->copyStringInfoFrom(*this);
6993   return ret.retn();
6994 }
6995
6996 /*!
6997  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6998  * of tuples specified by \a ranges parameter.
6999  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7000  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7001  *              of tuples in [\c begin,\c end) format.
7002  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7003  *          is to delete using decrRef() as it is no more needed.
7004  *  \throw If \a end < \a begin.
7005  *  \throw If \a end > \a this->getNumberOfTuples().
7006  *  \throw If \a this is not allocated.
7007  */
7008 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7009 {
7010   checkAllocated();
7011   int nbOfComp=getNumberOfComponents();
7012   int nbOfTuplesThis=getNumberOfTuples();
7013   if(ranges.empty())
7014     {
7015       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7016       ret->alloc(0,nbOfComp);
7017       ret->copyStringInfoFrom(*this);
7018       return ret.retn();
7019     }
7020   int ref=ranges.front().first;
7021   int nbOfTuples=0;
7022   bool isIncreasing=true;
7023   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7024     {
7025       if((*it).first<=(*it).second)
7026         {
7027           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7028             {
7029               nbOfTuples+=(*it).second-(*it).first;
7030               if(isIncreasing)
7031                 isIncreasing=ref<=(*it).first;
7032               ref=(*it).second;
7033             }
7034           else
7035             {
7036               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7037               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7038               throw INTERP_KERNEL::Exception(oss.str().c_str());
7039             }
7040         }
7041       else
7042         {
7043           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7044           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7045           throw INTERP_KERNEL::Exception(oss.str().c_str());
7046         }
7047     }
7048   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7049     return deepCpy();
7050   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7051   ret->alloc(nbOfTuples,nbOfComp);
7052   ret->copyStringInfoFrom(*this);
7053   const int *src=getConstPointer();
7054   int *work=ret->getPointer();
7055   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7056     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7057   return ret.retn();
7058 }
7059
7060 /*!
7061  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7062  * This map, if applied to \a this array, would make it sorted. For example, if
7063  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7064  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7065  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7066  * This method is useful for renumbering (in MED file for example). For more info
7067  * on renumbering see \ref MEDCouplingArrayRenumbering.
7068  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7069  *          array using decrRef() as it is no more needed.
7070  *  \throw If \a this is not allocated.
7071  *  \throw If \a this->getNumberOfComponents() != 1.
7072  *  \throw If there are equal values in \a this array.
7073  */
7074 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7075 {
7076   checkAllocated();
7077   if(getNumberOfComponents()!=1)
7078     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7079   int nbTuples=getNumberOfTuples();
7080   const int *pt=getConstPointer();
7081   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7082   DataArrayInt *ret=DataArrayInt::New();
7083   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7084   return ret;
7085 }
7086
7087 /*!
7088  * 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
7089  * input array \a ids2.
7090  * \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.
7091  * 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
7092  * inversely.
7093  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7094  *
7095  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7096  *          array using decrRef() as it is no more needed.
7097  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7098  * 
7099  */
7100 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7101 {
7102   if(!ids1 || !ids2)
7103     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7104   if(!ids1->isAllocated() || !ids2->isAllocated())
7105     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7106   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7107     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7108   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7109     {
7110       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 !";
7111       throw INTERP_KERNEL::Exception(oss.str().c_str());
7112     }
7113   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7114   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7115   p1->sort(true); p2->sort(true);
7116   if(!p1->isEqualWithoutConsideringStr(*p2))
7117     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7118   p1=ids1->checkAndPreparePermutation();
7119   p2=ids2->checkAndPreparePermutation();
7120   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7121   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7122   return p2.retn();
7123 }
7124
7125 /*!
7126  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7127  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7128  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7129  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7130  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7131  * The first of out arrays returns indices of elements of \a this array, grouped by their
7132  * place in the set \a B. The second out array is the index of the first one; it shows how
7133  * many elements of \a A are mapped into each element of \a B. <br>
7134  * For more info on
7135  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7136  * \b Example:
7137  * - \a this: [0,3,2,3,2,2,1,2]
7138  * - \a targetNb: 4
7139  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7140  * - \a arrI: [0,1,2,6,8]
7141  *
7142  * This result means: <br>
7143  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7144  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7145  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7146  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7147  * \a arrI[ 2+1 ]]); <br> etc.
7148  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7149  *         than the maximal value of \a A.
7150  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7151  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7152  *         this array using decrRef() as it is no more needed.
7153  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7154  *         elements of \a this. The caller is to delete this array using decrRef() as it
7155  *         is no more needed.
7156  *  \throw If \a this is not allocated.
7157  *  \throw If \a this->getNumberOfComponents() != 1.
7158  *  \throw If any value in \a this is more or equal to \a targetNb.
7159  */
7160 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7161 {
7162   checkAllocated();
7163   if(getNumberOfComponents()!=1)
7164     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7165   int nbOfTuples=getNumberOfTuples();
7166   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7167   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7168   retI->alloc(targetNb+1,1);
7169   const int *input=getConstPointer();
7170   std::vector< std::vector<int> > tmp(targetNb);
7171   for(int i=0;i<nbOfTuples;i++)
7172     {
7173       int tmp2=input[i];
7174       if(tmp2>=0 && tmp2<targetNb)
7175         tmp[tmp2].push_back(i);
7176       else
7177         {
7178           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7179           throw INTERP_KERNEL::Exception(oss.str().c_str());
7180         }
7181     }
7182   int *retIPtr=retI->getPointer();
7183   *retIPtr=0;
7184   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7185     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7186   if(nbOfTuples!=retI->getIJ(targetNb,0))
7187     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7188   ret->alloc(nbOfTuples,1);
7189   int *retPtr=ret->getPointer();
7190   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7191     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7192   arr=ret.retn();
7193   arrI=retI.retn();
7194 }
7195
7196
7197 /*!
7198  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7199  * from a zip representation of a surjective format (returned e.g. by
7200  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7201  * for example). The result array minimizes the permutation. <br>
7202  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7203  * \b Example: <br>
7204  * - \a nbOfOldTuples: 10 
7205  * - \a arr          : [0,3, 5,7,9]
7206  * - \a arrIBg       : [0,2,5]
7207  * - \a newNbOfTuples: 7
7208  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7209  *
7210  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7211  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7212  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7213  *         (indices of) equal values. Its every element (except the last one) points to
7214  *         the first element of a group of equal values.
7215  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7216  *          arrIBg is \a arrIEnd[ -1 ].
7217  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7218  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7219  *          array using decrRef() as it is no more needed.
7220  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7221  */
7222 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7223 {
7224   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7225   ret->alloc(nbOfOldTuples,1);
7226   int *pt=ret->getPointer();
7227   std::fill(pt,pt+nbOfOldTuples,-1);
7228   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7229   const int *cIPtr=arrIBg;
7230   for(int i=0;i<nbOfGrps;i++)
7231     pt[arr[cIPtr[i]]]=-(i+2);
7232   int newNb=0;
7233   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7234     {
7235       if(pt[iNode]<0)
7236         {
7237           if(pt[iNode]==-1)
7238             pt[iNode]=newNb++;
7239           else
7240             {
7241               int grpId=-(pt[iNode]+2);
7242               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7243                 {
7244                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7245                     pt[arr[j]]=newNb;
7246                   else
7247                     {
7248                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7249                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7250                     }
7251                 }
7252               newNb++;
7253             }
7254         }
7255     }
7256   newNbOfTuples=newNb;
7257   return ret.retn();
7258 }
7259
7260 /*!
7261  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7262  * which if applied to \a this array would make it sorted ascendingly.
7263  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7264  * \b Example: <br>
7265  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7266  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7267  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7268  *
7269  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7270  *          array using decrRef() as it is no more needed.
7271  *  \throw If \a this is not allocated.
7272  *  \throw If \a this->getNumberOfComponents() != 1.
7273  */
7274 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7275 {
7276   checkAllocated();
7277   if(getNumberOfComponents()!=1)
7278     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7279   int nbOfTuples=getNumberOfTuples();
7280   const int *pt=getConstPointer();
7281   std::map<int,int> m;
7282   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7283   ret->alloc(nbOfTuples,1);
7284   int *opt=ret->getPointer();
7285   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7286     {
7287       int val=*pt;
7288       std::map<int,int>::iterator it=m.find(val);
7289       if(it!=m.end())
7290         {
7291           *opt=(*it).second;
7292           (*it).second++;
7293         }
7294       else
7295         {
7296           *opt=0;
7297           m.insert(std::pair<int,int>(val,1));
7298         }
7299     }
7300   int sum=0;
7301   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7302     {
7303       int vt=(*it).second;
7304       (*it).second=sum;
7305       sum+=vt;
7306     }
7307   pt=getConstPointer();
7308   opt=ret->getPointer();
7309   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7310     *opt+=m[*pt];
7311   //
7312   return ret.retn();
7313 }
7314
7315 /*!
7316  * Checks if contents of \a this array are equal to that of an array filled with
7317  * iota(). This method is particularly useful for DataArrayInt instances that represent
7318  * a renumbering array to check the real need in renumbering. 
7319  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7320  *  \throw If \a this is not allocated.
7321  *  \throw If \a this->getNumberOfComponents() != 1.
7322  */
7323 bool DataArrayInt::isIdentity() const
7324 {
7325   checkAllocated();
7326   if(getNumberOfComponents()!=1)
7327     return false;
7328   int nbOfTuples=getNumberOfTuples();
7329   const int *pt=getConstPointer();
7330   for(int i=0;i<nbOfTuples;i++,pt++)
7331     if(*pt!=i)
7332       return false;
7333   return true;
7334 }
7335
7336 /*!
7337  * Checks if all values in \a this array are equal to \a val.
7338  *  \param [in] val - value to check equality of array values to.
7339  *  \return bool - \a true if all values are \a val.
7340  *  \throw If \a this is not allocated.
7341  *  \throw If \a this->getNumberOfComponents() != 1
7342  */
7343 bool DataArrayInt::isUniform(int val) const
7344 {
7345   checkAllocated();
7346   if(getNumberOfComponents()!=1)
7347     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7348   int nbOfTuples=getNumberOfTuples();
7349   const int *w=getConstPointer();
7350   const int *end2=w+nbOfTuples;
7351   for(;w!=end2;w++)
7352     if(*w!=val)
7353       return false;
7354   return true;
7355 }
7356
7357 /*!
7358  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7359  * array to the new one.
7360  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7361  */
7362 DataArrayDouble *DataArrayInt::convertToDblArr() const
7363 {
7364   checkAllocated();
7365   DataArrayDouble *ret=DataArrayDouble::New();
7366   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7367   std::size_t nbOfVals=getNbOfElems();
7368   const int *src=getConstPointer();
7369   double *dest=ret->getPointer();
7370   std::copy(src,src+nbOfVals,dest);
7371   ret->copyStringInfoFrom(*this);
7372   return ret;
7373 }
7374
7375 /*!
7376  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7377  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7378  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7379  * This method is a specialization of selectByTupleId2().
7380  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7381  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7382  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7383  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7384  *          is to delete using decrRef() as it is no more needed.
7385  *  \throw If \a tupleIdBg < 0.
7386  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7387     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7388  *  \sa DataArrayInt::selectByTupleId2
7389  */
7390 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7391 {
7392   checkAllocated();
7393   int nbt=getNumberOfTuples();
7394   if(tupleIdBg<0)
7395     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7396   if(tupleIdBg>nbt)
7397     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7398   int trueEnd=tupleIdEnd;
7399   if(tupleIdEnd!=-1)
7400     {
7401       if(tupleIdEnd>nbt)
7402         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7403     }
7404   else
7405     trueEnd=nbt;
7406   int nbComp=getNumberOfComponents();
7407   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7408   ret->alloc(trueEnd-tupleIdBg,nbComp);
7409   ret->copyStringInfoFrom(*this);
7410   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7411   return ret.retn();
7412 }
7413
7414 /*!
7415  * Changes the number of components within \a this array so that its raw data **does
7416  * not** change, instead splitting this data into tuples changes.
7417  *  \warning This method erases all (name and unit) component info set before!
7418  *  \param [in] newNbOfComp - number of components for \a this array to have.
7419  *  \throw If \a this is not allocated
7420  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7421  *  \throw If \a newNbOfCompo is lower than 1.
7422  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7423  *  \warning This method erases all (name and unit) component info set before!
7424  */
7425 void DataArrayInt::rearrange(int newNbOfCompo)
7426 {
7427   checkAllocated();
7428   if(newNbOfCompo<1)
7429     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7430   std::size_t nbOfElems=getNbOfElems();
7431   if(nbOfElems%newNbOfCompo!=0)
7432     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7433   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7434     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7435   _info_on_compo.clear();
7436   _info_on_compo.resize(newNbOfCompo);
7437   declareAsNew();
7438 }
7439
7440 /*!
7441  * Changes the number of components within \a this array to be equal to its number
7442  * of tuples, and inversely its number of tuples to become equal to its number of 
7443  * components. So that its raw data **does not** change, instead splitting this
7444  * data into tuples changes.
7445  *  \warning This method erases all (name and unit) component info set before!
7446  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7447  *  \throw If \a this is not allocated.
7448  *  \sa rearrange()
7449  */
7450 void DataArrayInt::transpose()
7451 {
7452   checkAllocated();
7453   int nbOfTuples=getNumberOfTuples();
7454   rearrange(nbOfTuples);
7455 }
7456
7457 /*!
7458  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7459  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7460  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7461  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7462  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7463  * components.  
7464  *  \param [in] newNbOfComp - number of components for the new array to have.
7465  *  \param [in] dftValue - value assigned to new values added to the new array.
7466  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7467  *          is to delete using decrRef() as it is no more needed.
7468  *  \throw If \a this is not allocated.
7469  */
7470 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7471 {
7472   checkAllocated();
7473   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7474   ret->alloc(getNumberOfTuples(),newNbOfComp);
7475   const int *oldc=getConstPointer();
7476   int *nc=ret->getPointer();
7477   int nbOfTuples=getNumberOfTuples();
7478   int oldNbOfComp=getNumberOfComponents();
7479   int dim=std::min(oldNbOfComp,newNbOfComp);
7480   for(int i=0;i<nbOfTuples;i++)
7481     {
7482       int j=0;
7483       for(;j<dim;j++)
7484         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7485       for(;j<newNbOfComp;j++)
7486         nc[newNbOfComp*i+j]=dftValue;
7487     }
7488   ret->setName(getName().c_str());
7489   for(int i=0;i<dim;i++)
7490     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7491   ret->setName(getName().c_str());
7492   return ret.retn();
7493 }
7494
7495 /*!
7496  * Changes number of tuples in the array. If the new number of tuples is smaller
7497  * than the current number the array is truncated, otherwise the array is extended.
7498  *  \param [in] nbOfTuples - new number of tuples. 
7499  *  \throw If \a this is not allocated.
7500  *  \throw If \a nbOfTuples is negative.
7501  */
7502 void DataArrayInt::reAlloc(int nbOfTuples)
7503 {
7504   if(nbOfTuples<0)
7505     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7506   checkAllocated();
7507   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7508   declareAsNew();
7509 }
7510
7511
7512 /*!
7513  * Returns a copy of \a this array composed of selected components.
7514  * The new DataArrayInt has the same number of tuples but includes components
7515  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7516  * can be either less, same or more than \a this->getNbOfElems().
7517  *  \param [in] compoIds - sequence of zero based indices of components to include
7518  *              into the new array.
7519  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7520  *          is to delete using decrRef() as it is no more needed.
7521  *  \throw If \a this is not allocated.
7522  *  \throw If a component index (\a i) is not valid: 
7523  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7524  *
7525  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7526  */
7527 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7528 {
7529   checkAllocated();
7530   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7531   int newNbOfCompo=(int)compoIds.size();
7532   int oldNbOfCompo=getNumberOfComponents();
7533   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7534     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7535   int nbOfTuples=getNumberOfTuples();
7536   ret->alloc(nbOfTuples,newNbOfCompo);
7537   ret->copyPartOfStringInfoFrom(*this,compoIds);
7538   const int *oldc=getConstPointer();
7539   int *nc=ret->getPointer();
7540   for(int i=0;i<nbOfTuples;i++)
7541     for(int j=0;j<newNbOfCompo;j++,nc++)
7542       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7543   return ret.retn();
7544 }
7545
7546 /*!
7547  * Appends components of another array to components of \a this one, tuple by tuple.
7548  * So that the number of tuples of \a this array remains the same and the number of 
7549  * components increases.
7550  *  \param [in] other - the DataArrayInt to append to \a this one.
7551  *  \throw If \a this is not allocated.
7552  *  \throw If \a this and \a other arrays have different number of tuples.
7553  *
7554  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7555  *
7556  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7557  */
7558 void DataArrayInt::meldWith(const DataArrayInt *other)
7559 {
7560   if(!other)
7561     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7562   checkAllocated();
7563   other->checkAllocated();
7564   int nbOfTuples=getNumberOfTuples();
7565   if(nbOfTuples!=other->getNumberOfTuples())
7566     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7567   int nbOfComp1=getNumberOfComponents();
7568   int nbOfComp2=other->getNumberOfComponents();
7569   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7570   int *w=newArr;
7571   const int *inp1=getConstPointer();
7572   const int *inp2=other->getConstPointer();
7573   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7574     {
7575       w=std::copy(inp1,inp1+nbOfComp1,w);
7576       w=std::copy(inp2,inp2+nbOfComp2,w);
7577     }
7578   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7579   std::vector<int> compIds(nbOfComp2);
7580   for(int i=0;i<nbOfComp2;i++)
7581     compIds[i]=nbOfComp1+i;
7582   copyPartOfStringInfoFrom2(compIds,*other);
7583 }
7584
7585 /*!
7586  * Copy all components in a specified order from another DataArrayInt.
7587  * The specified components become the first ones in \a this array.
7588  * Both numerical and textual data is copied. The number of tuples in \a this and
7589  * the other array can be different.
7590  *  \param [in] a - the array to copy data from.
7591  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7592  *              to be copied.
7593  *  \throw If \a a is NULL.
7594  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7595  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7596  *
7597  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7598  */
7599 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7600 {
7601   if(!a)
7602     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7603   checkAllocated();
7604   a->checkAllocated();
7605   copyPartOfStringInfoFrom2(compoIds,*a);
7606   std::size_t partOfCompoSz=compoIds.size();
7607   int nbOfCompo=getNumberOfComponents();
7608   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7609   const int *ac=a->getConstPointer();
7610   int *nc=getPointer();
7611   for(int i=0;i<nbOfTuples;i++)
7612     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7613       nc[nbOfCompo*i+compoIds[j]]=*ac;
7614 }
7615
7616 /*!
7617  * Copy all values from another DataArrayInt into specified tuples and components
7618  * of \a this array. Textual data is not copied.
7619  * The tree parameters defining set of indices of tuples and components are similar to
7620  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7621  *  \param [in] a - the array to copy values from.
7622  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7623  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7624  *              are located.
7625  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7626  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7627  *  \param [in] endComp - index of the component before which the components to assign
7628  *              to are located.
7629  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7630  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7631  *              must be equal to the number of columns to assign to, else an
7632  *              exception is thrown; if \a false, then it is only required that \a
7633  *              a->getNbOfElems() equals to number of values to assign to (this condition
7634  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7635  *              values to assign to is given by following Python expression:
7636  *              \a nbTargetValues = 
7637  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7638  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7639  *  \throw If \a a is NULL.
7640  *  \throw If \a a is not allocated.
7641  *  \throw If \a this is not allocated.
7642  *  \throw If parameters specifying tuples and components to assign to do not give a
7643  *            non-empty range of increasing indices.
7644  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7645  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7646  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7647  *
7648  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7649  */
7650 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7651 {
7652   if(!a)
7653     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7654   const char msg[]="DataArrayInt::setPartOfValues1";
7655   checkAllocated();
7656   a->checkAllocated();
7657   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7658   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7659   int nbComp=getNumberOfComponents();
7660   int nbOfTuples=getNumberOfTuples();
7661   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7662   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7663   bool assignTech=true;
7664   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7665     {
7666       if(strictCompoCompare)
7667         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7668     }
7669   else
7670     {
7671       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7672       assignTech=false;
7673     }
7674   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7675   const int *srcPt=a->getConstPointer();
7676   if(assignTech)
7677     {
7678       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7679         for(int j=0;j<newNbOfComp;j++,srcPt++)
7680           pt[j*stepComp]=*srcPt;
7681     }
7682   else
7683     {
7684       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7685         {
7686           const int *srcPt2=srcPt;
7687           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7688             pt[j*stepComp]=*srcPt2;
7689         }
7690     }
7691 }
7692
7693 /*!
7694  * Assign a given value to values at specified tuples and components of \a this array.
7695  * The tree parameters defining set of indices of tuples and components are similar to
7696  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7697  *  \param [in] a - the value to assign.
7698  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7699  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7700  *              are located.
7701  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7702  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7703  *  \param [in] endComp - index of the component before which the components to assign
7704  *              to are located.
7705  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7706  *  \throw If \a this is not allocated.
7707  *  \throw If parameters specifying tuples and components to assign to, do not give a
7708  *            non-empty range of increasing indices or indices are out of a valid range
7709  *            for \this array.
7710  *
7711  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7712  */
7713 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7714 {
7715   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7716   checkAllocated();
7717   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7718   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7719   int nbComp=getNumberOfComponents();
7720   int nbOfTuples=getNumberOfTuples();
7721   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7722   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7723   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7724   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7725     for(int j=0;j<newNbOfComp;j++)
7726       pt[j*stepComp]=a;
7727 }
7728
7729
7730 /*!
7731  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7732  * components of \a this array. Textual data is not copied.
7733  * The tuples and components to assign to are defined by C arrays of indices.
7734  * There are two *modes of usage*:
7735  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7736  *   of \a a is assigned to its own location within \a this array. 
7737  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7738  *   components of every specified tuple of \a this array. In this mode it is required
7739  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7740  * 
7741  *  \param [in] a - the array to copy values from.
7742  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7743  *              assign values of \a a to.
7744  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7745  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7746  *              \a bgTuples <= \a pi < \a endTuples.
7747  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7748  *              assign values of \a a to.
7749  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7750  *              pointer to a component index <em>(pi)</em> varies as this: 
7751  *              \a bgComp <= \a pi < \a endComp.
7752  *  \param [in] strictCompoCompare - this parameter is checked only if the
7753  *               *mode of usage* is the first; if it is \a true (default), 
7754  *               then \a a->getNumberOfComponents() must be equal 
7755  *               to the number of specified columns, else this is not required.
7756  *  \throw If \a a is NULL.
7757  *  \throw If \a a is not allocated.
7758  *  \throw If \a this is not allocated.
7759  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7760  *         out of a valid range for \a this array.
7761  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7762  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7763  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7764  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7765  *
7766  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7767  */
7768 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7769 {
7770   if(!a)
7771     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7772   const char msg[]="DataArrayInt::setPartOfValues2";
7773   checkAllocated();
7774   a->checkAllocated();
7775   int nbComp=getNumberOfComponents();
7776   int nbOfTuples=getNumberOfTuples();
7777   for(const int *z=bgComp;z!=endComp;z++)
7778     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7779   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7780   int newNbOfComp=(int)std::distance(bgComp,endComp);
7781   bool assignTech=true;
7782   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7783     {
7784       if(strictCompoCompare)
7785         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7786     }
7787   else
7788     {
7789       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7790       assignTech=false;
7791     }
7792   int *pt=getPointer();
7793   const int *srcPt=a->getConstPointer();
7794   if(assignTech)
7795     {    
7796       for(const int *w=bgTuples;w!=endTuples;w++)
7797         {
7798           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7799           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7800             {    
7801               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7802             }
7803         }
7804     }
7805   else
7806     {
7807       for(const int *w=bgTuples;w!=endTuples;w++)
7808         {
7809           const int *srcPt2=srcPt;
7810           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7811           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7812             {    
7813               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7814             }
7815         }
7816     }
7817 }
7818
7819 /*!
7820  * Assign a given value to values at specified tuples and components of \a this array.
7821  * The tuples and components to assign to are defined by C arrays of indices.
7822  *  \param [in] a - the value to assign.
7823  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7824  *              assign \a a to.
7825  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7826  *              pointer to a tuple index (\a pi) varies as this: 
7827  *              \a bgTuples <= \a pi < \a endTuples.
7828  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7829  *              assign \a a to.
7830  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7831  *              pointer to a component index (\a pi) varies as this: 
7832  *              \a bgComp <= \a pi < \a endComp.
7833  *  \throw If \a this is not allocated.
7834  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7835  *         out of a valid range for \a this array.
7836  *
7837  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7838  */
7839 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7840 {
7841   checkAllocated();
7842   int nbComp=getNumberOfComponents();
7843   int nbOfTuples=getNumberOfTuples();
7844   for(const int *z=bgComp;z!=endComp;z++)
7845     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7846   int *pt=getPointer();
7847   for(const int *w=bgTuples;w!=endTuples;w++)
7848     for(const int *z=bgComp;z!=endComp;z++)
7849       {
7850         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7851         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7852       }
7853 }
7854
7855 /*!
7856  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7857  * components of \a this array. Textual data is not copied.
7858  * The tuples to assign to are defined by a C array of indices.
7859  * The components to assign to are defined by three values similar to parameters of
7860  * the Python function \c range(\c start,\c stop,\c step).
7861  * There are two *modes of usage*:
7862  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7863  *   of \a a is assigned to its own location within \a this array. 
7864  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7865  *   components of every specified tuple of \a this array. In this mode it is required
7866  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7867  *
7868  *  \param [in] a - the array to copy values from.
7869  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7870  *              assign values of \a a to.
7871  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7872  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7873  *              \a bgTuples <= \a pi < \a endTuples.
7874  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7875  *  \param [in] endComp - index of the component before which the components to assign
7876  *              to are located.
7877  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7878  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7879  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7880  *               then \a a->getNumberOfComponents() must be equal 
7881  *               to the number of specified columns, else this is not required.
7882  *  \throw If \a a is NULL.
7883  *  \throw If \a a is not allocated.
7884  *  \throw If \a this is not allocated.
7885  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7886  *         \a this array.
7887  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7888  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7889  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7890  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7891  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7892  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7893  *  \throw If parameters specifying components to assign to, do not give a
7894  *            non-empty range of increasing indices or indices are out of a valid range
7895  *            for \this array.
7896  *
7897  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7898  */
7899 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7900 {
7901   if(!a)
7902     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7903   const char msg[]="DataArrayInt::setPartOfValues3";
7904   checkAllocated();
7905   a->checkAllocated();
7906   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7907   int nbComp=getNumberOfComponents();
7908   int nbOfTuples=getNumberOfTuples();
7909   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7910   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7911   bool assignTech=true;
7912   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7913     {
7914       if(strictCompoCompare)
7915         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7916     }
7917   else
7918     {
7919       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7920       assignTech=false;
7921     }
7922   int *pt=getPointer()+bgComp;
7923   const int *srcPt=a->getConstPointer();
7924   if(assignTech)
7925     {
7926       for(const int *w=bgTuples;w!=endTuples;w++)
7927         for(int j=0;j<newNbOfComp;j++,srcPt++)
7928           {
7929             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7930             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7931           }
7932     }
7933   else
7934     {
7935       for(const int *w=bgTuples;w!=endTuples;w++)
7936         {
7937           const int *srcPt2=srcPt;
7938           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7939             {
7940               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7941               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7942             }
7943         }
7944     }
7945 }
7946
7947 /*!
7948  * Assign a given value to values at specified tuples and components of \a this array.
7949  * The tuples to assign to are defined by a C array of indices.
7950  * The components to assign to are defined by three values similar to parameters of
7951  * the Python function \c range(\c start,\c stop,\c step).
7952  *  \param [in] a - the value to assign.
7953  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7954  *              assign \a a to.
7955  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7956  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7957  *              \a bgTuples <= \a pi < \a endTuples.
7958  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7959  *  \param [in] endComp - index of the component before which the components to assign
7960  *              to are located.
7961  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7962  *  \throw If \a this is not allocated.
7963  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7964  *         \a this array.
7965  *  \throw If parameters specifying components to assign to, do not give a
7966  *            non-empty range of increasing indices or indices are out of a valid range
7967  *            for \this array.
7968  *
7969  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7970  */
7971 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
7972 {
7973   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7974   checkAllocated();
7975   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7976   int nbComp=getNumberOfComponents();
7977   int nbOfTuples=getNumberOfTuples();
7978   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7979   int *pt=getPointer()+bgComp;
7980   for(const int *w=bgTuples;w!=endTuples;w++)
7981     for(int j=0;j<newNbOfComp;j++)
7982       {
7983         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7984         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7985       }
7986 }
7987
7988 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7989 {
7990   if(!a)
7991     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7992   const char msg[]="DataArrayInt::setPartOfValues4";
7993   checkAllocated();
7994   a->checkAllocated();
7995   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7996   int newNbOfComp=(int)std::distance(bgComp,endComp);
7997   int nbComp=getNumberOfComponents();
7998   for(const int *z=bgComp;z!=endComp;z++)
7999     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8000   int nbOfTuples=getNumberOfTuples();
8001   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8002   bool assignTech=true;
8003   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8004     {
8005       if(strictCompoCompare)
8006         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8007     }
8008   else
8009     {
8010       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8011       assignTech=false;
8012     }
8013   const int *srcPt=a->getConstPointer();
8014   int *pt=getPointer()+bgTuples*nbComp;
8015   if(assignTech)
8016     {
8017       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8018         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8019           pt[*z]=*srcPt;
8020     }
8021   else
8022     {
8023       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8024         {
8025           const int *srcPt2=srcPt;
8026           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8027             pt[*z]=*srcPt2;
8028         }
8029     }
8030 }
8031
8032 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8033 {
8034   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8035   checkAllocated();
8036   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8037   int nbComp=getNumberOfComponents();
8038   for(const int *z=bgComp;z!=endComp;z++)
8039     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8040   int nbOfTuples=getNumberOfTuples();
8041   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8042   int *pt=getPointer()+bgTuples*nbComp;
8043   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8044     for(const int *z=bgComp;z!=endComp;z++)
8045       pt[*z]=a;
8046 }
8047
8048 /*!
8049  * Copy some tuples from another DataArrayInt into specified tuples
8050  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8051  * components.
8052  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8053  * All components of selected tuples are copied.
8054  *  \param [in] a - the array to copy values from.
8055  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8056  *              target tuples of \a this. \a tuplesSelec has two components, and the
8057  *              first component specifies index of the source tuple and the second
8058  *              one specifies index of the target tuple.
8059  *  \throw If \a this is not allocated.
8060  *  \throw If \a a is NULL.
8061  *  \throw If \a a is not allocated.
8062  *  \throw If \a tuplesSelec is NULL.
8063  *  \throw If \a tuplesSelec is not allocated.
8064  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8065  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8066  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8067  *         the corresponding (\a this or \a a) array.
8068  */
8069 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8070 {
8071   if(!a || !tuplesSelec)
8072     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8073   checkAllocated();
8074   a->checkAllocated();
8075   tuplesSelec->checkAllocated();
8076   int nbOfComp=getNumberOfComponents();
8077   if(nbOfComp!=a->getNumberOfComponents())
8078     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8079   if(tuplesSelec->getNumberOfComponents()!=2)
8080     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8081   int thisNt=getNumberOfTuples();
8082   int aNt=a->getNumberOfTuples();
8083   int *valsToSet=getPointer();
8084   const int *valsSrc=a->getConstPointer();
8085   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8086     {
8087       if(tuple[1]>=0 && tuple[1]<aNt)
8088         {
8089           if(tuple[0]>=0 && tuple[0]<thisNt)
8090             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8091           else
8092             {
8093               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8094               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8095               throw INTERP_KERNEL::Exception(oss.str().c_str());
8096             }
8097         }
8098       else
8099         {
8100           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8101           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8102           throw INTERP_KERNEL::Exception(oss.str().c_str());
8103         }
8104     }
8105 }
8106
8107 /*!
8108  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8109  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8110  * components.
8111  * The tuples to assign to are defined by index of the first tuple, and
8112  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8113  * The tuples to copy are defined by values of a DataArrayInt.
8114  * All components of selected tuples are copied.
8115  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8116  *              values to.
8117  *  \param [in] aBase - the array to copy values from.
8118  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8119  *  \throw If \a this is not allocated.
8120  *  \throw If \a aBase is NULL.
8121  *  \throw If \a aBase is not allocated.
8122  *  \throw If \a tuplesSelec is NULL.
8123  *  \throw If \a tuplesSelec is not allocated.
8124  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8125  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8126  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8127  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8128  *         \a aBase array.
8129  */
8130 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8131 {
8132   if(!aBase || !tuplesSelec)
8133     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8134   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8135   if(!a)
8136     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8137   checkAllocated();
8138   a->checkAllocated();
8139   tuplesSelec->checkAllocated();
8140   int nbOfComp=getNumberOfComponents();
8141   if(nbOfComp!=a->getNumberOfComponents())
8142     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8143   if(tuplesSelec->getNumberOfComponents()!=1)
8144     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8145   int thisNt=getNumberOfTuples();
8146   int aNt=a->getNumberOfTuples();
8147   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8148   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8149   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8150     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8151   const int *valsSrc=a->getConstPointer();
8152   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8153     {
8154       if(*tuple>=0 && *tuple<aNt)
8155         {
8156           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8157         }
8158       else
8159         {
8160           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8161           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8162           throw INTERP_KERNEL::Exception(oss.str().c_str());
8163         }
8164     }
8165 }
8166
8167 /*!
8168  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8169  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8170  * components.
8171  * The tuples to copy are defined by three values similar to parameters of
8172  * the Python function \c range(\c start,\c stop,\c step).
8173  * The tuples to assign to are defined by index of the first tuple, and
8174  * their number is defined by number of tuples to copy.
8175  * All components of selected tuples are copied.
8176  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8177  *              values to.
8178  *  \param [in] aBase - the array to copy values from.
8179  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8180  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8181  *              are located.
8182  *  \param [in] step - index increment to get index of the next tuple to copy.
8183  *  \throw If \a this is not allocated.
8184  *  \throw If \a aBase is NULL.
8185  *  \throw If \a aBase is not allocated.
8186  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8187  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8188  *  \throw If parameters specifying tuples to copy, do not give a
8189  *            non-empty range of increasing indices or indices are out of a valid range
8190  *            for the array \a aBase.
8191  */
8192 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8193 {
8194   if(!aBase)
8195     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8196   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8197   if(!a)
8198     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8199   checkAllocated();
8200   a->checkAllocated();
8201   int nbOfComp=getNumberOfComponents();
8202   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8203   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8204   if(nbOfComp!=a->getNumberOfComponents())
8205     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8206   int thisNt=getNumberOfTuples();
8207   int aNt=a->getNumberOfTuples();
8208   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8209   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8210     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8211   if(end2>aNt)
8212     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8213   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8214   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8215     {
8216       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8217     }
8218 }
8219
8220 /*!
8221  * Returns a value located at specified tuple and component.
8222  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8223  * parameters is checked. So this method is safe but expensive if used to go through
8224  * all values of \a this.
8225  *  \param [in] tupleId - index of tuple of interest.
8226  *  \param [in] compoId - index of component of interest.
8227  *  \return double - value located by \a tupleId and \a compoId.
8228  *  \throw If \a this is not allocated.
8229  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8230  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8231  */
8232 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8233 {
8234   checkAllocated();
8235   if(tupleId<0 || tupleId>=getNumberOfTuples())
8236     {
8237       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8238       throw INTERP_KERNEL::Exception(oss.str().c_str());
8239     }
8240   if(compoId<0 || compoId>=getNumberOfComponents())
8241     {
8242       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8243       throw INTERP_KERNEL::Exception(oss.str().c_str());
8244     }
8245   return _mem[tupleId*_info_on_compo.size()+compoId];
8246 }
8247
8248 /*!
8249  * Returns the first value of \a this. 
8250  *  \return int - the last value of \a this array.
8251  *  \throw If \a this is not allocated.
8252  *  \throw If \a this->getNumberOfComponents() != 1.
8253  *  \throw If \a this->getNumberOfTuples() < 1.
8254  */
8255 int DataArrayInt::front() const
8256 {
8257   checkAllocated();
8258   if(getNumberOfComponents()!=1)
8259     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8260   int nbOfTuples=getNumberOfTuples();
8261   if(nbOfTuples<1)
8262     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8263   return *(getConstPointer());
8264 }
8265
8266 /*!
8267  * Returns the last value of \a this. 
8268  *  \return int - the last value of \a this array.
8269  *  \throw If \a this is not allocated.
8270  *  \throw If \a this->getNumberOfComponents() != 1.
8271  *  \throw If \a this->getNumberOfTuples() < 1.
8272  */
8273 int DataArrayInt::back() const
8274 {
8275   checkAllocated();
8276   if(getNumberOfComponents()!=1)
8277     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8278   int nbOfTuples=getNumberOfTuples();
8279   if(nbOfTuples<1)
8280     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8281   return *(getConstPointer()+nbOfTuples-1);
8282 }
8283
8284 /*!
8285  * Assign pointer to one array to a pointer to another appay. Reference counter of
8286  * \a arrayToSet is incremented / decremented.
8287  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8288  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8289  */
8290 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8291 {
8292   if(newArray!=arrayToSet)
8293     {
8294       if(arrayToSet)
8295         arrayToSet->decrRef();
8296       arrayToSet=newArray;
8297       if(arrayToSet)
8298         arrayToSet->incrRef();
8299     }
8300 }
8301
8302 DataArrayIntIterator *DataArrayInt::iterator()
8303 {
8304   return new DataArrayIntIterator(this);
8305 }
8306
8307 /*!
8308  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8309  * given one.
8310  *  \param [in] val - the value to find within \a this.
8311  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8312  *          array using decrRef() as it is no more needed.
8313  *  \throw If \a this is not allocated.
8314  *  \throw If \a this->getNumberOfComponents() != 1.
8315  */
8316 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8317 {
8318   checkAllocated();
8319   if(getNumberOfComponents()!=1)
8320     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8321   const int *cptr=getConstPointer();
8322   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8323   int nbOfTuples=getNumberOfTuples();
8324   for(int i=0;i<nbOfTuples;i++,cptr++)
8325     if(*cptr==val)
8326       ret->pushBackSilent(i);
8327   return ret.retn();
8328 }
8329
8330 /*!
8331  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8332  * equal to a given one. 
8333  *  \param [in] val - the value to ignore within \a this.
8334  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8335  *          array using decrRef() as it is no more needed.
8336  *  \throw If \a this is not allocated.
8337  *  \throw If \a this->getNumberOfComponents() != 1.
8338  */
8339 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8340 {
8341   checkAllocated();
8342   if(getNumberOfComponents()!=1)
8343     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8344   const int *cptr=getConstPointer();
8345   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8346   int nbOfTuples=getNumberOfTuples();
8347   for(int i=0;i<nbOfTuples;i++,cptr++)
8348     if(*cptr!=val)
8349       ret->pushBackSilent(i);
8350   return ret.retn();
8351 }
8352
8353
8354 /*!
8355  * Assigns \a newValue to all elements holding \a oldValue within \a this
8356  * one-dimensional array.
8357  *  \param [in] oldValue - the value to replace.
8358  *  \param [in] newValue - the value to assign.
8359  *  \return int - number of replacements performed.
8360  *  \throw If \a this is not allocated.
8361  *  \throw If \a this->getNumberOfComponents() != 1.
8362  */
8363 int DataArrayInt::changeValue(int oldValue, int newValue)
8364 {
8365   checkAllocated();
8366   if(getNumberOfComponents()!=1)
8367     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8368   int *start=getPointer();
8369   int *end2=start+getNbOfElems();
8370   int ret=0;
8371   for(int *val=start;val!=end2;val++)
8372     {
8373       if(*val==oldValue)
8374         {
8375           *val=newValue;
8376           ret++;
8377         }
8378     }
8379   return ret;
8380 }
8381
8382 /*!
8383  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8384  * one of given values.
8385  *  \param [in] valsBg - an array of values to find within \a this array.
8386  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8387  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8388  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8389  *          array using decrRef() as it is no more needed.
8390  *  \throw If \a this->getNumberOfComponents() != 1.
8391  */
8392 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8393 {
8394   if(getNumberOfComponents()!=1)
8395     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8396   std::set<int> vals2(valsBg,valsEnd);
8397   const int *cptr=getConstPointer();
8398   std::vector<int> res;
8399   int nbOfTuples=getNumberOfTuples();
8400   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8401   for(int i=0;i<nbOfTuples;i++,cptr++)
8402     if(vals2.find(*cptr)!=vals2.end())
8403       ret->pushBackSilent(i);
8404   return ret.retn();
8405 }
8406
8407 /*!
8408  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8409  * equal to any of given values.
8410  *  \param [in] valsBg - an array of values to ignore within \a this array.
8411  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8412  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8413  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8414  *          array using decrRef() as it is no more needed.
8415  *  \throw If \a this->getNumberOfComponents() != 1.
8416  */
8417 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8418 {
8419   if(getNumberOfComponents()!=1)
8420     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8421   std::set<int> vals2(valsBg,valsEnd);
8422   const int *cptr=getConstPointer();
8423   std::vector<int> res;
8424   int nbOfTuples=getNumberOfTuples();
8425   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8426   for(int i=0;i<nbOfTuples;i++,cptr++)
8427     if(vals2.find(*cptr)==vals2.end())
8428       ret->pushBackSilent(i);
8429   return ret.retn();
8430 }
8431
8432 /*!
8433  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8434  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8435  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8436  * If any the tuple id is returned. If not -1 is returned.
8437  * 
8438  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8439  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8440  *
8441  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8442  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8443  */
8444 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8445 {
8446   checkAllocated();
8447   int nbOfCompo=getNumberOfComponents();
8448   if(nbOfCompo==0)
8449     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8450   if(nbOfCompo!=(int)tupl.size())
8451     {
8452       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8453       throw INTERP_KERNEL::Exception(oss.str().c_str());
8454     }
8455   const int *cptr=getConstPointer();
8456   std::size_t nbOfVals=getNbOfElems();
8457   for(const int *work=cptr;work!=cptr+nbOfVals;)
8458     {
8459       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8460       if(work!=cptr+nbOfVals)
8461         {
8462           if(std::distance(cptr,work)%nbOfCompo!=0)
8463             work++;
8464           else
8465             return std::distance(cptr,work)/nbOfCompo;
8466         }
8467     }
8468   return -1;
8469 }
8470
8471 /*!
8472  * This method searches the sequence specified in input parameter \b vals in \b this.
8473  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8474  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8475  * \sa DataArrayInt::locateTuple
8476  */
8477 int DataArrayInt::search(const std::vector<int>& vals) const
8478 {
8479   checkAllocated();
8480   int nbOfCompo=getNumberOfComponents();
8481   if(nbOfCompo!=1)
8482     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8483   const int *cptr=getConstPointer();
8484   std::size_t nbOfVals=getNbOfElems();
8485   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8486   if(loc!=cptr+nbOfVals)
8487     return std::distance(cptr,loc);
8488   return -1;
8489 }
8490
8491 /*!
8492  * This method expects to be called when number of components of this is equal to one.
8493  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8494  * If not any tuple contains \b value -1 is returned.
8495  * \sa DataArrayInt::presenceOfValue
8496  */
8497 int DataArrayInt::locateValue(int value) const
8498 {
8499   checkAllocated();
8500   if(getNumberOfComponents()!=1)
8501     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8502   const int *cptr=getConstPointer();
8503   int nbOfTuples=getNumberOfTuples();
8504   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8505   if(ret!=cptr+nbOfTuples)
8506     return std::distance(cptr,ret);
8507   return -1;
8508 }
8509
8510 /*!
8511  * This method expects to be called when number of components of this is equal to one.
8512  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8513  * If not any tuple contains one of the values contained in 'vals' false is returned.
8514  * \sa DataArrayInt::presenceOfValue
8515  */
8516 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8517 {
8518   checkAllocated();
8519   if(getNumberOfComponents()!=1)
8520     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8521   std::set<int> vals2(vals.begin(),vals.end());
8522   const int *cptr=getConstPointer();
8523   int nbOfTuples=getNumberOfTuples();
8524   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8525     if(vals2.find(*w)!=vals2.end())
8526       return std::distance(cptr,w);
8527   return -1;
8528 }
8529
8530 /*!
8531  * This method returns the number of values in \a this that are equals to input parameter \a value.
8532  * This method only works for single component array.
8533  *
8534  * \return a value in [ 0, \c this->getNumberOfTuples() )
8535  *
8536  * \throw If \a this is not allocated
8537  *
8538  */
8539 int DataArrayInt::count(int value) const
8540 {
8541   int ret=0;
8542   checkAllocated();
8543   if(getNumberOfComponents()!=1)
8544     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8545   const int *vals=begin();
8546   int nbOfTuples=getNumberOfTuples();
8547   for(int i=0;i<nbOfTuples;i++,vals++)
8548     if(*vals==value)
8549       ret++;
8550   return ret;
8551 }
8552
8553 /*!
8554  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8555  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8556  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8557  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8558  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8559  * \sa DataArrayInt::locateTuple
8560  */
8561 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8562 {
8563   return locateTuple(tupl)!=-1;
8564 }
8565
8566
8567 /*!
8568  * Returns \a true if a given value is present within \a this one-dimensional array.
8569  *  \param [in] value - the value to find within \a this array.
8570  *  \return bool - \a true in case if \a value is present within \a this array.
8571  *  \throw If \a this is not allocated.
8572  *  \throw If \a this->getNumberOfComponents() != 1.
8573  *  \sa locateValue()
8574  */
8575 bool DataArrayInt::presenceOfValue(int value) const
8576 {
8577   return locateValue(value)!=-1;
8578 }
8579
8580 /*!
8581  * This method expects to be called when number of components of this is equal to one.
8582  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8583  * If not any tuple contains one of the values contained in 'vals' false is returned.
8584  * \sa DataArrayInt::locateValue
8585  */
8586 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8587 {
8588   return locateValue(vals)!=-1;
8589 }
8590
8591 /*!
8592  * Accumulates values of each component of \a this array.
8593  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8594  *         by the caller, that is filled by this method with sum value for each
8595  *         component.
8596  *  \throw If \a this is not allocated.
8597  */
8598 void DataArrayInt::accumulate(int *res) const
8599 {
8600   checkAllocated();
8601   const int *ptr=getConstPointer();
8602   int nbTuple=getNumberOfTuples();
8603   int nbComps=getNumberOfComponents();
8604   std::fill(res,res+nbComps,0);
8605   for(int i=0;i<nbTuple;i++)
8606     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8607 }
8608
8609 int DataArrayInt::accumulate(int compId) const
8610 {
8611   checkAllocated();
8612   const int *ptr=getConstPointer();
8613   int nbTuple=getNumberOfTuples();
8614   int nbComps=getNumberOfComponents();
8615   if(compId<0 || compId>=nbComps)
8616     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8617   int ret=0;
8618   for(int i=0;i<nbTuple;i++)
8619     ret+=ptr[i*nbComps+compId];
8620   return ret;
8621 }
8622
8623 /*!
8624  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8625  * The returned array will have same number of components than \a this and number of tuples equal to
8626  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8627  *
8628  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8629  *
8630  * \param [in] bgOfIndex - begin (included) of the input index array.
8631  * \param [in] endOfIndex - end (excluded) of the input index array.
8632  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8633  * 
8634  * \throw If bgOfIndex or end is NULL.
8635  * \throw If input index array is not ascendingly sorted.
8636  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8637  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8638  */
8639 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8640 {
8641   if(!bgOfIndex || !endOfIndex)
8642     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8643   checkAllocated();
8644   int nbCompo=getNumberOfComponents();
8645   int nbOfTuples=getNumberOfTuples();
8646   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8647   if(sz<1)
8648     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8649   sz--;
8650   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8651   const int *w=bgOfIndex;
8652   if(*w<0 || *w>=nbOfTuples)
8653     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8654   const int *srcPt=begin()+(*w)*nbCompo;
8655   int *tmp=ret->getPointer();
8656   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8657     {
8658       std::fill(tmp,tmp+nbCompo,0);
8659       if(w[1]>=w[0])
8660         {
8661           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8662             {
8663               if(j>=0 && j<nbOfTuples)
8664                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8665               else
8666                 {
8667                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8668                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8669                 }
8670             }
8671         }
8672       else
8673         {
8674           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8675           throw INTERP_KERNEL::Exception(oss.str().c_str());
8676         }
8677     }
8678   ret->copyStringInfoFrom(*this);
8679   return ret.retn();
8680 }
8681
8682 /*!
8683  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8684  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8685  * offsetA2</em> and (2)
8686  * the number of component in the result array is same as that of each of given arrays.
8687  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8688  * Info on components is copied from the first of the given arrays. Number of components
8689  * in the given arrays must be the same.
8690  *  \param [in] a1 - an array to include in the result array.
8691  *  \param [in] a2 - another array to include in the result array.
8692  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8693  *  \return DataArrayInt * - the new instance of DataArrayInt.
8694  *          The caller is to delete this result array using decrRef() as it is no more
8695  *          needed.
8696  *  \throw If either \a a1 or \a a2 is NULL.
8697  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8698  */
8699 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8700 {
8701   if(!a1 || !a2)
8702     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8703   int nbOfComp=a1->getNumberOfComponents();
8704   if(nbOfComp!=a2->getNumberOfComponents())
8705     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8706   int nbOfTuple1=a1->getNumberOfTuples();
8707   int nbOfTuple2=a2->getNumberOfTuples();
8708   DataArrayInt *ret=DataArrayInt::New();
8709   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8710   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8711   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8712   ret->copyStringInfoFrom(*a1);
8713   return ret;
8714 }
8715
8716 /*!
8717  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8718  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8719  * the number of component in the result array is same as that of each of given arrays.
8720  * Info on components is copied from the first of the given arrays. Number of components
8721  * in the given arrays must be  the same.
8722  *  \param [in] arr - a sequence of arrays to include in the result array.
8723  *  \return DataArrayInt * - the new instance of DataArrayInt.
8724  *          The caller is to delete this result array using decrRef() as it is no more
8725  *          needed.
8726  *  \throw If all arrays within \a arr are NULL.
8727  *  \throw If getNumberOfComponents() of arrays within \a arr.
8728  */
8729 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8730 {
8731   std::vector<const DataArrayInt *> a;
8732   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8733     if(*it4)
8734       a.push_back(*it4);
8735   if(a.empty())
8736     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8737   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8738   int nbOfComp=(*it)->getNumberOfComponents();
8739   int nbt=(*it++)->getNumberOfTuples();
8740   for(int i=1;it!=a.end();it++,i++)
8741     {
8742       if((*it)->getNumberOfComponents()!=nbOfComp)
8743         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8744       nbt+=(*it)->getNumberOfTuples();
8745     }
8746   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8747   ret->alloc(nbt,nbOfComp);
8748   int *pt=ret->getPointer();
8749   for(it=a.begin();it!=a.end();it++)
8750     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8751   ret->copyStringInfoFrom(*(a[0]));
8752   return ret.retn();
8753 }
8754
8755 /*!
8756  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8757  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8758  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8759  * 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.
8760  * 
8761  * \return DataArrayInt * - a new object to be managed by the caller.
8762  */
8763 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8764 {
8765   int retSz=1;
8766   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8767     {
8768       if(*it4)
8769         {
8770           (*it4)->checkAllocated();
8771           if((*it4)->getNumberOfComponents()!=1)
8772             {
8773               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8774               throw INTERP_KERNEL::Exception(oss.str().c_str());
8775             }
8776           int nbTupl=(*it4)->getNumberOfTuples();
8777           if(nbTupl<1)
8778             {
8779               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8780               throw INTERP_KERNEL::Exception(oss.str().c_str());
8781             }
8782           if((*it4)->front()!=0)
8783             {
8784               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8785               throw INTERP_KERNEL::Exception(oss.str().c_str());
8786             }
8787           retSz+=nbTupl-1;
8788         }
8789       else
8790         {
8791           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8792           throw INTERP_KERNEL::Exception(oss.str().c_str());
8793         }
8794     }
8795   if(arrs.empty())
8796     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8797   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8798   ret->alloc(retSz,1);
8799   int *pt=ret->getPointer(); *pt++=0;
8800   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8801     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8802   ret->copyStringInfoFrom(*(arrs[0]));
8803   return ret.retn();
8804 }
8805
8806 /*!
8807  * Returns the maximal value and its location within \a this one-dimensional array.
8808  *  \param [out] tupleId - index of the tuple holding the maximal value.
8809  *  \return int - the maximal value among all values of \a this array.
8810  *  \throw If \a this->getNumberOfComponents() != 1
8811  *  \throw If \a this->getNumberOfTuples() < 1
8812  */
8813 int DataArrayInt::getMaxValue(int& tupleId) const
8814 {
8815   checkAllocated();
8816   if(getNumberOfComponents()!=1)
8817     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8818   int nbOfTuples=getNumberOfTuples();
8819   if(nbOfTuples<=0)
8820     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8821   const int *vals=getConstPointer();
8822   const int *loc=std::max_element(vals,vals+nbOfTuples);
8823   tupleId=(int)std::distance(vals,loc);
8824   return *loc;
8825 }
8826
8827 /*!
8828  * Returns the maximal value within \a this array that is allowed to have more than
8829  *  one component.
8830  *  \return int - the maximal value among all values of \a this array.
8831  *  \throw If \a this is not allocated.
8832  */
8833 int DataArrayInt::getMaxValueInArray() const
8834 {
8835   checkAllocated();
8836   const int *loc=std::max_element(begin(),end());
8837   return *loc;
8838 }
8839
8840 /*!
8841  * Returns the minimal value and its location within \a this one-dimensional array.
8842  *  \param [out] tupleId - index of the tuple holding the minimal value.
8843  *  \return int - the minimal value among all values of \a this array.
8844  *  \throw If \a this->getNumberOfComponents() != 1
8845  *  \throw If \a this->getNumberOfTuples() < 1
8846  */
8847 int DataArrayInt::getMinValue(int& tupleId) const
8848 {
8849   checkAllocated();
8850   if(getNumberOfComponents()!=1)
8851     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8852   int nbOfTuples=getNumberOfTuples();
8853   if(nbOfTuples<=0)
8854     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8855   const int *vals=getConstPointer();
8856   const int *loc=std::min_element(vals,vals+nbOfTuples);
8857   tupleId=(int)std::distance(vals,loc);
8858   return *loc;
8859 }
8860
8861 /*!
8862  * Returns the minimal value within \a this array that is allowed to have more than
8863  *  one component.
8864  *  \return int - the minimal value among all values of \a this array.
8865  *  \throw If \a this is not allocated.
8866  */
8867 int DataArrayInt::getMinValueInArray() const
8868 {
8869   checkAllocated();
8870   const int *loc=std::min_element(begin(),end());
8871   return *loc;
8872 }
8873
8874 /*!
8875  * Converts every value of \a this array to its absolute value.
8876  *  \throw If \a this is not allocated.
8877  */
8878 void DataArrayInt::abs()
8879 {
8880   checkAllocated();
8881   int *ptr=getPointer();
8882   std::size_t nbOfElems=getNbOfElems();
8883   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8884   declareAsNew();
8885 }
8886
8887 /*!
8888  * Apply a liner function to a given component of \a this array, so that
8889  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8890  *  \param [in] a - the first coefficient of the function.
8891  *  \param [in] b - the second coefficient of the function.
8892  *  \param [in] compoId - the index of component to modify.
8893  *  \throw If \a this is not allocated.
8894  */
8895 void DataArrayInt::applyLin(int a, int b, int compoId)
8896 {
8897   checkAllocated();
8898   int *ptr=getPointer()+compoId;
8899   int nbOfComp=getNumberOfComponents();
8900   int nbOfTuple=getNumberOfTuples();
8901   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8902     *ptr=a*(*ptr)+b;
8903   declareAsNew();
8904 }
8905
8906 /*!
8907  * Apply a liner function to all elements of \a this array, so that
8908  * an element _x_ becomes \f$ a * x + b \f$.
8909  *  \param [in] a - the first coefficient of the function.
8910  *  \param [in] b - the second coefficient of the function.
8911  *  \throw If \a this is not allocated.
8912  */
8913 void DataArrayInt::applyLin(int a, int b)
8914 {
8915   checkAllocated();
8916   int *ptr=getPointer();
8917   std::size_t nbOfElems=getNbOfElems();
8918   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8919     *ptr=a*(*ptr)+b;
8920   declareAsNew();
8921 }
8922
8923 /*!
8924  * Returns a full copy of \a this array except that sign of all elements is reversed.
8925  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8926  *          same number of tuples and component as \a this array.
8927  *          The caller is to delete this result array using decrRef() as it is no more
8928  *          needed.
8929  *  \throw If \a this is not allocated.
8930  */
8931 DataArrayInt *DataArrayInt::negate() const
8932 {
8933   checkAllocated();
8934   DataArrayInt *newArr=DataArrayInt::New();
8935   int nbOfTuples=getNumberOfTuples();
8936   int nbOfComp=getNumberOfComponents();
8937   newArr->alloc(nbOfTuples,nbOfComp);
8938   const int *cptr=getConstPointer();
8939   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8940   newArr->copyStringInfoFrom(*this);
8941   return newArr;
8942 }
8943
8944 /*!
8945  * Modify all elements of \a this array, so that
8946  * an element _x_ becomes \f$ numerator / x \f$.
8947  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8948  *           array, all elements processed before detection of the zero element remain
8949  *           modified.
8950  *  \param [in] numerator - the numerator used to modify array elements.
8951  *  \throw If \a this is not allocated.
8952  *  \throw If there is an element equal to 0 in \a this array.
8953  */
8954 void DataArrayInt::applyInv(int numerator)
8955 {
8956   checkAllocated();
8957   int *ptr=getPointer();
8958   std::size_t nbOfElems=getNbOfElems();
8959   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8960     {
8961       if(*ptr!=0)
8962         {
8963           *ptr=numerator/(*ptr);
8964         }
8965       else
8966         {
8967           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8968           oss << " !";
8969           throw INTERP_KERNEL::Exception(oss.str().c_str());
8970         }
8971     }
8972   declareAsNew();
8973 }
8974
8975 /*!
8976  * Modify all elements of \a this array, so that
8977  * an element _x_ becomes \f$ x / val \f$.
8978  *  \param [in] val - the denominator used to modify array elements.
8979  *  \throw If \a this is not allocated.
8980  *  \throw If \a val == 0.
8981  */
8982 void DataArrayInt::applyDivideBy(int val)
8983 {
8984   if(val==0)
8985     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8986   checkAllocated();
8987   int *ptr=getPointer();
8988   std::size_t nbOfElems=getNbOfElems();
8989   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8990   declareAsNew();
8991 }
8992
8993 /*!
8994  * Modify all elements of \a this array, so that
8995  * an element _x_ becomes  <em> x % val </em>.
8996  *  \param [in] val - the divisor used to modify array elements.
8997  *  \throw If \a this is not allocated.
8998  *  \throw If \a val <= 0.
8999  */
9000 void DataArrayInt::applyModulus(int val)
9001 {
9002   if(val<=0)
9003     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9004   checkAllocated();
9005   int *ptr=getPointer();
9006   std::size_t nbOfElems=getNbOfElems();
9007   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9008   declareAsNew();
9009 }
9010
9011 /*!
9012  * This method works only on data array with one component.
9013  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9014  * this[*id] in [\b vmin,\b vmax)
9015  * 
9016  * \param [in] vmin begin of range. This value is included in range (included).
9017  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9018  * \return a newly allocated data array that the caller should deal with.
9019  */
9020 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9021 {
9022   checkAllocated();
9023   if(getNumberOfComponents()!=1)
9024     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9025   const int *cptr=getConstPointer();
9026   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
9027   int nbOfTuples=getNumberOfTuples();
9028   for(int i=0;i<nbOfTuples;i++,cptr++)
9029     if(*cptr>=vmin && *cptr<vmax)
9030       ret->pushBackSilent(i);
9031   return ret.retn();
9032 }
9033
9034 /*!
9035  * This method works only on data array with one component.
9036  * 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.
9037  * 
9038  * \param [in] vmin begin of range. This value is included in range (included).
9039  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9040  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
9041  */
9042 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9043 {
9044   checkAllocated();
9045   if(getNumberOfComponents()!=1)
9046     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9047   int nbOfTuples=getNumberOfTuples();
9048   bool ret=true;
9049   const int *cptr=getConstPointer();
9050   for(int i=0;i<nbOfTuples;i++,cptr++)
9051     {
9052       if(*cptr>=vmin && *cptr<vmax)
9053         { ret=ret && *cptr==i; }
9054       else
9055         {
9056           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9057           throw INTERP_KERNEL::Exception(oss.str().c_str());
9058         }
9059     }
9060   return ret;
9061 }
9062
9063 /*!
9064  * Modify all elements of \a this array, so that
9065  * an element _x_ becomes <em> val % x </em>.
9066  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9067  *           array, all elements processed before detection of the zero element remain
9068  *           modified.
9069  *  \param [in] val - the divident used to modify array elements.
9070  *  \throw If \a this is not allocated.
9071  *  \throw If there is an element equal to or less than 0 in \a this array.
9072  */
9073 void DataArrayInt::applyRModulus(int val)
9074 {
9075   checkAllocated();
9076   int *ptr=getPointer();
9077   std::size_t nbOfElems=getNbOfElems();
9078   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9079     {
9080       if(*ptr>0)
9081         {
9082           *ptr=val%(*ptr);
9083         }
9084       else
9085         {
9086           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9087           oss << " !";
9088           throw INTERP_KERNEL::Exception(oss.str().c_str());
9089         }
9090     }
9091   declareAsNew();
9092 }
9093
9094 /*!
9095  * Modify all elements of \a this array, so that
9096  * an element _x_ becomes <em> val ^ x </em>.
9097  *  \param [in] val - the value used to apply pow on all array elements.
9098  *  \throw If \a this is not allocated.
9099  *  \throw If \a val < 0.
9100  */
9101 void DataArrayInt::applyPow(int val)
9102 {
9103   checkAllocated();
9104   if(val<0)
9105     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9106   int *ptr=getPointer();
9107   std::size_t nbOfElems=getNbOfElems();
9108   if(val==0)
9109     {
9110       std::fill(ptr,ptr+nbOfElems,1);
9111       return ;
9112     }
9113   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9114     {
9115       int tmp=1;
9116       for(int j=0;j<val;j++)
9117         tmp*=*ptr;
9118       *ptr=tmp;
9119     }
9120   declareAsNew();
9121 }
9122
9123 /*!
9124  * Modify all elements of \a this array, so that
9125  * an element _x_ becomes \f$ val ^ x \f$.
9126  *  \param [in] val - the value used to apply pow on all array elements.
9127  *  \throw If \a this is not allocated.
9128  *  \throw If there is an element < 0 in \a this array.
9129  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9130  *           array, all elements processed before detection of the zero element remain
9131  *           modified.
9132  */
9133 void DataArrayInt::applyRPow(int val)
9134 {
9135   checkAllocated();
9136   int *ptr=getPointer();
9137   std::size_t nbOfElems=getNbOfElems();
9138   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9139     {
9140       if(*ptr>=0)
9141         {
9142           int tmp=1;
9143           for(int j=0;j<*ptr;j++)
9144             tmp*=val;
9145           *ptr=tmp;
9146         }
9147       else
9148         {
9149           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9150           oss << " !";
9151           throw INTERP_KERNEL::Exception(oss.str().c_str());
9152         }
9153     }
9154   declareAsNew();
9155 }
9156
9157 /*!
9158  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9159  * of components in the result array is a sum of the number of components of given arrays
9160  * and (2) the number of tuples in the result array is same as that of each of given
9161  * arrays. In other words the i-th tuple of result array includes all components of
9162  * i-th tuples of all given arrays.
9163  * Number of tuples in the given arrays must be the same.
9164  *  \param [in] a1 - an array to include in the result array.
9165  *  \param [in] a2 - another array to include in the result array.
9166  *  \return DataArrayInt * - the new instance of DataArrayInt.
9167  *          The caller is to delete this result array using decrRef() as it is no more
9168  *          needed.
9169  *  \throw If both \a a1 and \a a2 are NULL.
9170  *  \throw If any given array is not allocated.
9171  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9172  */
9173 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9174 {
9175   std::vector<const DataArrayInt *> arr(2);
9176   arr[0]=a1; arr[1]=a2;
9177   return Meld(arr);
9178 }
9179
9180 /*!
9181  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9182  * of components in the result array is a sum of the number of components of given arrays
9183  * and (2) the number of tuples in the result array is same as that of each of given
9184  * arrays. In other words the i-th tuple of result array includes all components of
9185  * i-th tuples of all given arrays.
9186  * Number of tuples in the given arrays must be  the same.
9187  *  \param [in] arr - a sequence of arrays to include in the result array.
9188  *  \return DataArrayInt * - the new instance of DataArrayInt.
9189  *          The caller is to delete this result array using decrRef() as it is no more
9190  *          needed.
9191  *  \throw If all arrays within \a arr are NULL.
9192  *  \throw If any given array is not allocated.
9193  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9194  */
9195 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9196 {
9197   std::vector<const DataArrayInt *> a;
9198   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9199     if(*it4)
9200       a.push_back(*it4);
9201   if(a.empty())
9202     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9203   std::vector<const DataArrayInt *>::const_iterator it;
9204   for(it=a.begin();it!=a.end();it++)
9205     (*it)->checkAllocated();
9206   it=a.begin();
9207   int nbOfTuples=(*it)->getNumberOfTuples();
9208   std::vector<int> nbc(a.size());
9209   std::vector<const int *> pts(a.size());
9210   nbc[0]=(*it)->getNumberOfComponents();
9211   pts[0]=(*it++)->getConstPointer();
9212   for(int i=1;it!=a.end();it++,i++)
9213     {
9214       if(nbOfTuples!=(*it)->getNumberOfTuples())
9215         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9216       nbc[i]=(*it)->getNumberOfComponents();
9217       pts[i]=(*it)->getConstPointer();
9218     }
9219   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9220   DataArrayInt *ret=DataArrayInt::New();
9221   ret->alloc(nbOfTuples,totalNbOfComp);
9222   int *retPtr=ret->getPointer();
9223   for(int i=0;i<nbOfTuples;i++)
9224     for(int j=0;j<(int)a.size();j++)
9225       {
9226         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9227         pts[j]+=nbc[j];
9228       }
9229   int k=0;
9230   for(int i=0;i<(int)a.size();i++)
9231     for(int j=0;j<nbc[i];j++,k++)
9232       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9233   return ret;
9234 }
9235
9236 /*!
9237  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9238  * The i-th item of the result array is an ID of a set of elements belonging to a
9239  * unique set of groups, which the i-th element is a part of. This set of elements
9240  * belonging to a unique set of groups is called \a family, so the result array contains
9241  * IDs of families each element belongs to.
9242  *
9243  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9244  * then there are 3 families:
9245  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9246  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9247  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9248  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9249  * stands for the element #3 which is in none of groups.
9250  *
9251  *  \param [in] groups - sequence of groups of element IDs.
9252  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9253  *         in \a groups.
9254  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9255  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9256  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9257  *         delete this array using decrRef() as it is no more needed.
9258  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9259  */
9260 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9261 {
9262   std::vector<const DataArrayInt *> groups2;
9263   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9264     if(*it4)
9265       groups2.push_back(*it4);
9266   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9267   ret->alloc(newNb,1);
9268   int *retPtr=ret->getPointer();
9269   std::fill(retPtr,retPtr+newNb,0);
9270   int fid=1;
9271   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9272     {
9273       const int *ptr=(*iter)->getConstPointer();
9274       std::size_t nbOfElem=(*iter)->getNbOfElems();
9275       int sfid=fid;
9276       for(int j=0;j<sfid;j++)
9277         {
9278           bool found=false;
9279           for(std::size_t i=0;i<nbOfElem;i++)
9280             {
9281               if(ptr[i]>=0 && ptr[i]<newNb)
9282                 {
9283                   if(retPtr[ptr[i]]==j)
9284                     {
9285                       retPtr[ptr[i]]=fid;
9286                       found=true;
9287                     }
9288                 }
9289               else
9290                 {
9291                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9292                   oss << ") !";
9293                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9294                 }
9295             }
9296           if(found)
9297             fid++;
9298         }
9299     }
9300   fidsOfGroups.clear();
9301   fidsOfGroups.resize(groups2.size());
9302   int grId=0;
9303   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9304     {
9305       std::set<int> tmp;
9306       const int *ptr=(*iter)->getConstPointer();
9307       std::size_t nbOfElem=(*iter)->getNbOfElems();
9308       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9309         tmp.insert(retPtr[*p]);
9310       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9311     }
9312   return ret.retn();
9313 }
9314
9315 /*!
9316  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9317  * arrays. The result array does not contain any duplicates and its values
9318  * are sorted in ascending order.
9319  *  \param [in] arr - sequence of DataArrayInt's to unite.
9320  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9321  *         array using decrRef() as it is no more needed.
9322  *  \throw If any \a arr[i] is not allocated.
9323  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9324  */
9325 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9326 {
9327   std::vector<const DataArrayInt *> a;
9328   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9329     if(*it4)
9330       a.push_back(*it4);
9331   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9332     {
9333       (*it)->checkAllocated();
9334       if((*it)->getNumberOfComponents()!=1)
9335         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9336     }
9337   //
9338   std::set<int> r;
9339   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9340     {
9341       const int *pt=(*it)->getConstPointer();
9342       int nbOfTuples=(*it)->getNumberOfTuples();
9343       r.insert(pt,pt+nbOfTuples);
9344     }
9345   DataArrayInt *ret=DataArrayInt::New();
9346   ret->alloc((int)r.size(),1);
9347   std::copy(r.begin(),r.end(),ret->getPointer());
9348   return ret;
9349 }
9350
9351 /*!
9352  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9353  * arrays. The result array does not contain any duplicates and its values
9354  * are sorted in ascending order.
9355  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9356  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9357  *         array using decrRef() as it is no more needed.
9358  *  \throw If any \a arr[i] is not allocated.
9359  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9360  */
9361 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9362 {
9363   std::vector<const DataArrayInt *> a;
9364   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9365     if(*it4)
9366       a.push_back(*it4);
9367   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9368     {
9369       (*it)->checkAllocated();
9370       if((*it)->getNumberOfComponents()!=1)
9371         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9372     }
9373   //
9374   std::set<int> r;
9375   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9376     {
9377       const int *pt=(*it)->getConstPointer();
9378       int nbOfTuples=(*it)->getNumberOfTuples();
9379       std::set<int> s1(pt,pt+nbOfTuples);
9380       if(it!=a.begin())
9381         {
9382           std::set<int> r2;
9383           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9384           r=r2;
9385         }
9386       else
9387         r=s1;
9388     }
9389   DataArrayInt *ret=DataArrayInt::New();
9390   ret->alloc((int)r.size(),1);
9391   std::copy(r.begin(),r.end(),ret->getPointer());
9392   return ret;
9393 }
9394
9395 /*!
9396  * Returns a new DataArrayInt which contains a complement of elements of \a this
9397  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9398  * \a nbOfElement) not present in \a this array.
9399  *  \param [in] nbOfElement - maximal size of the result array.
9400  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9401  *         array using decrRef() as it is no more needed.
9402  *  \throw If \a this is not allocated.
9403  *  \throw If \a this->getNumberOfComponents() != 1.
9404  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9405  *         nbOfElement ).
9406  */
9407 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9408 {
9409    checkAllocated();
9410    if(getNumberOfComponents()!=1)
9411      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9412    std::vector<bool> tmp(nbOfElement);
9413    const int *pt=getConstPointer();
9414    int nbOfTuples=getNumberOfTuples();
9415    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9416      if(*w>=0 && *w<nbOfElement)
9417        tmp[*w]=true;
9418      else
9419        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9420    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9421    DataArrayInt *ret=DataArrayInt::New();
9422    ret->alloc(nbOfRetVal,1);
9423    int j=0;
9424    int *retPtr=ret->getPointer();
9425    for(int i=0;i<nbOfElement;i++)
9426      if(!tmp[i])
9427        retPtr[j++]=i;
9428    return ret;
9429 }
9430
9431 /*!
9432  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9433  * from an \a other one-dimensional array.
9434  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9435  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9436  *         caller is to delete this array using decrRef() as it is no more needed.
9437  *  \throw If \a other is NULL.
9438  *  \throw If \a other is not allocated.
9439  *  \throw If \a other->getNumberOfComponents() != 1.
9440  *  \throw If \a this is not allocated.
9441  *  \throw If \a this->getNumberOfComponents() != 1.
9442  *  \sa DataArrayInt::buildSubstractionOptimized()
9443  */
9444 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9445 {
9446   if(!other)
9447     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9448   checkAllocated();
9449   other->checkAllocated();
9450   if(getNumberOfComponents()!=1)
9451      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9452   if(other->getNumberOfComponents()!=1)
9453      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9454   const int *pt=getConstPointer();
9455   int nbOfTuples=getNumberOfTuples();
9456   std::set<int> s1(pt,pt+nbOfTuples);
9457   pt=other->getConstPointer();
9458   nbOfTuples=other->getNumberOfTuples();
9459   std::set<int> s2(pt,pt+nbOfTuples);
9460   std::vector<int> r;
9461   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9462   DataArrayInt *ret=DataArrayInt::New();
9463   ret->alloc((int)r.size(),1);
9464   std::copy(r.begin(),r.end(),ret->getPointer());
9465   return ret;
9466 }
9467
9468 /*!
9469  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9470  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9471  * 
9472  * \param [in] other an array with one component and expected to be sorted ascendingly.
9473  * \ret list of ids in \a this but not in \a other.
9474  * \sa DataArrayInt::buildSubstraction
9475  */
9476 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9477 {
9478   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9479   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9480   checkAllocated(); other->checkAllocated();
9481   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9482   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9483   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9484   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9485   for(;work1!=pt1End;work1++)
9486     {
9487       if(work2!=pt2End && *work1==*work2)
9488         work2++;
9489       else
9490         ret->pushBackSilent(*work1);
9491     }
9492   return ret.retn();
9493 }
9494
9495
9496 /*!
9497  * Returns a new DataArrayInt which contains all elements of \a this and a given
9498  * one-dimensional arrays. The result array does not contain any duplicates
9499  * and its values are sorted in ascending order.
9500  *  \param [in] other - an array to unite with \a this one.
9501  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9502  *         array using decrRef() as it is no more needed.
9503  *  \throw If \a this or \a other is not allocated.
9504  *  \throw If \a this->getNumberOfComponents() != 1.
9505  *  \throw If \a other->getNumberOfComponents() != 1.
9506  */
9507 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9508 {
9509   std::vector<const DataArrayInt *>arrs(2);
9510   arrs[0]=this; arrs[1]=other;
9511   return BuildUnion(arrs);
9512 }
9513
9514
9515 /*!
9516  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9517  * one-dimensional arrays. The result array does not contain any duplicates
9518  * and its values are sorted in ascending order.
9519  *  \param [in] other - an array to intersect with \a this one.
9520  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9521  *         array using decrRef() as it is no more needed.
9522  *  \throw If \a this or \a other is not allocated.
9523  *  \throw If \a this->getNumberOfComponents() != 1.
9524  *  \throw If \a other->getNumberOfComponents() != 1.
9525  */
9526 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9527 {
9528   std::vector<const DataArrayInt *>arrs(2);
9529   arrs[0]=this; arrs[1]=other;
9530   return BuildIntersection(arrs);
9531 }
9532
9533 /*!
9534  * This method can be applied on allocated with one component DataArrayInt instance.
9535  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9536  * 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]
9537  * 
9538  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9539  * \throw if \a this is not allocated or if \a this has not exactly one component.
9540  */
9541 DataArrayInt *DataArrayInt::buildUnique() const
9542 {
9543   checkAllocated();
9544   if(getNumberOfComponents()!=1)
9545      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9546   int nbOfTuples=getNumberOfTuples();
9547   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9548   int *data=tmp->getPointer();
9549   int *last=std::unique(data,data+nbOfTuples);
9550   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9551   ret->alloc(std::distance(data,last),1);
9552   std::copy(data,last,ret->getPointer());
9553   return ret.retn();
9554 }
9555
9556 /*!
9557  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9558  * "index" array. Such "index" array is returned for example by 
9559  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9560  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9561  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9562  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9563  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9564  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9565  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9566  *          The caller is to delete this array using decrRef() as it is no more needed. 
9567  *  \throw If \a this is not allocated.
9568  *  \throw If \a this->getNumberOfComponents() != 1.
9569  *  \throw If \a this->getNumberOfTuples() < 2.
9570  *
9571  *  \b Example: <br> 
9572  *         - this contains [1,3,6,7,7,9,15]
9573  *         - result array contains [2,3,1,0,2,6],
9574  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9575  *
9576  * \sa DataArrayInt::computeOffsets2
9577  */
9578 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9579 {
9580   checkAllocated();
9581   if(getNumberOfComponents()!=1)
9582      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9583   int nbOfTuples=getNumberOfTuples();
9584   if(nbOfTuples<2)
9585     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9586   const int *ptr=getConstPointer();
9587   DataArrayInt *ret=DataArrayInt::New();
9588   ret->alloc(nbOfTuples-1,1);
9589   int *out=ret->getPointer();
9590   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9591   return ret;
9592 }
9593
9594 /*!
9595  * Modifies \a this one-dimensional array so that value of each element \a x
9596  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9597  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9598  * and components remains the same.<br>
9599  * This method is useful for allToAllV in MPI with contiguous policy. This method
9600  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9601  * this one.
9602  *  \throw If \a this is not allocated.
9603  *  \throw If \a this->getNumberOfComponents() != 1.
9604  *
9605  *  \b Example: <br>
9606  *          - Before \a this contains [3,5,1,2,0,8]
9607  *          - After \a this contains  [0,3,8,9,11,11]<br>
9608  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9609  *          array is retained and thus there is no space to store the last element.
9610  */
9611 void DataArrayInt::computeOffsets()
9612 {
9613   checkAllocated();
9614   if(getNumberOfComponents()!=1)
9615      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9616   int nbOfTuples=getNumberOfTuples();
9617   if(nbOfTuples==0)
9618     return ;
9619   int *work=getPointer();
9620   int tmp=work[0];
9621   work[0]=0;
9622   for(int i=1;i<nbOfTuples;i++)
9623     {
9624       int tmp2=work[i];
9625       work[i]=work[i-1]+tmp;
9626       tmp=tmp2;
9627     }
9628   declareAsNew();
9629 }
9630
9631
9632 /*!
9633  * Modifies \a this one-dimensional array so that value of each element \a x
9634  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9635  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9636  * components remains the same and number of tuples is inceamented by one.<br>
9637  * This method is useful for allToAllV in MPI with contiguous policy. This method
9638  * differs from computeOffsets() in that the number of tuples is changed by this one.
9639  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9640  *  \throw If \a this is not allocated.
9641  *  \throw If \a this->getNumberOfComponents() != 1.
9642  *
9643  *  \b Example: <br>
9644  *          - Before \a this contains [3,5,1,2,0,8]
9645  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9646  * \sa DataArrayInt::deltaShiftIndex
9647  */
9648 void DataArrayInt::computeOffsets2()
9649 {
9650   checkAllocated();
9651   if(getNumberOfComponents()!=1)
9652     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9653   int nbOfTuples=getNumberOfTuples();
9654   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9655   if(nbOfTuples==0)
9656     return ;
9657   const int *work=getConstPointer();
9658   ret[0]=0;
9659   for(int i=0;i<nbOfTuples;i++)
9660     ret[i+1]=work[i]+ret[i];
9661   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9662   declareAsNew();
9663 }
9664
9665 /*!
9666  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9667  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9668  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9669  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9670  * filling completely one of the ranges in \a this.
9671  *
9672  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9673  * \param [out] rangeIdsFetched the range ids fetched
9674  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9675  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9676  *
9677  * \sa DataArrayInt::computeOffsets2
9678  *
9679  *  \b Example: <br>
9680  *          - \a this : [0,3,7,9,15,18]
9681  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9682  *          - \a rangeIdsFetched result array: [0,2,4]
9683  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9684  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9685  * <br>
9686  */
9687 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9688 {
9689   if(!listOfIds)
9690     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9691   listOfIds->checkAllocated(); checkAllocated();
9692   if(listOfIds->getNumberOfComponents()!=1)
9693     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9694   if(getNumberOfComponents()!=1)
9695     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9696   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9697   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9698   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9699   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9700   while(tupPtr!=tupEnd && offPtr!=offEnd)
9701     {
9702       if(*tupPtr==*offPtr)
9703         {
9704           int i=offPtr[0];
9705           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9706           if(i==offPtr[1])
9707             {
9708               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9709               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9710               offPtr++;
9711             }
9712         }
9713       else
9714         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9715     }
9716   rangeIdsFetched=ret0.retn();
9717   idsInInputListThatFetch=ret1.retn();
9718 }
9719
9720 /*!
9721  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9722  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9723  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9724  * beginning within the "iota" array. And \a this is a one-dimensional array
9725  * considered as a selector of groups described by \a offsets to include into the result array.
9726  *  \throw If \a offsets is NULL.
9727  *  \throw If \a offsets is not allocated.
9728  *  \throw If \a offsets->getNumberOfComponents() != 1.
9729  *  \throw If \a offsets is not monotonically increasing.
9730  *  \throw If \a this is not allocated.
9731  *  \throw If \a this->getNumberOfComponents() != 1.
9732  *  \throw If any element of \a this is not a valid index for \a offsets array.
9733  *
9734  *  \b Example: <br>
9735  *          - \a this: [0,2,3]
9736  *          - \a offsets: [0,3,6,10,14,20]
9737  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9738  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9739  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9740  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9741  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9742  */
9743 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
9744 {
9745   if(!offsets)
9746     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9747   checkAllocated();
9748   if(getNumberOfComponents()!=1)
9749      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9750   offsets->checkAllocated();
9751   if(offsets->getNumberOfComponents()!=1)
9752      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9753   int othNbTuples=offsets->getNumberOfTuples()-1;
9754   int nbOfTuples=getNumberOfTuples();
9755   int retNbOftuples=0;
9756   const int *work=getConstPointer();
9757   const int *offPtr=offsets->getConstPointer();
9758   for(int i=0;i<nbOfTuples;i++)
9759     {
9760       int val=work[i];
9761       if(val>=0 && val<othNbTuples)
9762         {
9763           int delta=offPtr[val+1]-offPtr[val];
9764           if(delta>=0)
9765             retNbOftuples+=delta;
9766           else
9767             {
9768               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9769               throw INTERP_KERNEL::Exception(oss.str().c_str());
9770             }
9771         }
9772       else
9773         {
9774           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9775           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9776           throw INTERP_KERNEL::Exception(oss.str().c_str());
9777         }
9778     }
9779   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9780   ret->alloc(retNbOftuples,1);
9781   int *retPtr=ret->getPointer();
9782   for(int i=0;i<nbOfTuples;i++)
9783     {
9784       int val=work[i];
9785       int start=offPtr[val];
9786       int off=offPtr[val+1]-start;
9787       for(int j=0;j<off;j++,retPtr++)
9788         *retPtr=start+j;
9789     }
9790   return ret.retn();
9791 }
9792
9793 /*!
9794  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9795  * scaled array (monotonically increasing).
9796 from that of \a this and \a
9797  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9798  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9799  * beginning within the "iota" array. And \a this is a one-dimensional array
9800  * considered as a selector of groups described by \a offsets to include into the result array.
9801  *  \throw If \a  is NULL.
9802  *  \throw If \a this is not allocated.
9803  *  \throw If \a this->getNumberOfComponents() != 1.
9804  *  \throw If \a this->getNumberOfTuples() == 0.
9805  *  \throw If \a this is not monotonically increasing.
9806  *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
9807  *
9808  *  \b Example: <br>
9809  *          - \a bg , \a end and \a step : (0,5,2)
9810  *          - \a this: [0,3,6,10,14,20]
9811  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9812  */
9813 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const
9814 {
9815   if(!isAllocated())
9816     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9817   if(getNumberOfComponents()!=1)
9818     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9819   int nbOfTuples(getNumberOfTuples());
9820   if(nbOfTuples==0)
9821     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9822   const int *ids(begin());
9823   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9824   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9825     {
9826       if(pos>=0 && pos<nbOfTuples-1)
9827         {
9828           int delta(ids[pos+1]-ids[pos]);
9829           sz+=delta;
9830           if(delta<0)
9831             {
9832               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9833               throw INTERP_KERNEL::Exception(oss.str().c_str());
9834             }          
9835         }
9836       else
9837         {
9838           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9839           throw INTERP_KERNEL::Exception(oss.str().c_str());
9840         }
9841     }
9842   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9843   int *retPtr(ret->getPointer());
9844   pos=bg;
9845   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9846     {
9847       int delta(ids[pos+1]-ids[pos]);
9848       for(int j=0;j<delta;j++,retPtr++)
9849         *retPtr=pos;
9850     }
9851   return ret.retn();
9852 }
9853
9854 /*!
9855  * 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.
9856  * 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
9857  * in tuple **i** of returned DataArrayInt.
9858  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9859  *
9860  * 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)]
9861  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9862  * 
9863  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9864  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9865  * \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
9866  *        is thrown if no ranges in \a ranges contains value in \a this.
9867  * 
9868  * \sa DataArrayInt::findIdInRangeForEachTuple
9869  */
9870 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
9871 {
9872   if(!ranges)
9873     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9874   if(ranges->getNumberOfComponents()!=2)
9875     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9876   checkAllocated();
9877   if(getNumberOfComponents()!=1)
9878     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9879   int nbTuples=getNumberOfTuples();
9880   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9881   int nbOfRanges=ranges->getNumberOfTuples();
9882   const int *rangesPtr=ranges->getConstPointer();
9883   int *retPtr=ret->getPointer();
9884   const int *inPtr=getConstPointer();
9885   for(int i=0;i<nbTuples;i++,retPtr++)
9886     {
9887       int val=inPtr[i];
9888       bool found=false;
9889       for(int j=0;j<nbOfRanges && !found;j++)
9890         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9891           { *retPtr=j; found=true; }
9892       if(found)
9893         continue;
9894       else
9895         {
9896           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9897           throw INTERP_KERNEL::Exception(oss.str().c_str());
9898         }
9899     }
9900   return ret.retn();
9901 }
9902
9903 /*!
9904  * 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.
9905  * 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
9906  * in tuple **i** of returned DataArrayInt.
9907  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9908  *
9909  * 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)]
9910  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9911  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9912  * 
9913  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9914  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9915  * \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
9916  *        is thrown if no ranges in \a ranges contains value in \a this.
9917  * \sa DataArrayInt::findRangeIdForEachTuple
9918  */
9919 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
9920 {
9921   if(!ranges)
9922     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9923   if(ranges->getNumberOfComponents()!=2)
9924     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9925   checkAllocated();
9926   if(getNumberOfComponents()!=1)
9927     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9928   int nbTuples=getNumberOfTuples();
9929   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9930   int nbOfRanges=ranges->getNumberOfTuples();
9931   const int *rangesPtr=ranges->getConstPointer();
9932   int *retPtr=ret->getPointer();
9933   const int *inPtr=getConstPointer();
9934   for(int i=0;i<nbTuples;i++,retPtr++)
9935     {
9936       int val=inPtr[i];
9937       bool found=false;
9938       for(int j=0;j<nbOfRanges && !found;j++)
9939         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9940           { *retPtr=val-rangesPtr[2*j]; found=true; }
9941       if(found)
9942         continue;
9943       else
9944         {
9945           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9946           throw INTERP_KERNEL::Exception(oss.str().c_str());
9947         }
9948     }
9949   return ret.retn();
9950 }
9951
9952 /*!
9953  * 
9954  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9955  *             \a nbTimes  should be at least equal to 1.
9956  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9957  * \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.
9958  */
9959 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
9960 {
9961   checkAllocated();
9962   if(getNumberOfComponents()!=1)
9963     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9964   if(nbTimes<1)
9965     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9966   int nbTuples=getNumberOfTuples();
9967   const int *inPtr=getConstPointer();
9968   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9969   int *retPtr=ret->getPointer();
9970   for(int i=0;i<nbTuples;i++,inPtr++)
9971     {
9972       int val=*inPtr;
9973       for(int j=0;j<nbTimes;j++,retPtr++)
9974         *retPtr=val;
9975     }
9976   ret->copyStringInfoFrom(*this);
9977   return ret.retn();
9978 }
9979
9980 /*!
9981  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9982  * But the number of components can be different from one.
9983  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9984  */
9985 DataArrayInt *DataArrayInt::getDifferentValues() const
9986 {
9987   checkAllocated();
9988   std::set<int> ret;
9989   ret.insert(begin(),end());
9990   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9991   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9992   return ret2.retn();
9993 }
9994
9995 /*!
9996  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9997  * them it tells which tuple id have this id.
9998  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9999  * This method returns two arrays having same size.
10000  * 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.
10001  * 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]]
10002  */
10003 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10004 {
10005   checkAllocated();
10006   if(getNumberOfComponents()!=1)
10007     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10008   int id=0;
10009   std::map<int,int> m,m2,m3;
10010   for(const int *w=begin();w!=end();w++)
10011     m[*w]++;
10012   differentIds.resize(m.size());
10013   std::vector<DataArrayInt *> ret(m.size());
10014   std::vector<int *> retPtr(m.size());
10015   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10016     {
10017       m2[(*it).first]=id;
10018       ret[id]=DataArrayInt::New();
10019       ret[id]->alloc((*it).second,1);
10020       retPtr[id]=ret[id]->getPointer();
10021       differentIds[id]=(*it).first;
10022     }
10023   id=0;
10024   for(const int *w=begin();w!=end();w++,id++)
10025     {
10026       retPtr[m2[*w]][m3[*w]++]=id;
10027     }
10028   return ret;
10029 }
10030
10031 /*!
10032  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10033  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10034  *
10035  * \param [in] nbOfSlices - number of slices expected.
10036  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10037  * 
10038  * \sa DataArray::GetSlice
10039  * \throw If \a this is not allocated or not with exactly one component.
10040  * \throw If an element in \a this if < 0.
10041  */
10042 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10043 {
10044   if(!isAllocated() || getNumberOfComponents()!=1)
10045     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10046   if(nbOfSlices<=0)
10047     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10048   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10049   int sumPerSlc(sum/nbOfSlices),pos(0);
10050   const int *w(begin());
10051   std::vector< std::pair<int,int> > ret(nbOfSlices);
10052   for(int i=0;i<nbOfSlices;i++)
10053     {
10054       std::pair<int,int> p(pos,-1);
10055       int locSum(0);
10056       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10057       if(i!=nbOfSlices-1)
10058         p.second=pos;
10059       else
10060         p.second=nbOfTuples;
10061       ret[i]=p;
10062     }
10063   return ret;
10064 }
10065
10066 /*!
10067  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10068  * valid cases.
10069  * 1.  The arrays have same number of tuples and components. Then each value of
10070  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10071  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10072  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10073  *   component. Then
10074  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10075  * 3.  The arrays have same number of components and one array, say _a2_, has one
10076  *   tuple. Then
10077  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10078  *
10079  * Info on components is copied either from the first array (in the first case) or from
10080  * the array with maximal number of elements (getNbOfElems()).
10081  *  \param [in] a1 - an array to sum up.
10082  *  \param [in] a2 - another array to sum up.
10083  *  \return DataArrayInt * - the new instance of DataArrayInt.
10084  *          The caller is to delete this result array using decrRef() as it is no more
10085  *          needed.
10086  *  \throw If either \a a1 or \a a2 is NULL.
10087  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10088  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10089  *         none of them has number of tuples or components equal to 1.
10090  */
10091 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10092 {
10093   if(!a1 || !a2)
10094     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10095   int nbOfTuple=a1->getNumberOfTuples();
10096   int nbOfTuple2=a2->getNumberOfTuples();
10097   int nbOfComp=a1->getNumberOfComponents();
10098   int nbOfComp2=a2->getNumberOfComponents();
10099   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10100   if(nbOfTuple==nbOfTuple2)
10101     {
10102       if(nbOfComp==nbOfComp2)
10103         {
10104           ret=DataArrayInt::New();
10105           ret->alloc(nbOfTuple,nbOfComp);
10106           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10107           ret->copyStringInfoFrom(*a1);
10108         }
10109       else
10110         {
10111           int nbOfCompMin,nbOfCompMax;
10112           const DataArrayInt *aMin, *aMax;
10113           if(nbOfComp>nbOfComp2)
10114             {
10115               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10116               aMin=a2; aMax=a1;
10117             }
10118           else
10119             {
10120               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10121               aMin=a1; aMax=a2;
10122             }
10123           if(nbOfCompMin==1)
10124             {
10125               ret=DataArrayInt::New();
10126               ret->alloc(nbOfTuple,nbOfCompMax);
10127               const int *aMinPtr=aMin->getConstPointer();
10128               const int *aMaxPtr=aMax->getConstPointer();
10129               int *res=ret->getPointer();
10130               for(int i=0;i<nbOfTuple;i++)
10131                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10132               ret->copyStringInfoFrom(*aMax);
10133             }
10134           else
10135             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10136         }
10137     }
10138   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10139     {
10140       if(nbOfComp==nbOfComp2)
10141         {
10142           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10143           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10144           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10145           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10146           ret=DataArrayInt::New();
10147           ret->alloc(nbOfTupleMax,nbOfComp);
10148           int *res=ret->getPointer();
10149           for(int i=0;i<nbOfTupleMax;i++)
10150             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10151           ret->copyStringInfoFrom(*aMax);
10152         }
10153       else
10154         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10155     }
10156   else
10157     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10158   return ret.retn();
10159 }
10160
10161 /*!
10162  * Adds values of another DataArrayInt to values of \a this one. There are 3
10163  * valid cases.
10164  * 1.  The arrays have same number of tuples and components. Then each value of
10165  *   \a other array is added to the corresponding value of \a this array, i.e.:
10166  *   _a_ [ i, j ] += _other_ [ i, j ].
10167  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10168  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10169  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10170  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10171  *
10172  *  \param [in] other - an array to add to \a this one.
10173  *  \throw If \a other is NULL.
10174  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10175  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10176  *         \a other has number of both tuples and components not equal to 1.
10177  */
10178 void DataArrayInt::addEqual(const DataArrayInt *other)
10179 {
10180   if(!other)
10181     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10182   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10183   checkAllocated(); other->checkAllocated();
10184   int nbOfTuple=getNumberOfTuples();
10185   int nbOfTuple2=other->getNumberOfTuples();
10186   int nbOfComp=getNumberOfComponents();
10187   int nbOfComp2=other->getNumberOfComponents();
10188   if(nbOfTuple==nbOfTuple2)
10189     {
10190       if(nbOfComp==nbOfComp2)
10191         {
10192           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10193         }
10194       else if(nbOfComp2==1)
10195         {
10196           int *ptr=getPointer();
10197           const int *ptrc=other->getConstPointer();
10198           for(int i=0;i<nbOfTuple;i++)
10199             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10200         }
10201       else
10202         throw INTERP_KERNEL::Exception(msg);
10203     }
10204   else if(nbOfTuple2==1)
10205     {
10206       if(nbOfComp2==nbOfComp)
10207         {
10208           int *ptr=getPointer();
10209           const int *ptrc=other->getConstPointer();
10210           for(int i=0;i<nbOfTuple;i++)
10211             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10212         }
10213       else
10214         throw INTERP_KERNEL::Exception(msg);
10215     }
10216   else
10217     throw INTERP_KERNEL::Exception(msg);
10218   declareAsNew();
10219 }
10220
10221 /*!
10222  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10223  * valid cases.
10224  * 1.  The arrays have same number of tuples and components. Then each value of
10225  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10226  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10227  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10228  *   component. Then
10229  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10230  * 3.  The arrays have same number of components and one array, say _a2_, has one
10231  *   tuple. Then
10232  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10233  *
10234  * Info on components is copied either from the first array (in the first case) or from
10235  * the array with maximal number of elements (getNbOfElems()).
10236  *  \param [in] a1 - an array to subtract from.
10237  *  \param [in] a2 - an array to subtract.
10238  *  \return DataArrayInt * - the new instance of DataArrayInt.
10239  *          The caller is to delete this result array using decrRef() as it is no more
10240  *          needed.
10241  *  \throw If either \a a1 or \a a2 is NULL.
10242  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10243  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10244  *         none of them has number of tuples or components equal to 1.
10245  */
10246 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10247 {
10248   if(!a1 || !a2)
10249     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10250   int nbOfTuple1=a1->getNumberOfTuples();
10251   int nbOfTuple2=a2->getNumberOfTuples();
10252   int nbOfComp1=a1->getNumberOfComponents();
10253   int nbOfComp2=a2->getNumberOfComponents();
10254   if(nbOfTuple2==nbOfTuple1)
10255     {
10256       if(nbOfComp1==nbOfComp2)
10257         {
10258           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10259           ret->alloc(nbOfTuple2,nbOfComp1);
10260           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10261           ret->copyStringInfoFrom(*a1);
10262           return ret.retn();
10263         }
10264       else if(nbOfComp2==1)
10265         {
10266           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10267           ret->alloc(nbOfTuple1,nbOfComp1);
10268           const int *a2Ptr=a2->getConstPointer();
10269           const int *a1Ptr=a1->getConstPointer();
10270           int *res=ret->getPointer();
10271           for(int i=0;i<nbOfTuple1;i++)
10272             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10273           ret->copyStringInfoFrom(*a1);
10274           return ret.retn();
10275         }
10276       else
10277         {
10278           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10279           return 0;
10280         }
10281     }
10282   else if(nbOfTuple2==1)
10283     {
10284       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10285       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10286       ret->alloc(nbOfTuple1,nbOfComp1);
10287       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10288       int *pt=ret->getPointer();
10289       for(int i=0;i<nbOfTuple1;i++)
10290         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10291       ret->copyStringInfoFrom(*a1);
10292       return ret.retn();
10293     }
10294   else
10295     {
10296       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10297       return 0;
10298     }
10299 }
10300
10301 /*!
10302  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10303  * valid cases.
10304  * 1.  The arrays have same number of tuples and components. Then each value of
10305  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10306  *   _a_ [ i, j ] -= _other_ [ i, j ].
10307  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10308  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10309  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10310  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10311  *
10312  *  \param [in] other - an array to subtract from \a this one.
10313  *  \throw If \a other is NULL.
10314  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10315  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10316  *         \a other has number of both tuples and components not equal to 1.
10317  */
10318 void DataArrayInt::substractEqual(const DataArrayInt *other)
10319 {
10320   if(!other)
10321     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10322   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10323   checkAllocated(); other->checkAllocated();
10324   int nbOfTuple=getNumberOfTuples();
10325   int nbOfTuple2=other->getNumberOfTuples();
10326   int nbOfComp=getNumberOfComponents();
10327   int nbOfComp2=other->getNumberOfComponents();
10328   if(nbOfTuple==nbOfTuple2)
10329     {
10330       if(nbOfComp==nbOfComp2)
10331         {
10332           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10333         }
10334       else if(nbOfComp2==1)
10335         {
10336           int *ptr=getPointer();
10337           const int *ptrc=other->getConstPointer();
10338           for(int i=0;i<nbOfTuple;i++)
10339             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10340         }
10341       else
10342         throw INTERP_KERNEL::Exception(msg);
10343     }
10344   else if(nbOfTuple2==1)
10345     {
10346       int *ptr=getPointer();
10347       const int *ptrc=other->getConstPointer();
10348       for(int i=0;i<nbOfTuple;i++)
10349         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10350     }
10351   else
10352     throw INTERP_KERNEL::Exception(msg);
10353   declareAsNew();
10354 }
10355
10356 /*!
10357  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10358  * valid cases.
10359  * 1.  The arrays have same number of tuples and components. Then each value of
10360  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10361  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10362  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10363  *   component. Then
10364  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10365  * 3.  The arrays have same number of components and one array, say _a2_, has one
10366  *   tuple. Then
10367  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10368  *
10369  * Info on components is copied either from the first array (in the first case) or from
10370  * the array with maximal number of elements (getNbOfElems()).
10371  *  \param [in] a1 - a factor array.
10372  *  \param [in] a2 - another factor array.
10373  *  \return DataArrayInt * - the new instance of DataArrayInt.
10374  *          The caller is to delete this result array using decrRef() as it is no more
10375  *          needed.
10376  *  \throw If either \a a1 or \a a2 is NULL.
10377  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10378  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10379  *         none of them has number of tuples or components equal to 1.
10380  */
10381 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10382 {
10383   if(!a1 || !a2)
10384     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10385   int nbOfTuple=a1->getNumberOfTuples();
10386   int nbOfTuple2=a2->getNumberOfTuples();
10387   int nbOfComp=a1->getNumberOfComponents();
10388   int nbOfComp2=a2->getNumberOfComponents();
10389   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10390   if(nbOfTuple==nbOfTuple2)
10391     {
10392       if(nbOfComp==nbOfComp2)
10393         {
10394           ret=DataArrayInt::New();
10395           ret->alloc(nbOfTuple,nbOfComp);
10396           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10397           ret->copyStringInfoFrom(*a1);
10398         }
10399       else
10400         {
10401           int nbOfCompMin,nbOfCompMax;
10402           const DataArrayInt *aMin, *aMax;
10403           if(nbOfComp>nbOfComp2)
10404             {
10405               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10406               aMin=a2; aMax=a1;
10407             }
10408           else
10409             {
10410               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10411               aMin=a1; aMax=a2;
10412             }
10413           if(nbOfCompMin==1)
10414             {
10415               ret=DataArrayInt::New();
10416               ret->alloc(nbOfTuple,nbOfCompMax);
10417               const int *aMinPtr=aMin->getConstPointer();
10418               const int *aMaxPtr=aMax->getConstPointer();
10419               int *res=ret->getPointer();
10420               for(int i=0;i<nbOfTuple;i++)
10421                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10422               ret->copyStringInfoFrom(*aMax);
10423             }
10424           else
10425             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10426         }
10427     }
10428   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10429     {
10430       if(nbOfComp==nbOfComp2)
10431         {
10432           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10433           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10434           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10435           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10436           ret=DataArrayInt::New();
10437           ret->alloc(nbOfTupleMax,nbOfComp);
10438           int *res=ret->getPointer();
10439           for(int i=0;i<nbOfTupleMax;i++)
10440             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10441           ret->copyStringInfoFrom(*aMax);
10442         }
10443       else
10444         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10445     }
10446   else
10447     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10448   return ret.retn();
10449 }
10450
10451
10452 /*!
10453  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10454  * valid cases.
10455  * 1.  The arrays have same number of tuples and components. Then each value of
10456  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10457  *   _a_ [ i, j ] *= _other_ [ i, j ].
10458  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10459  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10460  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10461  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10462  *
10463  *  \param [in] other - an array to multiply to \a this one.
10464  *  \throw If \a other is NULL.
10465  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10466  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10467  *         \a other has number of both tuples and components not equal to 1.
10468  */
10469 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10470 {
10471   if(!other)
10472     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10473   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10474   checkAllocated(); other->checkAllocated();
10475   int nbOfTuple=getNumberOfTuples();
10476   int nbOfTuple2=other->getNumberOfTuples();
10477   int nbOfComp=getNumberOfComponents();
10478   int nbOfComp2=other->getNumberOfComponents();
10479   if(nbOfTuple==nbOfTuple2)
10480     {
10481       if(nbOfComp==nbOfComp2)
10482         {
10483           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10484         }
10485       else if(nbOfComp2==1)
10486         {
10487           int *ptr=getPointer();
10488           const int *ptrc=other->getConstPointer();
10489           for(int i=0;i<nbOfTuple;i++)
10490             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10491         }
10492       else
10493         throw INTERP_KERNEL::Exception(msg);
10494     }
10495   else if(nbOfTuple2==1)
10496     {
10497       if(nbOfComp2==nbOfComp)
10498         {
10499           int *ptr=getPointer();
10500           const int *ptrc=other->getConstPointer();
10501           for(int i=0;i<nbOfTuple;i++)
10502             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10503         }
10504       else
10505         throw INTERP_KERNEL::Exception(msg);
10506     }
10507   else
10508     throw INTERP_KERNEL::Exception(msg);
10509   declareAsNew();
10510 }
10511
10512
10513 /*!
10514  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10515  * valid cases.
10516  * 1.  The arrays have same number of tuples and components. Then each value of
10517  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10518  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10519  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10520  *   component. Then
10521  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10522  * 3.  The arrays have same number of components and one array, say _a2_, has one
10523  *   tuple. Then
10524  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10525  *
10526  * Info on components is copied either from the first array (in the first case) or from
10527  * the array with maximal number of elements (getNbOfElems()).
10528  *  \warning No check of division by zero is performed!
10529  *  \param [in] a1 - a numerator array.
10530  *  \param [in] a2 - a denominator array.
10531  *  \return DataArrayInt * - the new instance of DataArrayInt.
10532  *          The caller is to delete this result array using decrRef() as it is no more
10533  *          needed.
10534  *  \throw If either \a a1 or \a a2 is NULL.
10535  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10536  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10537  *         none of them has number of tuples or components equal to 1.
10538  */
10539 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10540 {
10541   if(!a1 || !a2)
10542     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10543   int nbOfTuple1=a1->getNumberOfTuples();
10544   int nbOfTuple2=a2->getNumberOfTuples();
10545   int nbOfComp1=a1->getNumberOfComponents();
10546   int nbOfComp2=a2->getNumberOfComponents();
10547   if(nbOfTuple2==nbOfTuple1)
10548     {
10549       if(nbOfComp1==nbOfComp2)
10550         {
10551           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10552           ret->alloc(nbOfTuple2,nbOfComp1);
10553           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10554           ret->copyStringInfoFrom(*a1);
10555           return ret.retn();
10556         }
10557       else if(nbOfComp2==1)
10558         {
10559           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10560           ret->alloc(nbOfTuple1,nbOfComp1);
10561           const int *a2Ptr=a2->getConstPointer();
10562           const int *a1Ptr=a1->getConstPointer();
10563           int *res=ret->getPointer();
10564           for(int i=0;i<nbOfTuple1;i++)
10565             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10566           ret->copyStringInfoFrom(*a1);
10567           return ret.retn();
10568         }
10569       else
10570         {
10571           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10572           return 0;
10573         }
10574     }
10575   else if(nbOfTuple2==1)
10576     {
10577       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10578       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10579       ret->alloc(nbOfTuple1,nbOfComp1);
10580       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10581       int *pt=ret->getPointer();
10582       for(int i=0;i<nbOfTuple1;i++)
10583         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10584       ret->copyStringInfoFrom(*a1);
10585       return ret.retn();
10586     }
10587   else
10588     {
10589       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10590       return 0;
10591     }
10592 }
10593
10594 /*!
10595  * Divide values of \a this array by values of another DataArrayInt. There are 3
10596  * valid cases.
10597  * 1.  The arrays have same number of tuples and components. Then each value of
10598  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10599  *   _a_ [ i, j ] /= _other_ [ i, j ].
10600  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10601  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10602  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10603  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10604  *
10605  *  \warning No check of division by zero is performed!
10606  *  \param [in] other - an array to divide \a this one by.
10607  *  \throw If \a other is NULL.
10608  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10609  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10610  *         \a other has number of both tuples and components not equal to 1.
10611  */
10612 void DataArrayInt::divideEqual(const DataArrayInt *other)
10613 {
10614   if(!other)
10615     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10616   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10617   checkAllocated(); other->checkAllocated();
10618   int nbOfTuple=getNumberOfTuples();
10619   int nbOfTuple2=other->getNumberOfTuples();
10620   int nbOfComp=getNumberOfComponents();
10621   int nbOfComp2=other->getNumberOfComponents();
10622   if(nbOfTuple==nbOfTuple2)
10623     {
10624       if(nbOfComp==nbOfComp2)
10625         {
10626           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10627         }
10628       else if(nbOfComp2==1)
10629         {
10630           int *ptr=getPointer();
10631           const int *ptrc=other->getConstPointer();
10632           for(int i=0;i<nbOfTuple;i++)
10633             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10634         }
10635       else
10636         throw INTERP_KERNEL::Exception(msg);
10637     }
10638   else if(nbOfTuple2==1)
10639     {
10640       if(nbOfComp2==nbOfComp)
10641         {
10642           int *ptr=getPointer();
10643           const int *ptrc=other->getConstPointer();
10644           for(int i=0;i<nbOfTuple;i++)
10645             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10646         }
10647       else
10648         throw INTERP_KERNEL::Exception(msg);
10649     }
10650   else
10651     throw INTERP_KERNEL::Exception(msg);
10652   declareAsNew();
10653 }
10654
10655
10656 /*!
10657  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10658  * valid cases.
10659  * 1.  The arrays have same number of tuples and components. Then each value of
10660  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10661  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10662  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10663  *   component. Then
10664  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10665  * 3.  The arrays have same number of components and one array, say _a2_, has one
10666  *   tuple. Then
10667  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10668  *
10669  * Info on components is copied either from the first array (in the first case) or from
10670  * the array with maximal number of elements (getNbOfElems()).
10671  *  \warning No check of division by zero is performed!
10672  *  \param [in] a1 - a dividend array.
10673  *  \param [in] a2 - a divisor array.
10674  *  \return DataArrayInt * - the new instance of DataArrayInt.
10675  *          The caller is to delete this result array using decrRef() as it is no more
10676  *          needed.
10677  *  \throw If either \a a1 or \a a2 is NULL.
10678  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10679  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10680  *         none of them has number of tuples or components equal to 1.
10681  */
10682 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10683 {
10684     if(!a1 || !a2)
10685     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10686   int nbOfTuple1=a1->getNumberOfTuples();
10687   int nbOfTuple2=a2->getNumberOfTuples();
10688   int nbOfComp1=a1->getNumberOfComponents();
10689   int nbOfComp2=a2->getNumberOfComponents();
10690   if(nbOfTuple2==nbOfTuple1)
10691     {
10692       if(nbOfComp1==nbOfComp2)
10693         {
10694           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10695           ret->alloc(nbOfTuple2,nbOfComp1);
10696           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10697           ret->copyStringInfoFrom(*a1);
10698           return ret.retn();
10699         }
10700       else if(nbOfComp2==1)
10701         {
10702           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10703           ret->alloc(nbOfTuple1,nbOfComp1);
10704           const int *a2Ptr=a2->getConstPointer();
10705           const int *a1Ptr=a1->getConstPointer();
10706           int *res=ret->getPointer();
10707           for(int i=0;i<nbOfTuple1;i++)
10708             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10709           ret->copyStringInfoFrom(*a1);
10710           return ret.retn();
10711         }
10712       else
10713         {
10714           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10715           return 0;
10716         }
10717     }
10718   else if(nbOfTuple2==1)
10719     {
10720       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10721       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10722       ret->alloc(nbOfTuple1,nbOfComp1);
10723       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10724       int *pt=ret->getPointer();
10725       for(int i=0;i<nbOfTuple1;i++)
10726         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10727       ret->copyStringInfoFrom(*a1);
10728       return ret.retn();
10729     }
10730   else
10731     {
10732       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10733       return 0;
10734     }
10735 }
10736
10737 /*!
10738  * Modify \a this array so that each value becomes a modulus of division of this value by
10739  * a value of another DataArrayInt. There are 3 valid cases.
10740  * 1.  The arrays have same number of tuples and components. Then each value of
10741  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10742  *   _a_ [ i, j ] %= _other_ [ i, j ].
10743  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10744  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10745  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10746  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10747  *
10748  *  \warning No check of division by zero is performed!
10749  *  \param [in] other - a divisor array.
10750  *  \throw If \a other is NULL.
10751  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10752  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10753  *         \a other has number of both tuples and components not equal to 1.
10754  */
10755 void DataArrayInt::modulusEqual(const DataArrayInt *other)
10756 {
10757   if(!other)
10758     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10759   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10760   checkAllocated(); other->checkAllocated();
10761   int nbOfTuple=getNumberOfTuples();
10762   int nbOfTuple2=other->getNumberOfTuples();
10763   int nbOfComp=getNumberOfComponents();
10764   int nbOfComp2=other->getNumberOfComponents();
10765   if(nbOfTuple==nbOfTuple2)
10766     {
10767       if(nbOfComp==nbOfComp2)
10768         {
10769           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10770         }
10771       else if(nbOfComp2==1)
10772         {
10773           if(nbOfComp2==nbOfComp)
10774             {
10775               int *ptr=getPointer();
10776               const int *ptrc=other->getConstPointer();
10777               for(int i=0;i<nbOfTuple;i++)
10778                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10779             }
10780           else
10781             throw INTERP_KERNEL::Exception(msg);
10782         }
10783       else
10784         throw INTERP_KERNEL::Exception(msg);
10785     }
10786   else if(nbOfTuple2==1)
10787     {
10788       int *ptr=getPointer();
10789       const int *ptrc=other->getConstPointer();
10790       for(int i=0;i<nbOfTuple;i++)
10791         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10792     }
10793   else
10794     throw INTERP_KERNEL::Exception(msg);
10795   declareAsNew();
10796 }
10797
10798 /*!
10799  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10800  * valid cases.
10801  *
10802  *  \param [in] a1 - an array to pow up.
10803  *  \param [in] a2 - another array to sum up.
10804  *  \return DataArrayInt * - the new instance of DataArrayInt.
10805  *          The caller is to delete this result array using decrRef() as it is no more
10806  *          needed.
10807  *  \throw If either \a a1 or \a a2 is NULL.
10808  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10809  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10810  *  \throw If there is a negative value in \a a2.
10811  */
10812 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
10813 {
10814   if(!a1 || !a2)
10815     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10816   int nbOfTuple=a1->getNumberOfTuples();
10817   int nbOfTuple2=a2->getNumberOfTuples();
10818   int nbOfComp=a1->getNumberOfComponents();
10819   int nbOfComp2=a2->getNumberOfComponents();
10820   if(nbOfTuple!=nbOfTuple2)
10821     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10822   if(nbOfComp!=1 || nbOfComp2!=1)
10823     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10824   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10825   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10826   int *ptr=ret->getPointer();
10827   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10828     {
10829       if(*ptr2>=0)
10830         {
10831           int tmp=1;
10832           for(int j=0;j<*ptr2;j++)
10833             tmp*=*ptr1;
10834           *ptr=tmp;
10835         }
10836       else
10837         {
10838           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10839           throw INTERP_KERNEL::Exception(oss.str().c_str());
10840         }
10841     }
10842   return ret.retn();
10843 }
10844
10845 /*!
10846  * Apply pow on values of another DataArrayInt to values of \a this one.
10847  *
10848  *  \param [in] other - an array to pow to \a this one.
10849  *  \throw If \a other is NULL.
10850  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10851  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10852  *  \throw If there is a negative value in \a other.
10853  */
10854 void DataArrayInt::powEqual(const DataArrayInt *other)
10855 {
10856   if(!other)
10857     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10858   int nbOfTuple=getNumberOfTuples();
10859   int nbOfTuple2=other->getNumberOfTuples();
10860   int nbOfComp=getNumberOfComponents();
10861   int nbOfComp2=other->getNumberOfComponents();
10862   if(nbOfTuple!=nbOfTuple2)
10863     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10864   if(nbOfComp!=1 || nbOfComp2!=1)
10865     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10866   int *ptr=getPointer();
10867   const int *ptrc=other->begin();
10868   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10869     {
10870       if(*ptrc>=0)
10871         {
10872           int tmp=1;
10873           for(int j=0;j<*ptrc;j++)
10874             tmp*=*ptr;
10875           *ptr=tmp;
10876         }
10877       else
10878         {
10879           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10880           throw INTERP_KERNEL::Exception(oss.str().c_str());
10881         }
10882     }
10883   declareAsNew();
10884 }
10885
10886 /*!
10887  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10888  * This map, if applied to \a start array, would make it sorted. For example, if
10889  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10890  * [5,6,0,3,2,7,1,4].
10891  *  \param [in] start - pointer to the first element of the array for which the
10892  *         permutation map is computed.
10893  *  \param [in] end - pointer specifying the end of the array \a start, so that
10894  *         the last value of \a start is \a end[ -1 ].
10895  *  \return int * - the result permutation array that the caller is to delete as it is no
10896  *         more needed.
10897  *  \throw If there are equal values in the input array.
10898  */
10899 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10900 {
10901   std::size_t sz=std::distance(start,end);
10902   int *ret=(int *)malloc(sz*sizeof(int));
10903   int *work=new int[sz];
10904   std::copy(start,end,work);
10905   std::sort(work,work+sz);
10906   if(std::unique(work,work+sz)!=work+sz)
10907     {
10908       delete [] work;
10909       free(ret);
10910       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10911     }
10912   std::map<int,int> m;
10913   for(int *workPt=work;workPt!=work+sz;workPt++)
10914     m[*workPt]=(int)std::distance(work,workPt);
10915   int *iter2=ret;
10916   for(const int *iter=start;iter!=end;iter++,iter2++)
10917     *iter2=m[*iter];
10918   delete [] work;
10919   return ret;
10920 }
10921
10922 /*!
10923  * Returns a new DataArrayInt containing an arithmetic progression
10924  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10925  * function.
10926  *  \param [in] begin - the start value of the result sequence.
10927  *  \param [in] end - limiting value, so that every value of the result array is less than
10928  *              \a end.
10929  *  \param [in] step - specifies the increment or decrement.
10930  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10931  *          array using decrRef() as it is no more needed.
10932  *  \throw If \a step == 0.
10933  *  \throw If \a end < \a begin && \a step > 0.
10934  *  \throw If \a end > \a begin && \a step < 0.
10935  */
10936 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
10937 {
10938   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10939   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10940   ret->alloc(nbOfTuples,1);
10941   int *ptr=ret->getPointer();
10942   if(step>0)
10943     {
10944       for(int i=begin;i<end;i+=step,ptr++)
10945         *ptr=i;
10946     }
10947   else
10948     {
10949       for(int i=begin;i>end;i+=step,ptr++)
10950         *ptr=i;
10951     }
10952   return ret.retn();
10953 }
10954
10955 /*!
10956  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10957  * Server side.
10958  */
10959 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10960 {
10961   tinyInfo.resize(2);
10962   if(isAllocated())
10963     {
10964       tinyInfo[0]=getNumberOfTuples();
10965       tinyInfo[1]=getNumberOfComponents();
10966     }
10967   else
10968     {
10969       tinyInfo[0]=-1;
10970       tinyInfo[1]=-1;
10971     }
10972 }
10973
10974 /*!
10975  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10976  * Server side.
10977  */
10978 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10979 {
10980   if(isAllocated())
10981     {
10982       int nbOfCompo=getNumberOfComponents();
10983       tinyInfo.resize(nbOfCompo+1);
10984       tinyInfo[0]=getName();
10985       for(int i=0;i<nbOfCompo;i++)
10986         tinyInfo[i+1]=getInfoOnComponent(i);
10987     }
10988   else
10989     {
10990       tinyInfo.resize(1);
10991       tinyInfo[0]=getName();
10992     }
10993 }
10994
10995 /*!
10996  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10997  * This method returns if a feeding is needed.
10998  */
10999 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11000 {
11001   int nbOfTuple=tinyInfoI[0];
11002   int nbOfComp=tinyInfoI[1];
11003   if(nbOfTuple!=-1 || nbOfComp!=-1)
11004     {
11005       alloc(nbOfTuple,nbOfComp);
11006       return true;
11007     }
11008   return false;
11009 }
11010
11011 /*!
11012  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11013  * This method returns if a feeding is needed.
11014  */
11015 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11016 {
11017   setName(tinyInfoS[0].c_str());
11018   if(isAllocated())
11019     {
11020       int nbOfCompo=tinyInfoI[1];
11021       for(int i=0;i<nbOfCompo;i++)
11022         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
11023     }
11024 }
11025
11026 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11027 {
11028   if(_da)
11029     {
11030       _da->incrRef();
11031       if(_da->isAllocated())
11032         {
11033           _nb_comp=da->getNumberOfComponents();
11034           _nb_tuple=da->getNumberOfTuples();
11035           _pt=da->getPointer();
11036         }
11037     }
11038 }
11039
11040 DataArrayIntIterator::~DataArrayIntIterator()
11041 {
11042   if(_da)
11043     _da->decrRef();
11044 }
11045
11046 DataArrayIntTuple *DataArrayIntIterator::nextt()
11047 {
11048   if(_tuple_id<_nb_tuple)
11049     {
11050       _tuple_id++;
11051       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11052       _pt+=_nb_comp;
11053       return ret;
11054     }
11055   else
11056     return 0;
11057 }
11058
11059 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11060 {
11061 }
11062
11063 std::string DataArrayIntTuple::repr() const
11064 {
11065   std::ostringstream oss; oss << "(";
11066   for(int i=0;i<_nb_of_compo-1;i++)
11067     oss << _pt[i] << ", ";
11068   oss << _pt[_nb_of_compo-1] << ")";
11069   return oss.str();
11070 }
11071
11072 int DataArrayIntTuple::intValue() const
11073 {
11074   if(_nb_of_compo==1)
11075     return *_pt;
11076   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11077 }
11078
11079 /*!
11080  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11081  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11082  * 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
11083  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11084  */
11085 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11086 {
11087   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11088     {
11089       DataArrayInt *ret=DataArrayInt::New();
11090       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11091       return ret;
11092     }
11093   else
11094     {
11095       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11096       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11097       throw INTERP_KERNEL::Exception(oss.str().c_str());
11098     }
11099 }