Salome HOME
Script to perform automatic renaming should be installed.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const std::string& name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const std::string& varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * This method put in info format the result of the merge of \a var and \a unit.
427  * The standard format for that is "var [unit]".
428  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
429  */
430 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
431 {
432   std::ostringstream oss;
433   oss << var << " [" << unit << "]";
434   return oss.str();
435 }
436
437 std::string DataArray::GetAxTypeRepr(MEDCouplingAxisType at)
438 {
439   switch(at)
440     {
441     case AX_CART:
442       return std::string("AX_CART");
443     case AX_CYL:
444       return std::string("AX_CYL");
445     case AX_SPHER:
446       return std::string("AX_SPHER");
447     default:
448       throw INTERP_KERNEL::Exception("DataArray::GetAxTypeRepr : unrecognized axis type enum !");
449     }
450 }
451
452 /*!
453  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
454  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
455  * the number of component in the result array is same as that of each of given arrays.
456  * Info on components is copied from the first of the given arrays. Number of components
457  * in the given arrays must be  the same.
458  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
459  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
460  *          The caller is to delete this result array using decrRef() as it is no more
461  *          needed.
462  *  \throw If all arrays within \a arrs are NULL.
463  *  \throw If all not null arrays in \a arrs have not the same type.
464  *  \throw If getNumberOfComponents() of arrays within \a arrs.
465  */
466 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
467 {
468   std::vector<const DataArray *> arr2;
469   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
470     if(*it)
471       arr2.push_back(*it);
472   if(arr2.empty())
473     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
474   std::vector<const DataArrayDouble *> arrd;
475   std::vector<const DataArrayInt *> arri;
476   std::vector<const DataArrayChar *> arrc;
477   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
478     {
479       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
480       if(a)
481         { arrd.push_back(a); continue; }
482       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
483       if(b)
484         { arri.push_back(b); continue; }
485       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
486       if(c)
487         { arrc.push_back(c); continue; }
488       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
489     }
490   if(arr2.size()==arrd.size())
491     return DataArrayDouble::Aggregate(arrd);
492   if(arr2.size()==arri.size())
493     return DataArrayInt::Aggregate(arri);
494   if(arr2.size()==arrc.size())
495     return DataArrayChar::Aggregate(arrc);
496   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
497 }
498
499 /*!
500  * Sets information on a component specified by an index.
501  * To know more on format of this information
502  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
503  *  \warning Don't pass NULL as \a info!
504  *  \param [in] i - the index (zero based) of the component of interest.
505  *  \param [in] info - the string containing the information.
506  *  \throw If \a i is not a valid component index.
507  */
508 void DataArray::setInfoOnComponent(int i, const std::string& info)
509 {
510   if(i<(int)_info_on_compo.size() && i>=0)
511     _info_on_compo[i]=info;
512   else
513     {
514       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();
515       throw INTERP_KERNEL::Exception(oss.str().c_str());
516     }
517 }
518
519 /*!
520  * Sets information on all components. This method can change number of components
521  * at certain conditions; if the conditions are not respected, an exception is thrown.
522  * The number of components can be changed in \a this only if \a this is not allocated.
523  * The condition of number of components must not be changed.
524  *
525  * To know more on format of the component information see
526  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
527  *  \param [in] info - a vector of component infos.
528  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
529  */
530 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
531 {
532   if(getNumberOfComponents()!=(int)info.size())
533     {
534       if(!isAllocated())
535         _info_on_compo=info;
536       else
537         {
538           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 !";
539           throw INTERP_KERNEL::Exception(oss.str().c_str());
540         }
541     }
542   else
543     _info_on_compo=info;
544 }
545
546 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
547 {
548   if(getNumberOfTuples()!=nbOfTuples)
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553 }
554
555 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
556 {
557   if(getNumberOfComponents()!=nbOfCompo)
558     {
559       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
560       throw INTERP_KERNEL::Exception(oss.str().c_str());
561     }
562 }
563
564 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
565 {
566   if(getNbOfElems()!=nbOfElems)
567     {
568       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
569       throw INTERP_KERNEL::Exception(oss.str().c_str());
570     }
571 }
572
573 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
574 {
575   if(getNumberOfTuples()!=other.getNumberOfTuples())
576     {
577       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
578       throw INTERP_KERNEL::Exception(oss.str().c_str());
579     }
580   if(getNumberOfComponents()!=other.getNumberOfComponents())
581     {
582       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
583       throw INTERP_KERNEL::Exception(oss.str().c_str());
584     }
585 }
586
587 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
588 {
589   checkNbOfTuples(nbOfTuples,msg);
590   checkNbOfComps(nbOfCompo,msg);
591 }
592
593 /*!
594  * Simply this method checks that \b value is in [0,\b ref).
595  */
596 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
597 {
598   if(value<0 || value>=ref)
599     {
600       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
601       throw INTERP_KERNEL::Exception(oss.str().c_str());
602     }
603 }
604
605 /*!
606  * This method checks that [\b start, \b end) is compliant with ref length \b value.
607  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
608  */
609 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
610 {
611   if(start<0 || start>=value)
612     {
613       if(value!=start || end!=start)
614         {
615           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
616           throw INTERP_KERNEL::Exception(oss.str().c_str());
617         }
618     }
619   if(end<0 || end>value)
620     {
621       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
622       throw INTERP_KERNEL::Exception(oss.str().c_str());
623     }
624 }
625
626 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
627 {
628   if(value<0 || value>ref)
629     {
630       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633 }
634
635 /*!
636  * 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, 
637  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
638  *
639  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
640  *
641  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
642  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
643  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
644  * \param [in] sliceId - the slice id considered
645  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
646  * \param [out] startSlice - the start of the slice considered
647  * \param [out] stopSlice - the stop of the slice consided
648  * 
649  * \throw If \a step == 0
650  * \throw If \a nbOfSlices not > 0
651  * \throw If \a sliceId not in [0,nbOfSlices)
652  */
653 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
654 {
655   if(nbOfSlices<=0)
656     {
657       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
658       throw INTERP_KERNEL::Exception(oss.str().c_str());
659     }
660   if(sliceId<0 || sliceId>=nbOfSlices)
661     {
662       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
663       throw INTERP_KERNEL::Exception(oss.str().c_str());
664     }
665   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
666   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
667   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
668   if(sliceId<nbOfSlices-1)
669     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
670   else
671     stopSlice=stop;
672 }
673
674 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
675 {
676   if(end<begin)
677     {
678       std::ostringstream oss; oss << msg << " : end before begin !";
679       throw INTERP_KERNEL::Exception(oss.str().c_str());
680     }
681   if(end==begin)
682     return 0;
683   if(step<=0)
684     {
685       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
686       throw INTERP_KERNEL::Exception(oss.str().c_str());
687     }
688   return (end-1-begin)/step+1;
689 }
690
691 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
692 {
693   if(step==0)
694     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
695   if(end<begin && step>0)
696     {
697       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
698       throw INTERP_KERNEL::Exception(oss.str().c_str());
699     }
700   if(begin<end && step<0)
701     {
702       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
703       throw INTERP_KERNEL::Exception(oss.str().c_str());
704     }
705   if(begin!=end)
706     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
707   else
708     return 0;
709 }
710
711 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
712 {
713   if(step!=0)
714     {
715       if(step>0)
716         {
717           if(begin<=value && value<end)
718             {
719               if((value-begin)%step==0)
720                 return (value-begin)/step;
721               else
722                 return -1;
723             }
724           else
725             return -1;
726         }
727       else
728         {
729           if(begin>=value && value>end)
730             {
731               if((begin-value)%(-step)==0)
732                 return (begin-value)/(-step);
733               else
734                 return -1;
735             }
736           else
737             return -1;
738         }
739     }
740   else
741     return -1;
742 }
743
744 /*!
745  * Returns a new instance of DataArrayDouble. The caller is to delete this array
746  * using decrRef() as it is no more needed. 
747  */
748 DataArrayDouble *DataArrayDouble::New()
749 {
750   return new DataArrayDouble;
751 }
752
753 /*!
754  * Checks if raw data is allocated. Read more on the raw data
755  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
756  *  \return bool - \a true if the raw data is allocated, \a false else.
757  */
758 bool DataArrayDouble::isAllocated() const
759 {
760   return getConstPointer()!=0;
761 }
762
763 /*!
764  * Checks if raw data is allocated and throws an exception if it is not the case.
765  *  \throw If the raw data is not allocated.
766  */
767 void DataArrayDouble::checkAllocated() const
768 {
769   if(!isAllocated())
770     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
771 }
772
773 /*!
774  * This method desallocated \a this without modification of informations relative to the components.
775  * After call of this method, DataArrayDouble::isAllocated will return false.
776  * If \a this is already not allocated, \a this is let unchanged.
777  */
778 void DataArrayDouble::desallocate()
779 {
780   _mem.destroy();
781 }
782
783 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
784 {
785   std::size_t sz(_mem.getNbOfElemAllocated());
786   sz*=sizeof(double);
787   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
788 }
789
790 /*!
791  * Returns the only one value in \a this, if and only if number of elements
792  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
793  *  \return double - the sole value stored in \a this array.
794  *  \throw If at least one of conditions stated above is not fulfilled.
795  */
796 double DataArrayDouble::doubleValue() const
797 {
798   if(isAllocated())
799     {
800       if(getNbOfElems()==1)
801         {
802           return *getConstPointer();
803         }
804       else
805         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
806     }
807   else
808     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
809 }
810
811 /*!
812  * Checks the number of tuples.
813  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
814  *  \throw If \a this is not allocated.
815  */
816 bool DataArrayDouble::empty() const
817 {
818   checkAllocated();
819   return getNumberOfTuples()==0;
820 }
821
822 /*!
823  * Returns a full copy of \a this. For more info on copying data arrays see
824  * \ref MEDCouplingArrayBasicsCopyDeep.
825  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
826  *          delete this array using decrRef() as it is no more needed. 
827  */
828 DataArrayDouble *DataArrayDouble::deepCpy() const
829 {
830   return new DataArrayDouble(*this);
831 }
832
833 /*!
834  * Returns either a \a deep or \a shallow copy of this array. For more info see
835  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
836  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
837  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
838  *          == \a true) or \a this instance (if \a dCpy == \a false).
839  */
840 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
841 {
842   if(dCpy)
843     return deepCpy();
844   else
845     {
846       incrRef();
847       return const_cast<DataArrayDouble *>(this);
848     }
849 }
850
851 /*!
852  * Copies all the data from another DataArrayDouble. For more info see
853  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
854  *  \param [in] other - another instance of DataArrayDouble to copy data from.
855  *  \throw If the \a other is not allocated.
856  */
857 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
858 {
859   other.checkAllocated();
860   int nbOfTuples=other.getNumberOfTuples();
861   int nbOfComp=other.getNumberOfComponents();
862   allocIfNecessary(nbOfTuples,nbOfComp);
863   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
864   double *pt=getPointer();
865   const double *ptI=other.getConstPointer();
866   for(std::size_t i=0;i<nbOfElems;i++)
867     pt[i]=ptI[i];
868   copyStringInfoFrom(other);
869 }
870
871 /*!
872  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
873  * 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.
874  * If \a this has not already been allocated, number of components is set to one.
875  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
876  * 
877  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
878  */
879 void DataArrayDouble::reserve(std::size_t nbOfElems)
880 {
881   int nbCompo=getNumberOfComponents();
882   if(nbCompo==1)
883     {
884       _mem.reserve(nbOfElems);
885     }
886   else if(nbCompo==0)
887     {
888       _mem.reserve(nbOfElems);
889       _info_on_compo.resize(1);
890     }
891   else
892     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
893 }
894
895 /*!
896  * 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
897  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
898  *
899  * \param [in] val the value to be added in \a this
900  * \throw If \a this has already been allocated with number of components different from one.
901  * \sa DataArrayDouble::pushBackValsSilent
902  */
903 void DataArrayDouble::pushBackSilent(double val)
904 {
905   int nbCompo=getNumberOfComponents();
906   if(nbCompo==1)
907     _mem.pushBack(val);
908   else if(nbCompo==0)
909     {
910       _info_on_compo.resize(1);
911       _mem.pushBack(val);
912     }
913   else
914     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
915 }
916
917 /*!
918  * 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
919  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
920  *
921  *  \param [in] valsBg - an array of values to push at the end of \c this.
922  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
923  *              the last value of \a valsBg is \a valsEnd[ -1 ].
924  * \throw If \a this has already been allocated with number of components different from one.
925  * \sa DataArrayDouble::pushBackSilent
926  */
927 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
928 {
929   int nbCompo=getNumberOfComponents();
930   if(nbCompo==1)
931     _mem.insertAtTheEnd(valsBg,valsEnd);
932   else if(nbCompo==0)
933     {
934       _info_on_compo.resize(1);
935       _mem.insertAtTheEnd(valsBg,valsEnd);
936     }
937   else
938     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
939 }
940
941 /*!
942  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
943  * \throw If \a this is already empty.
944  * \throw If \a this has number of components different from one.
945  */
946 double DataArrayDouble::popBackSilent()
947 {
948   if(getNumberOfComponents()==1)
949     return _mem.popBack();
950   else
951     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
952 }
953
954 /*!
955  * 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.
956  *
957  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
958  */
959 void DataArrayDouble::pack() const
960 {
961   _mem.pack();
962 }
963
964 /*!
965  * Allocates the raw data in memory. If exactly same memory as needed already
966  * allocated, it is not re-allocated.
967  *  \param [in] nbOfTuple - number of tuples of data to allocate.
968  *  \param [in] nbOfCompo - number of components of data to allocate.
969  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
970  */
971 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
972 {
973   if(isAllocated())
974     {
975       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
976         alloc(nbOfTuple,nbOfCompo);
977     }
978   else
979     alloc(nbOfTuple,nbOfCompo);
980 }
981
982 /*!
983  * Allocates the raw data in memory. If the memory was already allocated, then it is
984  * freed and re-allocated. See an example of this method use
985  * \ref MEDCouplingArraySteps1WC "here".
986  *  \param [in] nbOfTuple - number of tuples of data to allocate.
987  *  \param [in] nbOfCompo - number of components of data to allocate.
988  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
989  */
990 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
991 {
992   if(nbOfTuple<0 || nbOfCompo<0)
993     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
994   _info_on_compo.resize(nbOfCompo);
995   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
996   declareAsNew();
997 }
998
999 /*!
1000  * Assign zero to all values in \a this array. To know more on filling arrays see
1001  * \ref MEDCouplingArrayFill.
1002  * \throw If \a this is not allocated.
1003  */
1004 void DataArrayDouble::fillWithZero()
1005 {
1006   checkAllocated();
1007   _mem.fillWithValue(0.);
1008   declareAsNew();
1009 }
1010
1011 /*!
1012  * Assign \a val to all values in \a this array. To know more on filling arrays see
1013  * \ref MEDCouplingArrayFill.
1014  *  \param [in] val - the value to fill with.
1015  *  \throw If \a this is not allocated.
1016  */
1017 void DataArrayDouble::fillWithValue(double val)
1018 {
1019   checkAllocated();
1020   _mem.fillWithValue(val);
1021   declareAsNew();
1022 }
1023
1024 /*!
1025  * Set all values in \a this array so that the i-th element equals to \a init + i
1026  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1027  *  \param [in] init - value to assign to the first element of array.
1028  *  \throw If \a this->getNumberOfComponents() != 1
1029  *  \throw If \a this is not allocated.
1030  */
1031 void DataArrayDouble::iota(double init)
1032 {
1033   checkAllocated();
1034   if(getNumberOfComponents()!=1)
1035     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1036   double *ptr=getPointer();
1037   int ntuples=getNumberOfTuples();
1038   for(int i=0;i<ntuples;i++)
1039     ptr[i]=init+double(i);
1040   declareAsNew();
1041 }
1042
1043 /*!
1044  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1045  *  \param [in] val - value to check equality of array values to.
1046  *  \param [in] eps - precision to check the equality.
1047  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1048  *                 \a false else.
1049  *  \throw If \a this->getNumberOfComponents() != 1
1050  *  \throw If \a this is not allocated.
1051  */
1052 bool DataArrayDouble::isUniform(double val, double eps) const
1053 {
1054   checkAllocated();
1055   if(getNumberOfComponents()!=1)
1056     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1057   int nbOfTuples=getNumberOfTuples();
1058   const double *w=getConstPointer();
1059   const double *end2=w+nbOfTuples;
1060   const double vmin=val-eps;
1061   const double vmax=val+eps;
1062   for(;w!=end2;w++)
1063     if(*w<vmin || *w>vmax)
1064       return false;
1065   return true;
1066 }
1067
1068 /*!
1069  * Sorts values of the array.
1070  *  \param [in] asc - \a true means ascending order, \a false, descending.
1071  *  \throw If \a this is not allocated.
1072  *  \throw If \a this->getNumberOfComponents() != 1.
1073  */
1074 void DataArrayDouble::sort(bool asc)
1075 {
1076   checkAllocated();
1077   if(getNumberOfComponents()!=1)
1078     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1079   _mem.sort(asc);
1080   declareAsNew();
1081 }
1082
1083 /*!
1084  * Reverse the array values.
1085  *  \throw If \a this->getNumberOfComponents() < 1.
1086  *  \throw If \a this is not allocated.
1087  */
1088 void DataArrayDouble::reverse()
1089 {
1090   checkAllocated();
1091   _mem.reverse(getNumberOfComponents());
1092   declareAsNew();
1093 }
1094
1095 /*!
1096  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1097  * with at least absolute difference value of |\a eps| at each step.
1098  * If not an exception is thrown.
1099  *  \param [in] increasing - if \a true, the array values should be increasing.
1100  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1101  *                    the values are considered different.
1102  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1103  *         increasing arg.
1104  *  \throw If \a this->getNumberOfComponents() != 1.
1105  *  \throw If \a this is not allocated.
1106  */
1107 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1108 {
1109   if(!isMonotonic(increasing,eps))
1110     {
1111       if (increasing)
1112         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1113       else
1114         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1115     }
1116 }
1117
1118 /*!
1119  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1120  * with at least absolute difference value of |\a eps| at each step.
1121  *  \param [in] increasing - if \a true, array values should be increasing.
1122  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1123  *                    the values are considered different.
1124  *  \return bool - \a true if values change in accordance with \a increasing arg.
1125  *  \throw If \a this->getNumberOfComponents() != 1.
1126  *  \throw If \a this is not allocated.
1127  */
1128 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1129 {
1130   checkAllocated();
1131   if(getNumberOfComponents()!=1)
1132     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1133   int nbOfElements=getNumberOfTuples();
1134   const double *ptr=getConstPointer();
1135   if(nbOfElements==0)
1136     return true;
1137   double ref=ptr[0];
1138   double absEps=fabs(eps);
1139   if(increasing)
1140     {
1141       for(int i=1;i<nbOfElements;i++)
1142         {
1143           if(ptr[i]<(ref+absEps))
1144             return false;
1145           ref=ptr[i];
1146         }
1147       return true;
1148     }
1149   else
1150     {
1151       for(int i=1;i<nbOfElements;i++)
1152         {
1153           if(ptr[i]>(ref-absEps))
1154             return false;
1155           ref=ptr[i];
1156         }
1157       return true;
1158     }
1159 }
1160
1161 /*!
1162  * Returns a textual and human readable representation of \a this instance of
1163  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1164  * \return std::string - text describing \a this DataArrayDouble.
1165  *
1166  * \sa reprNotTooLong, reprZip
1167  */
1168 std::string DataArrayDouble::repr() const
1169 {
1170   std::ostringstream ret;
1171   reprStream(ret);
1172   return ret.str();
1173 }
1174
1175 std::string DataArrayDouble::reprZip() const
1176 {
1177   std::ostringstream ret;
1178   reprZipStream(ret);
1179   return ret.str();
1180 }
1181
1182 /*!
1183  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
1184  * printed out to avoid to consume too much space in interpretor.
1185  * \sa repr
1186  */
1187 std::string DataArrayDouble::reprNotTooLong() const
1188 {
1189   std::ostringstream ret;
1190   reprNotTooLongStream(ret);
1191   return ret.str();
1192 }
1193
1194 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1195 {
1196   static const char SPACE[4]={' ',' ',' ',' '};
1197   checkAllocated();
1198   std::string idt(indent,' ');
1199   ofs.precision(17);
1200   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1201   //
1202   bool areAllEmpty(true);
1203   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
1204     if(!(*it).empty())
1205       areAllEmpty=false;
1206   if(!areAllEmpty)
1207     for(std::size_t i=0;i<_info_on_compo.size();i++)
1208       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
1209   //
1210   if(byteArr)
1211     {
1212       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1213       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1214       float *pt(tmp);
1215       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1216       for(const double *src=begin();src!=end();src++,pt++)
1217         *pt=float(*src);
1218       const char *data(reinterpret_cast<const char *>((float *)tmp));
1219       std::size_t sz(getNbOfElems()*sizeof(float));
1220       byteArr->insertAtTheEnd(data,data+sz);
1221       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1222     }
1223   else
1224     {
1225       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1226       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1227     }
1228   ofs << std::endl << idt << "</DataArray>\n";
1229 }
1230
1231 void DataArrayDouble::reprStream(std::ostream& stream) const
1232 {
1233   stream << "Name of double array : \"" << _name << "\"\n";
1234   reprWithoutNameStream(stream);
1235 }
1236
1237 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1238 {
1239   stream << "Name of double array : \"" << _name << "\"\n";
1240   reprZipWithoutNameStream(stream);
1241 }
1242
1243 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1244 {
1245   stream << "Name of double array : \"" << _name << "\"\n";
1246   reprNotTooLongWithoutNameStream(stream);
1247 }
1248
1249 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1250 {
1251   DataArray::reprWithoutNameStream(stream);
1252   stream.precision(17);
1253   _mem.repr(getNumberOfComponents(),stream);
1254 }
1255
1256 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1257 {
1258   DataArray::reprWithoutNameStream(stream);
1259   stream.precision(17);
1260   _mem.reprZip(getNumberOfComponents(),stream);
1261 }
1262
1263 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1264 {
1265   DataArray::reprWithoutNameStream(stream);
1266   stream.precision(17);
1267   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1268 }
1269
1270 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1271 {
1272   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1273   const double *data=getConstPointer();
1274   stream.precision(17);
1275   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1276   if(nbTuples*nbComp>=1)
1277     {
1278       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1279       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1280       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1281       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1282     }
1283   else
1284     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1285   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1286 }
1287
1288 /*!
1289  * Method that gives a quick overvien of \a this for python.
1290  */
1291 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1292 {
1293   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1294   stream << "DataArrayDouble C++ instance at " << this << ". ";
1295   if(isAllocated())
1296     {
1297       int nbOfCompo=(int)_info_on_compo.size();
1298       if(nbOfCompo>=1)
1299         {
1300           int nbOfTuples=getNumberOfTuples();
1301           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1302           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1303         }
1304       else
1305         stream << "Number of components : 0.";
1306     }
1307   else
1308     stream << "*** No data allocated ****";
1309 }
1310
1311 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1312 {
1313   const double *data=begin();
1314   int nbOfTuples=getNumberOfTuples();
1315   int nbOfCompo=(int)_info_on_compo.size();
1316   std::ostringstream oss2; oss2 << "[";
1317   oss2.precision(17);
1318   std::string oss2Str(oss2.str());
1319   bool isFinished=true;
1320   for(int i=0;i<nbOfTuples && isFinished;i++)
1321     {
1322       if(nbOfCompo>1)
1323         {
1324           oss2 << "(";
1325           for(int j=0;j<nbOfCompo;j++,data++)
1326             {
1327               oss2 << *data;
1328               if(j!=nbOfCompo-1) oss2 << ", ";
1329             }
1330           oss2 << ")";
1331         }
1332       else
1333         oss2 << *data++;
1334       if(i!=nbOfTuples-1) oss2 << ", ";
1335       std::string oss3Str(oss2.str());
1336       if(oss3Str.length()<maxNbOfByteInRepr)
1337         oss2Str=oss3Str;
1338       else
1339         isFinished=false;
1340     }
1341   stream << oss2Str;
1342   if(!isFinished)
1343     stream << "... ";
1344   stream << "]";
1345 }
1346
1347 /*!
1348  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1349  * mismatch is given.
1350  * 
1351  * \param [in] other the instance to be compared with \a this
1352  * \param [in] prec the precision to compare numeric data of the arrays.
1353  * \param [out] reason In case of inequality returns the reason.
1354  * \sa DataArrayDouble::isEqual
1355  */
1356 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1357 {
1358   if(!areInfoEqualsIfNotWhy(other,reason))
1359     return false;
1360   return _mem.isEqual(other._mem,prec,reason);
1361 }
1362
1363 /*!
1364  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1365  * \ref MEDCouplingArrayBasicsCompare.
1366  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1367  *  \param [in] prec - precision value to compare numeric data of the arrays.
1368  *  \return bool - \a true if the two arrays are equal, \a false else.
1369  */
1370 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1371 {
1372   std::string tmp;
1373   return isEqualIfNotWhy(other,prec,tmp);
1374 }
1375
1376 /*!
1377  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1378  * \ref MEDCouplingArrayBasicsCompare.
1379  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1380  *  \param [in] prec - precision value to compare numeric data of the arrays.
1381  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1382  */
1383 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1384 {
1385   std::string tmp;
1386   return _mem.isEqual(other._mem,prec,tmp);
1387 }
1388
1389 /*!
1390  * Changes number of tuples in the array. If the new number of tuples is smaller
1391  * than the current number the array is truncated, otherwise the array is extended.
1392  *  \param [in] nbOfTuples - new number of tuples. 
1393  *  \throw If \a this is not allocated.
1394  *  \throw If \a nbOfTuples is negative.
1395  */
1396 void DataArrayDouble::reAlloc(int nbOfTuples)
1397 {
1398   if(nbOfTuples<0)
1399     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1400   checkAllocated();
1401   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1402   declareAsNew();
1403 }
1404
1405 /*!
1406  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1407  * array to the new one.
1408  *  \return DataArrayInt * - the new instance of DataArrayInt.
1409  */
1410 DataArrayInt *DataArrayDouble::convertToIntArr() const
1411 {
1412   DataArrayInt *ret=DataArrayInt::New();
1413   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1414   int *dest=ret->getPointer();
1415   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1416   for(const double *src=begin();src!=end();src++,dest++)
1417     *dest=(int)*src;
1418   ret->copyStringInfoFrom(*this);
1419   return ret;
1420 }
1421
1422 /*!
1423  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1424  * arranged in memory. If \a this array holds 2 components of 3 values:
1425  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1426  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1427  *  \warning Do not confuse this method with transpose()!
1428  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1429  *          is to delete using decrRef() as it is no more needed.
1430  *  \throw If \a this is not allocated.
1431  */
1432 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1433 {
1434   if(_mem.isNull())
1435     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1436   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1437   DataArrayDouble *ret=DataArrayDouble::New();
1438   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1439   return ret;
1440 }
1441
1442 /*!
1443  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1444  * arranged in memory. If \a this array holds 2 components of 3 values:
1445  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1446  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1447  *  \warning Do not confuse this method with transpose()!
1448  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1449  *          is to delete using decrRef() as it is no more needed.
1450  *  \throw If \a this is not allocated.
1451  */
1452 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1453 {
1454   if(_mem.isNull())
1455     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1456   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1457   DataArrayDouble *ret=DataArrayDouble::New();
1458   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1459   return ret;
1460 }
1461
1462 /*!
1463  * Permutes values of \a this array as required by \a old2New array. The values are
1464  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1465  * the same as in \c this one.
1466  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1467  * For more info on renumbering see \ref numbering.
1468  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1469  *     giving a new position for i-th old value.
1470  */
1471 void DataArrayDouble::renumberInPlace(const int *old2New)
1472 {
1473   checkAllocated();
1474   int nbTuples=getNumberOfTuples();
1475   int nbOfCompo=getNumberOfComponents();
1476   double *tmp=new double[nbTuples*nbOfCompo];
1477   const double *iptr=getConstPointer();
1478   for(int i=0;i<nbTuples;i++)
1479     {
1480       int v=old2New[i];
1481       if(v>=0 && v<nbTuples)
1482         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1483       else
1484         {
1485           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1486           throw INTERP_KERNEL::Exception(oss.str().c_str());
1487         }
1488     }
1489   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1490   delete [] tmp;
1491   declareAsNew();
1492 }
1493
1494 /*!
1495  * Permutes values of \a this array as required by \a new2Old array. The values are
1496  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1497  * the same as in \c this one.
1498  * For more info on renumbering see \ref numbering.
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 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1505 {
1506   checkAllocated();
1507   int nbTuples=getNumberOfTuples();
1508   int nbOfCompo=getNumberOfComponents();
1509   double *tmp=new double[nbTuples*nbOfCompo];
1510   const double *iptr=getConstPointer();
1511   for(int i=0;i<nbTuples;i++)
1512     {
1513       int v=new2Old[i];
1514       if(v>=0 && v<nbTuples)
1515         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1516       else
1517         {
1518           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1519           throw INTERP_KERNEL::Exception(oss.str().c_str());
1520         }
1521     }
1522   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1523   delete [] tmp;
1524   declareAsNew();
1525 }
1526
1527 /*!
1528  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1529  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1530  * Number of tuples in the result array remains the same as in \c this one.
1531  * If a permutation reduction is needed, renumberAndReduce() should be used.
1532  * For more info on renumbering see \ref numbering.
1533  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1534  *          giving a new position for i-th old value.
1535  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1536  *          is to delete using decrRef() as it is no more needed.
1537  *  \throw If \a this is not allocated.
1538  */
1539 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1540 {
1541   checkAllocated();
1542   int nbTuples=getNumberOfTuples();
1543   int nbOfCompo=getNumberOfComponents();
1544   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1545   ret->alloc(nbTuples,nbOfCompo);
1546   ret->copyStringInfoFrom(*this);
1547   const double *iptr=getConstPointer();
1548   double *optr=ret->getPointer();
1549   for(int i=0;i<nbTuples;i++)
1550     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1551   ret->copyStringInfoFrom(*this);
1552   return ret.retn();
1553 }
1554
1555 /*!
1556  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1557  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1558  * tuples in the result array remains the same as in \c this one.
1559  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1560  * For more info on renumbering see \ref numbering.
1561  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1562  *     giving a previous position of i-th new value.
1563  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1564  *          is to delete using decrRef() as it is no more needed.
1565  */
1566 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1567 {
1568   checkAllocated();
1569   int nbTuples=getNumberOfTuples();
1570   int nbOfCompo=getNumberOfComponents();
1571   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1572   ret->alloc(nbTuples,nbOfCompo);
1573   ret->copyStringInfoFrom(*this);
1574   const double *iptr=getConstPointer();
1575   double *optr=ret->getPointer();
1576   for(int i=0;i<nbTuples;i++)
1577     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1578   ret->copyStringInfoFrom(*this);
1579   return ret.retn();
1580 }
1581
1582 /*!
1583  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1584  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1585  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1586  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1587  * \a old2New[ i ] is negative, is missing from the result array.
1588  * For more info on renumbering see \ref numbering.
1589  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1590  *     giving a new position for i-th old tuple and giving negative position for
1591  *     for i-th old tuple that should be omitted.
1592  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1593  *          is to delete using decrRef() as it is no more needed.
1594  */
1595 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1596 {
1597   checkAllocated();
1598   int nbTuples=getNumberOfTuples();
1599   int nbOfCompo=getNumberOfComponents();
1600   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1601   ret->alloc(newNbOfTuple,nbOfCompo);
1602   const double *iptr=getConstPointer();
1603   double *optr=ret->getPointer();
1604   for(int i=0;i<nbTuples;i++)
1605     {
1606       int w=old2New[i];
1607       if(w>=0)
1608         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1609     }
1610   ret->copyStringInfoFrom(*this);
1611   return ret.retn();
1612 }
1613
1614 /*!
1615  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1616  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1617  * \a new2OldBg array.
1618  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1619  * This method is equivalent to renumberAndReduce() except that convention in input is
1620  * \c new2old and \b not \c old2new.
1621  * For more info on renumbering see \ref numbering.
1622  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1623  *              tuple index in \a this array to fill the i-th tuple in the new array.
1624  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1625  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1626  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1627  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1628  *          is to delete using decrRef() as it is no more needed.
1629  */
1630 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1631 {
1632   checkAllocated();
1633   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1634   int nbComp=getNumberOfComponents();
1635   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1636   ret->copyStringInfoFrom(*this);
1637   double *pt=ret->getPointer();
1638   const double *srcPt=getConstPointer();
1639   int i=0;
1640   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1641     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1642   ret->copyStringInfoFrom(*this);
1643   return ret.retn();
1644 }
1645
1646 DataArrayDouble *DataArrayDouble::selectByTupleId(const DataArrayInt & di) const
1647 {
1648   return selectByTupleId(di.getConstPointer(), di.getConstPointer()+di.getNumberOfTuples());
1649 }
1650
1651 /*!
1652  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1653  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1654  * \a new2OldBg array.
1655  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1656  * This method is equivalent to renumberAndReduce() except that convention in input is
1657  * \c new2old and \b not \c old2new.
1658  * This method is equivalent to selectByTupleId() except that it prevents coping data
1659  * from behind the end of \a this array.
1660  * For more info on renumbering see \ref numbering.
1661  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1662  *              tuple index in \a this array to fill the i-th tuple in the new array.
1663  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1664  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1665  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1666  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1667  *          is to delete using decrRef() as it is no more needed.
1668  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1669  */
1670 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1671 {
1672   checkAllocated();
1673   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1674   int nbComp=getNumberOfComponents();
1675   int oldNbOfTuples=getNumberOfTuples();
1676   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1677   ret->copyStringInfoFrom(*this);
1678   double *pt=ret->getPointer();
1679   const double *srcPt=getConstPointer();
1680   int i=0;
1681   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1682     if(*w>=0 && *w<oldNbOfTuples)
1683       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1684     else
1685       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1686   ret->copyStringInfoFrom(*this);
1687   return ret.retn();
1688 }
1689
1690 /*!
1691  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1692  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1693  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1694  * command \c range( \a bg, \a end2, \a step ).
1695  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1696  * not constructed explicitly.
1697  * For more info on renumbering see \ref numbering.
1698  *  \param [in] bg - index of the first tuple to copy from \a this array.
1699  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1700  *  \param [in] step - index increment to get index of the next tuple to copy.
1701  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1702  *          is to delete using decrRef() as it is no more needed.
1703  *  \sa DataArrayDouble::substr.
1704  */
1705 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1706 {
1707   checkAllocated();
1708   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1709   int nbComp=getNumberOfComponents();
1710   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1711   ret->alloc(newNbOfTuples,nbComp);
1712   double *pt=ret->getPointer();
1713   const double *srcPt=getConstPointer()+bg*nbComp;
1714   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1715     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1716   ret->copyStringInfoFrom(*this);
1717   return ret.retn();
1718 }
1719
1720 /*!
1721  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1722  * of tuples specified by \a ranges parameter.
1723  * For more info on renumbering see \ref numbering.
1724  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1725  *              of tuples in [\c begin,\c end) format.
1726  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1727  *          is to delete using decrRef() as it is no more needed.
1728  *  \throw If \a end < \a begin.
1729  *  \throw If \a end > \a this->getNumberOfTuples().
1730  *  \throw If \a this is not allocated.
1731  */
1732 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1733 {
1734   checkAllocated();
1735   int nbOfComp=getNumberOfComponents();
1736   int nbOfTuplesThis=getNumberOfTuples();
1737   if(ranges.empty())
1738     {
1739       DataArrayDouble *ret=DataArrayDouble::New();
1740       ret->alloc(0,nbOfComp);
1741       ret->copyStringInfoFrom(*this);
1742       return ret;
1743     }
1744   int ref=ranges.front().first;
1745   int nbOfTuples=0;
1746   bool isIncreasing=true;
1747   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1748     {
1749       if((*it).first<=(*it).second)
1750         {
1751           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1752             {
1753               nbOfTuples+=(*it).second-(*it).first;
1754               if(isIncreasing)
1755                 isIncreasing=ref<=(*it).first;
1756               ref=(*it).second;
1757             }
1758           else
1759             {
1760               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1761               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1762               throw INTERP_KERNEL::Exception(oss.str().c_str());
1763             }
1764         }
1765       else
1766         {
1767           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1768           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1769           throw INTERP_KERNEL::Exception(oss.str().c_str());
1770         }
1771     }
1772   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1773     return deepCpy();
1774   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1775   ret->alloc(nbOfTuples,nbOfComp);
1776   ret->copyStringInfoFrom(*this);
1777   const double *src=getConstPointer();
1778   double *work=ret->getPointer();
1779   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1780     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1781   return ret.retn();
1782 }
1783
1784 /*!
1785  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1786  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1787  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1788  * This method is a specialization of selectByTupleId2().
1789  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1790  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1791  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1792  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1793  *          is to delete using decrRef() as it is no more needed.
1794  *  \throw If \a tupleIdBg < 0.
1795  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1796     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1797  *  \sa DataArrayDouble::selectByTupleId2
1798  */
1799 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1800 {
1801   checkAllocated();
1802   int nbt=getNumberOfTuples();
1803   if(tupleIdBg<0)
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1805   if(tupleIdBg>nbt)
1806     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1807   int trueEnd=tupleIdEnd;
1808   if(tupleIdEnd!=-1)
1809     {
1810       if(tupleIdEnd>nbt)
1811         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1812     }
1813   else
1814     trueEnd=nbt;
1815   int nbComp=getNumberOfComponents();
1816   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1817   ret->alloc(trueEnd-tupleIdBg,nbComp);
1818   ret->copyStringInfoFrom(*this);
1819   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1820   return ret.retn();
1821 }
1822
1823 /*!
1824  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1825  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1826  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1827  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1828  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1829  * components.  
1830  *  \param [in] newNbOfComp - number of components for the new array to have.
1831  *  \param [in] dftValue - value assigned to new values added to the new array.
1832  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1833  *          is to delete using decrRef() as it is no more needed.
1834  *  \throw If \a this is not allocated.
1835  */
1836 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1837 {
1838   checkAllocated();
1839   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1840   ret->alloc(getNumberOfTuples(),newNbOfComp);
1841   const double *oldc=getConstPointer();
1842   double *nc=ret->getPointer();
1843   int nbOfTuples=getNumberOfTuples();
1844   int oldNbOfComp=getNumberOfComponents();
1845   int dim=std::min(oldNbOfComp,newNbOfComp);
1846   for(int i=0;i<nbOfTuples;i++)
1847     {
1848       int j=0;
1849       for(;j<dim;j++)
1850         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1851       for(;j<newNbOfComp;j++)
1852         nc[newNbOfComp*i+j]=dftValue;
1853     }
1854   ret->setName(getName());
1855   for(int i=0;i<dim;i++)
1856     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1857   ret->setName(getName());
1858   return ret.retn();
1859 }
1860
1861 /*!
1862  * Changes the number of components within \a this array so that its raw data **does
1863  * not** change, instead splitting this data into tuples changes.
1864  *  \warning This method erases all (name and unit) component info set before!
1865  *  \param [in] newNbOfComp - number of components for \a this array to have.
1866  *  \throw If \a this is not allocated
1867  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1868  *  \throw If \a newNbOfCompo is lower than 1.
1869  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1870  *  \warning This method erases all (name and unit) component info set before!
1871  */
1872 void DataArrayDouble::rearrange(int newNbOfCompo)
1873 {
1874   checkAllocated();
1875   if(newNbOfCompo<1)
1876     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1877   std::size_t nbOfElems=getNbOfElems();
1878   if(nbOfElems%newNbOfCompo!=0)
1879     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1880   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1881     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1882   _info_on_compo.clear();
1883   _info_on_compo.resize(newNbOfCompo);
1884   declareAsNew();
1885 }
1886
1887 /*!
1888  * Changes the number of components within \a this array to be equal to its number
1889  * of tuples, and inversely its number of tuples to become equal to its number of 
1890  * components. So that its raw data **does not** change, instead splitting this
1891  * data into tuples changes.
1892  *  \warning This method erases all (name and unit) component info set before!
1893  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1894  *  \throw If \a this is not allocated.
1895  *  \sa rearrange()
1896  */
1897 void DataArrayDouble::transpose()
1898 {
1899   checkAllocated();
1900   int nbOfTuples=getNumberOfTuples();
1901   rearrange(nbOfTuples);
1902 }
1903
1904 /*!
1905  * Returns a copy of \a this array composed of selected components.
1906  * The new DataArrayDouble has the same number of tuples but includes components
1907  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1908  * can be either less, same or more than \a this->getNbOfElems().
1909  *  \param [in] compoIds - sequence of zero based indices of components to include
1910  *              into the new array.
1911  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1912  *          is to delete using decrRef() as it is no more needed.
1913  *  \throw If \a this is not allocated.
1914  *  \throw If a component index (\a i) is not valid: 
1915  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1916  *
1917  *  \if ENABLE_EXAMPLES
1918  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1919  *  \endif
1920  */
1921 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1922 {
1923   checkAllocated();
1924   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1925   std::size_t newNbOfCompo=compoIds.size();
1926   int oldNbOfCompo=getNumberOfComponents();
1927   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1928     if((*it)<0 || (*it)>=oldNbOfCompo)
1929       {
1930         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1931         throw INTERP_KERNEL::Exception(oss.str().c_str());
1932       }
1933   int nbOfTuples=getNumberOfTuples();
1934   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1935   ret->copyPartOfStringInfoFrom(*this,compoIds);
1936   const double *oldc=getConstPointer();
1937   double *nc=ret->getPointer();
1938   for(int i=0;i<nbOfTuples;i++)
1939     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1940       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1941   return ret.retn();
1942 }
1943
1944 /*!
1945  * Appends components of another array to components of \a this one, tuple by tuple.
1946  * So that the number of tuples of \a this array remains the same and the number of 
1947  * components increases.
1948  *  \param [in] other - the DataArrayDouble to append to \a this one.
1949  *  \throw If \a this is not allocated.
1950  *  \throw If \a this and \a other arrays have different number of tuples.
1951  *
1952  *  \if ENABLE_EXAMPLES
1953  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1954  *
1955  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1956  *  \endif
1957  */
1958 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1959 {
1960   checkAllocated();
1961   other->checkAllocated();
1962   int nbOfTuples=getNumberOfTuples();
1963   if(nbOfTuples!=other->getNumberOfTuples())
1964     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1965   int nbOfComp1=getNumberOfComponents();
1966   int nbOfComp2=other->getNumberOfComponents();
1967   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1968   double *w=newArr;
1969   const double *inp1=getConstPointer();
1970   const double *inp2=other->getConstPointer();
1971   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1972     {
1973       w=std::copy(inp1,inp1+nbOfComp1,w);
1974       w=std::copy(inp2,inp2+nbOfComp2,w);
1975     }
1976   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1977   std::vector<int> compIds(nbOfComp2);
1978   for(int i=0;i<nbOfComp2;i++)
1979     compIds[i]=nbOfComp1+i;
1980   copyPartOfStringInfoFrom2(compIds,*other);
1981 }
1982
1983 /*!
1984  * This method checks that all tuples in \a other are in \a this.
1985  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1986  * 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.
1987  *
1988  * \param [in] other - the array having the same number of components than \a this.
1989  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1990  * \sa DataArrayDouble::findCommonTuples
1991  */
1992 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1993 {
1994   if(!other)
1995     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1996   checkAllocated(); other->checkAllocated();
1997   if(getNumberOfComponents()!=other->getNumberOfComponents())
1998     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1999   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
2000   DataArrayInt *c=0,*ci=0;
2001   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
2002   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2003   int newNbOfTuples=-1;
2004   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
2005   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
2006   tupleIds=ret1.retn();
2007   return newNbOfTuples==getNumberOfTuples();
2008 }
2009
2010 /*!
2011  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
2012  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
2013  * distance separating two points is computed with the infinite norm.
2014  *
2015  * Indices of coincident tuples are stored in output arrays.
2016  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
2017  *
2018  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
2019  * MEDCouplingUMesh::mergeNodes().
2020  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
2021  *              considered not coincident.
2022  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2023  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
2024  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
2025  *               \a comm->getNumberOfComponents() == 1. 
2026  *               \a comm->getNumberOfTuples() == \a commIndex->back().
2027  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
2028  *               groups of (indices of) coincident tuples. Its every value is a tuple
2029  *               index where a next group of tuples begins. For example the second
2030  *               group of tuples in \a comm is described by following range of indices:
2031  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
2032  *               gives the number of groups of coincident tuples.
2033  *  \throw If \a this is not allocated.
2034  *  \throw If the number of components is not in [1,2,3,4].
2035  *
2036  *  \if ENABLE_EXAMPLES
2037  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
2038  *
2039  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
2040  *  \endif
2041  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
2042  */
2043 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
2044 {
2045   checkAllocated();
2046   int nbOfCompo=getNumberOfComponents();
2047   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
2048     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
2049
2050   int nbOfTuples=getNumberOfTuples();
2051   //
2052   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
2053   switch(nbOfCompo)
2054   {
2055     case 4:
2056       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2057       break;
2058     case 3:
2059       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2060       break;
2061     case 2:
2062       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2063       break;
2064     case 1:
2065       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2066       break;
2067     default:
2068       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2069   }
2070   comm=c.retn();
2071   commIndex=cI.retn();
2072 }
2073
2074 /*!
2075  * 
2076  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2077  *             \a nbTimes  should be at least equal to 1.
2078  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2079  * \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.
2080  */
2081 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2082 {
2083   checkAllocated();
2084   if(getNumberOfComponents()!=1)
2085     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2086   if(nbTimes<1)
2087     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2088   int nbTuples=getNumberOfTuples();
2089   const double *inPtr=getConstPointer();
2090   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2091   double *retPtr=ret->getPointer();
2092   for(int i=0;i<nbTuples;i++,inPtr++)
2093     {
2094       double val=*inPtr;
2095       for(int j=0;j<nbTimes;j++,retPtr++)
2096         *retPtr=val;
2097     }
2098   ret->copyStringInfoFrom(*this);
2099   return ret.retn();
2100 }
2101
2102 /*!
2103  * This methods returns the minimal distance between the two set of points \a this and \a other.
2104  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2105  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2106  *
2107  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2108  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2109  * \return the minimal distance between the two set of points \a this and \a other.
2110  * \sa DataArrayDouble::findClosestTupleId
2111  */
2112 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2113 {
2114   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2115   int nbOfCompo(getNumberOfComponents());
2116   int otherNbTuples(other->getNumberOfTuples());
2117   const double *thisPt(begin()),*otherPt(other->begin());
2118   const int *part1Pt(part1->begin());
2119   double ret=std::numeric_limits<double>::max();
2120   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2121     {
2122       double tmp(0.);
2123       for(int j=0;j<nbOfCompo;j++)
2124         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2125       if(tmp<ret)
2126         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2127     }
2128   return sqrt(ret);
2129 }
2130
2131 /*!
2132  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2133  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2134  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2135  *
2136  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2137  * \sa DataArrayDouble::minimalDistanceTo
2138  */
2139 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2140 {
2141   if(!other)
2142     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2143   checkAllocated(); other->checkAllocated();
2144   int nbOfCompo=getNumberOfComponents();
2145   if(nbOfCompo!=other->getNumberOfComponents())
2146     {
2147       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2148       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2149       throw INTERP_KERNEL::Exception(oss.str().c_str());
2150     }
2151   int nbOfTuples=other->getNumberOfTuples();
2152   int thisNbOfTuples=getNumberOfTuples();
2153   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2154   double bounds[6];
2155   getMinMaxPerComponent(bounds);
2156   switch(nbOfCompo)
2157   {
2158     case 3:
2159       {
2160         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2161         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2162         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2163         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2164         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2165         break;
2166       }
2167     case 2:
2168       {
2169         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2170         double delta=std::max(xDelta,yDelta);
2171         double characSize=sqrt(delta/(double)thisNbOfTuples);
2172         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2173         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2174         break;
2175       }
2176     case 1:
2177       {
2178         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2179         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2180         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2181         break;
2182       }
2183     default:
2184       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2185   }
2186   return ret.retn();
2187 }
2188
2189 /*!
2190  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2191  * 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
2192  * how many bounding boxes in \a otherBBoxFrmt.
2193  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2194  *
2195  * \param [in] otherBBoxFrmt - It is an array .
2196  * \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.
2197  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2198  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2199  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2200  */
2201 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2202 {
2203   if(!otherBBoxFrmt)
2204     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2205   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2206     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2207   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2208   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2209     {
2210       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2211       throw INTERP_KERNEL::Exception(oss.str().c_str());
2212     }
2213   if(nbOfComp%2!=0)
2214     {
2215       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2216       throw INTERP_KERNEL::Exception(oss.str().c_str());
2217     }
2218   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2219   const double *thisBBPtr(begin());
2220   int *retPtr(ret->getPointer());
2221   switch(nbOfComp/2)
2222   {
2223     case 3:
2224       {
2225         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2226         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2227           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2228         break;
2229       }
2230     case 2:
2231       {
2232         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2233         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2234           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2235         break;
2236       }
2237     case 1:
2238       {
2239         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2240         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2241           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2242         break;
2243       }
2244     default:
2245       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2246   }
2247
2248   return ret.retn();
2249 }
2250
2251 /*!
2252  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2253  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2254  * space. The distance between tuples is computed using norm2. If several tuples are
2255  * not far each from other than \a prec, only one of them remains in the result
2256  * array. The order of tuples in the result array is same as in \a this one except
2257  * that coincident tuples are excluded.
2258  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2259  *              considered not coincident.
2260  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2261  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2262  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2263  *          is to delete using decrRef() as it is no more needed.
2264  *  \throw If \a this is not allocated.
2265  *  \throw If the number of components is not in [1,2,3,4].
2266  *
2267  *  \if ENABLE_EXAMPLES
2268  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2269  *  \endif
2270  */
2271 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2272 {
2273   checkAllocated();
2274   DataArrayInt *c0=0,*cI0=0;
2275   findCommonTuples(prec,limitTupleId,c0,cI0);
2276   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2277   int newNbOfTuples=-1;
2278   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2279   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2280 }
2281
2282 /*!
2283  * Copy all components in a specified order from another DataArrayDouble.
2284  * Both numerical and textual data is copied. The number of tuples in \a this and
2285  * the other array can be different.
2286  *  \param [in] a - the array to copy data from.
2287  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2288  *              to be copied.
2289  *  \throw If \a a is NULL.
2290  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2291  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2292  *
2293  *  \if ENABLE_EXAMPLES
2294  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2295  *  \endif
2296  */
2297 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2298 {
2299   if(!a)
2300     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2301   checkAllocated();
2302   copyPartOfStringInfoFrom2(compoIds,*a);
2303   std::size_t partOfCompoSz=compoIds.size();
2304   int nbOfCompo=getNumberOfComponents();
2305   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2306   const double *ac=a->getConstPointer();
2307   double *nc=getPointer();
2308   for(int i=0;i<nbOfTuples;i++)
2309     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2310       nc[nbOfCompo*i+compoIds[j]]=*ac;
2311 }
2312
2313 /*!
2314  * Copy all values from another DataArrayDouble into specified tuples and components
2315  * of \a this array. Textual data is not copied.
2316  * The tree parameters defining set of indices of tuples and components are similar to
2317  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2318  *  \param [in] a - the array to copy values from.
2319  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2320  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2321  *              are located.
2322  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2323  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2324  *  \param [in] endComp - index of the component before which the components to assign
2325  *              to are located.
2326  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2327  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2328  *              must be equal to the number of columns to assign to, else an
2329  *              exception is thrown; if \a false, then it is only required that \a
2330  *              a->getNbOfElems() equals to number of values to assign to (this condition
2331  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2332  *              values to assign to is given by following Python expression:
2333  *              \a nbTargetValues = 
2334  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2335  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2336  *  \throw If \a a is NULL.
2337  *  \throw If \a a is not allocated.
2338  *  \throw If \a this is not allocated.
2339  *  \throw If parameters specifying tuples and components to assign to do not give a
2340  *            non-empty range of increasing indices.
2341  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2342  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2343  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2344  *
2345  *  \if ENABLE_EXAMPLES
2346  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2347  *  \endif
2348  */
2349 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2350 {
2351   if(!a)
2352     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2353   const char msg[]="DataArrayDouble::setPartOfValues1";
2354   checkAllocated();
2355   a->checkAllocated();
2356   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2357   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2358   int nbComp=getNumberOfComponents();
2359   int nbOfTuples=getNumberOfTuples();
2360   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2361   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2362   bool assignTech=true;
2363   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2364     {
2365       if(strictCompoCompare)
2366         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2367     }
2368   else
2369     {
2370       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2371       assignTech=false;
2372     }
2373   const double *srcPt=a->getConstPointer();
2374   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2375   if(assignTech)
2376     {
2377       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2378         for(int j=0;j<newNbOfComp;j++,srcPt++)
2379           pt[j*stepComp]=*srcPt;
2380     }
2381   else
2382     {
2383       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2384         {
2385           const double *srcPt2=srcPt;
2386           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2387             pt[j*stepComp]=*srcPt2;
2388         }
2389     }
2390 }
2391
2392 /*!
2393  * Assign a given value to values at specified tuples and components of \a this array.
2394  * The tree parameters defining set of indices of tuples and components are similar to
2395  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2396  *  \param [in] a - the value to assign.
2397  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2398  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2399  *              are located.
2400  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2401  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2402  *  \param [in] endComp - index of the component before which the components to assign
2403  *              to are located.
2404  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2405  *  \throw If \a this is not allocated.
2406  *  \throw If parameters specifying tuples and components to assign to, do not give a
2407  *            non-empty range of increasing indices or indices are out of a valid range
2408  *            for \c this array.
2409  *
2410  *  \if ENABLE_EXAMPLES
2411  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2412  *  \endif
2413  */
2414 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2415 {
2416   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2417   checkAllocated();
2418   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2419   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2420   int nbComp=getNumberOfComponents();
2421   int nbOfTuples=getNumberOfTuples();
2422   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2423   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2424   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2425   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2426     for(int j=0;j<newNbOfComp;j++)
2427       pt[j*stepComp]=a;
2428 }
2429
2430 /*!
2431  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2432  * components of \a this array. Textual data is not copied.
2433  * The tuples and components to assign to are defined by C arrays of indices.
2434  * There are two *modes of usage*:
2435  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2436  *   of \a a is assigned to its own location within \a this array. 
2437  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2438  *   components of every specified tuple of \a this array. In this mode it is required
2439  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2440  *
2441  *  \param [in] a - the array to copy values from.
2442  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2443  *              assign values of \a a to.
2444  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2445  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2446  *              \a bgTuples <= \a pi < \a endTuples.
2447  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2448  *              assign values of \a a to.
2449  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2450  *              pointer to a component index <em>(pi)</em> varies as this: 
2451  *              \a bgComp <= \a pi < \a endComp.
2452  *  \param [in] strictCompoCompare - this parameter is checked only if the
2453  *               *mode of usage* is the first; if it is \a true (default), 
2454  *               then \a a->getNumberOfComponents() must be equal 
2455  *               to the number of specified columns, else this is not required.
2456  *  \throw If \a a is NULL.
2457  *  \throw If \a a is not allocated.
2458  *  \throw If \a this is not allocated.
2459  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2460  *         out of a valid range for \a this array.
2461  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2462  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2463  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2464  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2465  *
2466  *  \if ENABLE_EXAMPLES
2467  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2468  *  \endif
2469  */
2470 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2471 {
2472   if(!a)
2473     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2474   const char msg[]="DataArrayDouble::setPartOfValues2";
2475   checkAllocated();
2476   a->checkAllocated();
2477   int nbComp=getNumberOfComponents();
2478   int nbOfTuples=getNumberOfTuples();
2479   for(const int *z=bgComp;z!=endComp;z++)
2480     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2481   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2482   int newNbOfComp=(int)std::distance(bgComp,endComp);
2483   bool assignTech=true;
2484   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2485     {
2486       if(strictCompoCompare)
2487         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2488     }
2489   else
2490     {
2491       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2492       assignTech=false;
2493     }
2494   double *pt=getPointer();
2495   const double *srcPt=a->getConstPointer();
2496   if(assignTech)
2497     {    
2498       for(const int *w=bgTuples;w!=endTuples;w++)
2499         {
2500           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2501           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2502             {    
2503               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2504             }
2505         }
2506     }
2507   else
2508     {
2509       for(const int *w=bgTuples;w!=endTuples;w++)
2510         {
2511           const double *srcPt2=srcPt;
2512           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2513           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2514             {    
2515               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2516             }
2517         }
2518     }
2519 }
2520
2521 /*!
2522  * Assign a given value to values at specified tuples and components of \a this array.
2523  * The tuples and components to assign to are defined by C arrays of indices.
2524  *  \param [in] a - the value to assign.
2525  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2526  *              assign \a a to.
2527  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2528  *              pointer to a tuple index (\a pi) varies as this: 
2529  *              \a bgTuples <= \a pi < \a endTuples.
2530  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2531  *              assign \a a to.
2532  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2533  *              pointer to a component index (\a pi) varies as this: 
2534  *              \a bgComp <= \a pi < \a endComp.
2535  *  \throw If \a this is not allocated.
2536  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2537  *         out of a valid range for \a this array.
2538  *
2539  *  \if ENABLE_EXAMPLES
2540  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2541  *  \endif
2542  */
2543 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2544 {
2545   checkAllocated();
2546   int nbComp=getNumberOfComponents();
2547   int nbOfTuples=getNumberOfTuples();
2548   for(const int *z=bgComp;z!=endComp;z++)
2549     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2550   double *pt=getPointer();
2551   for(const int *w=bgTuples;w!=endTuples;w++)
2552     for(const int *z=bgComp;z!=endComp;z++)
2553       {
2554         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2555         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2556       }
2557 }
2558
2559 /*!
2560  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2561  * components of \a this array. Textual data is not copied.
2562  * The tuples to assign to are defined by a C array of indices.
2563  * The components to assign to are defined by three values similar to parameters of
2564  * the Python function \c range(\c start,\c stop,\c step).
2565  * There are two *modes of usage*:
2566  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2567  *   of \a a is assigned to its own location within \a this array. 
2568  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2569  *   components of every specified tuple of \a this array. In this mode it is required
2570  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2571  *
2572  *  \param [in] a - the array to copy values from.
2573  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2574  *              assign values of \a a to.
2575  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2576  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2577  *              \a bgTuples <= \a pi < \a endTuples.
2578  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2579  *  \param [in] endComp - index of the component before which the components to assign
2580  *              to are located.
2581  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2582  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2583  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2584  *               then \a a->getNumberOfComponents() must be equal 
2585  *               to the number of specified columns, else this is not required.
2586  *  \throw If \a a is NULL.
2587  *  \throw If \a a is not allocated.
2588  *  \throw If \a this is not allocated.
2589  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2590  *         \a this array.
2591  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2592  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2593  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2594  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2595  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2596  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2597  *  \throw If parameters specifying components to assign to, do not give a
2598  *            non-empty range of increasing indices or indices are out of a valid range
2599  *            for \c this array.
2600  *
2601  *  \if ENABLE_EXAMPLES
2602  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2603  *  \endif
2604  */
2605 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2606 {
2607   if(!a)
2608     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2609   const char msg[]="DataArrayDouble::setPartOfValues3";
2610   checkAllocated();
2611   a->checkAllocated();
2612   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2613   int nbComp=getNumberOfComponents();
2614   int nbOfTuples=getNumberOfTuples();
2615   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2616   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2617   bool assignTech=true;
2618   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2619     {
2620       if(strictCompoCompare)
2621         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2622     }
2623   else
2624     {
2625       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2626       assignTech=false;
2627     }
2628   double *pt=getPointer()+bgComp;
2629   const double *srcPt=a->getConstPointer();
2630   if(assignTech)
2631     {
2632       for(const int *w=bgTuples;w!=endTuples;w++)
2633         for(int j=0;j<newNbOfComp;j++,srcPt++)
2634           {
2635             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2636             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2637           }
2638     }
2639   else
2640     {
2641       for(const int *w=bgTuples;w!=endTuples;w++)
2642         {
2643           const double *srcPt2=srcPt;
2644           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2645             {
2646               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2647               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2648             }
2649         }
2650     }
2651 }
2652
2653 /*!
2654  * Assign a given value to values at specified tuples and components of \a this array.
2655  * The tuples to assign to are defined by a C array of indices.
2656  * The components to assign to are defined by three values similar to parameters of
2657  * the Python function \c range(\c start,\c stop,\c step).
2658  *  \param [in] a - the value to assign.
2659  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2660  *              assign \a a to.
2661  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2662  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2663  *              \a bgTuples <= \a pi < \a endTuples.
2664  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2665  *  \param [in] endComp - index of the component before which the components to assign
2666  *              to are located.
2667  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2668  *  \throw If \a this is not allocated.
2669  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2670  *         \a this array.
2671  *  \throw If parameters specifying components to assign to, do not give a
2672  *            non-empty range of increasing indices or indices are out of a valid range
2673  *            for \c this array.
2674  *
2675  *  \if ENABLE_EXAMPLES
2676  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2677  *  \endif
2678  */
2679 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2680 {
2681   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2682   checkAllocated();
2683   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2684   int nbComp=getNumberOfComponents();
2685   int nbOfTuples=getNumberOfTuples();
2686   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2687   double *pt=getPointer()+bgComp;
2688   for(const int *w=bgTuples;w!=endTuples;w++)
2689     for(int j=0;j<newNbOfComp;j++)
2690       {
2691         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2692         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2693       }
2694 }
2695
2696 /*!
2697  * Copy all values from another DataArrayDouble into specified tuples and components
2698  * of \a this array. Textual data is not copied.
2699  * The tree parameters defining set of indices of tuples and components are similar to
2700  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2701  *  \param [in] a - the array to copy values from.
2702  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2703  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2704  *              are located.
2705  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2706  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2707  *              assign \a a to.
2708  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2709  *              pointer to a component index (\a pi) varies as this: 
2710  *              \a bgComp <= \a pi < \a endComp.
2711  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2712  *              must be equal to the number of columns to assign to, else an
2713  *              exception is thrown; if \a false, then it is only required that \a
2714  *              a->getNbOfElems() equals to number of values to assign to (this condition
2715  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2716  *              values to assign to is given by following Python expression:
2717  *              \a nbTargetValues = 
2718  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2719  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2720  *  \throw If \a a is NULL.
2721  *  \throw If \a a is not allocated.
2722  *  \throw If \a this is not allocated.
2723  *  \throw If parameters specifying tuples and components to assign to do not give a
2724  *            non-empty range of increasing indices.
2725  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2726  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2727  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2728  *
2729  */
2730 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2731 {
2732   if(!a)
2733     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2734   const char msg[]="DataArrayDouble::setPartOfValues4";
2735   checkAllocated();
2736   a->checkAllocated();
2737   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2738   int newNbOfComp=(int)std::distance(bgComp,endComp);
2739   int nbComp=getNumberOfComponents();
2740   for(const int *z=bgComp;z!=endComp;z++)
2741     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2742   int nbOfTuples=getNumberOfTuples();
2743   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2744   bool assignTech=true;
2745   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2746     {
2747       if(strictCompoCompare)
2748         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2749     }
2750   else
2751     {
2752       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2753       assignTech=false;
2754     }
2755   const double *srcPt=a->getConstPointer();
2756   double *pt=getPointer()+bgTuples*nbComp;
2757   if(assignTech)
2758     {
2759       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2760         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2761           pt[*z]=*srcPt;
2762     }
2763   else
2764     {
2765       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2766         {
2767           const double *srcPt2=srcPt;
2768           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2769             pt[*z]=*srcPt2;
2770         }
2771     }
2772 }
2773
2774 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2775 {
2776   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2777   checkAllocated();
2778   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2779   int nbComp=getNumberOfComponents();
2780   for(const int *z=bgComp;z!=endComp;z++)
2781     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2782   int nbOfTuples=getNumberOfTuples();
2783   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2784   double *pt=getPointer()+bgTuples*nbComp;
2785   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2786     for(const int *z=bgComp;z!=endComp;z++)
2787       pt[*z]=a;
2788 }
2789
2790 /*!
2791  * Copy some tuples from another DataArrayDouble into specified tuples
2792  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2793  * components.
2794  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2795  * All components of selected tuples are copied.
2796  *  \param [in] a - the array to copy values from.
2797  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2798  *              target tuples of \a this. \a tuplesSelec has two components, and the
2799  *              first component specifies index of the source tuple and the second
2800  *              one specifies index of the target tuple.
2801  *  \throw If \a this is not allocated.
2802  *  \throw If \a a is NULL.
2803  *  \throw If \a a is not allocated.
2804  *  \throw If \a tuplesSelec is NULL.
2805  *  \throw If \a tuplesSelec is not allocated.
2806  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2807  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2808  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2809  *         the corresponding (\a this or \a a) array.
2810  */
2811 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2812 {
2813   if(!a || !tuplesSelec)
2814     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2815   checkAllocated();
2816   a->checkAllocated();
2817   tuplesSelec->checkAllocated();
2818   int nbOfComp=getNumberOfComponents();
2819   if(nbOfComp!=a->getNumberOfComponents())
2820     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2821   if(tuplesSelec->getNumberOfComponents()!=2)
2822     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2823   int thisNt=getNumberOfTuples();
2824   int aNt=a->getNumberOfTuples();
2825   double *valsToSet=getPointer();
2826   const double *valsSrc=a->getConstPointer();
2827   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2828     {
2829       if(tuple[1]>=0 && tuple[1]<aNt)
2830         {
2831           if(tuple[0]>=0 && tuple[0]<thisNt)
2832             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2833           else
2834             {
2835               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2836               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2837               throw INTERP_KERNEL::Exception(oss.str().c_str());
2838             }
2839         }
2840       else
2841         {
2842           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2843           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2844           throw INTERP_KERNEL::Exception(oss.str().c_str());
2845         }
2846     }
2847 }
2848
2849 /*!
2850  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2851  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2852  * components.
2853  * The tuples to assign to are defined by index of the first tuple, and
2854  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2855  * The tuples to copy are defined by values of a DataArrayInt.
2856  * All components of selected tuples are copied.
2857  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2858  *              values to.
2859  *  \param [in] aBase - the array to copy values from.
2860  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2861  *  \throw If \a this is not allocated.
2862  *  \throw If \a aBase is NULL.
2863  *  \throw If \a aBase is not allocated.
2864  *  \throw If \a tuplesSelec is NULL.
2865  *  \throw If \a tuplesSelec is not allocated.
2866  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2867  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2868  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2869  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2870  *         \a aBase array.
2871  */
2872 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2873 {
2874   if(!aBase || !tuplesSelec)
2875     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2876   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2877   if(!a)
2878     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2879   checkAllocated();
2880   a->checkAllocated();
2881   tuplesSelec->checkAllocated();
2882   int nbOfComp=getNumberOfComponents();
2883   if(nbOfComp!=a->getNumberOfComponents())
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2885   if(tuplesSelec->getNumberOfComponents()!=1)
2886     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2887   int thisNt=getNumberOfTuples();
2888   int aNt=a->getNumberOfTuples();
2889   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2890   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2891   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2892     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2893   const double *valsSrc=a->getConstPointer();
2894   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2895     {
2896       if(*tuple>=0 && *tuple<aNt)
2897         {
2898           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2899         }
2900       else
2901         {
2902           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2903           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2904           throw INTERP_KERNEL::Exception(oss.str().c_str());
2905         }
2906     }
2907 }
2908
2909 /*!
2910  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2911  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2912  * components.
2913  * The tuples to copy are defined by three values similar to parameters of
2914  * the Python function \c range(\c start,\c stop,\c step).
2915  * The tuples to assign to are defined by index of the first tuple, and
2916  * their number is defined by number of tuples to copy.
2917  * All components of selected tuples are copied.
2918  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2919  *              values to.
2920  *  \param [in] aBase - the array to copy values from.
2921  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2922  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2923  *              are located.
2924  *  \param [in] step - index increment to get index of the next tuple to copy.
2925  *  \throw If \a this is not allocated.
2926  *  \throw If \a aBase is NULL.
2927  *  \throw If \a aBase is not allocated.
2928  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2929  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2930  *  \throw If parameters specifying tuples to copy, do not give a
2931  *            non-empty range of increasing indices or indices are out of a valid range
2932  *            for the array \a aBase.
2933  */
2934 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2935 {
2936   if(!aBase)
2937     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2938   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2939   if(!a)
2940     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2941   checkAllocated();
2942   a->checkAllocated();
2943   int nbOfComp=getNumberOfComponents();
2944   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2945   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2946   if(nbOfComp!=a->getNumberOfComponents())
2947     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2948   int thisNt=getNumberOfTuples();
2949   int aNt=a->getNumberOfTuples();
2950   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2951   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2952     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2953   if(end2>aNt)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2955   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2956   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2957     {
2958       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2959     }
2960 }
2961
2962 /*!
2963  * Returns a value located at specified tuple and component.
2964  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2965  * parameters is checked. So this method is safe but expensive if used to go through
2966  * all values of \a this.
2967  *  \param [in] tupleId - index of tuple of interest.
2968  *  \param [in] compoId - index of component of interest.
2969  *  \return double - value located by \a tupleId and \a compoId.
2970  *  \throw If \a this is not allocated.
2971  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2972  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2973  */
2974 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2975 {
2976   checkAllocated();
2977   if(tupleId<0 || tupleId>=getNumberOfTuples())
2978     {
2979       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2980       throw INTERP_KERNEL::Exception(oss.str().c_str());
2981     }
2982   if(compoId<0 || compoId>=getNumberOfComponents())
2983     {
2984       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2985       throw INTERP_KERNEL::Exception(oss.str().c_str());
2986     }
2987   return _mem[tupleId*_info_on_compo.size()+compoId];
2988 }
2989
2990 /*!
2991  * Returns the first value of \a this. 
2992  *  \return double - the last value of \a this array.
2993  *  \throw If \a this is not allocated.
2994  *  \throw If \a this->getNumberOfComponents() != 1.
2995  *  \throw If \a this->getNumberOfTuples() < 1.
2996  */
2997 double DataArrayDouble::front() const
2998 {
2999   checkAllocated();
3000   if(getNumberOfComponents()!=1)
3001     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
3002   int nbOfTuples=getNumberOfTuples();
3003   if(nbOfTuples<1)
3004     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
3005   return *(getConstPointer());
3006 }
3007
3008 /*!
3009  * Returns the last value of \a this. 
3010  *  \return double - the last value of \a this array.
3011  *  \throw If \a this is not allocated.
3012  *  \throw If \a this->getNumberOfComponents() != 1.
3013  *  \throw If \a this->getNumberOfTuples() < 1.
3014  */
3015 double DataArrayDouble::back() const
3016 {
3017   checkAllocated();
3018   if(getNumberOfComponents()!=1)
3019     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
3020   int nbOfTuples=getNumberOfTuples();
3021   if(nbOfTuples<1)
3022     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
3023   return *(getConstPointer()+nbOfTuples-1);
3024 }
3025
3026 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
3027 {
3028   if(newArray!=arrayToSet)
3029     {
3030       if(arrayToSet)
3031         arrayToSet->decrRef();
3032       arrayToSet=newArray;
3033       if(arrayToSet)
3034         arrayToSet->incrRef();
3035     }
3036 }
3037
3038 /*!
3039  * Sets a C array to be used as raw data of \a this. The previously set info
3040  *  of components is retained and re-sized. 
3041  * For more info see \ref MEDCouplingArraySteps1.
3042  *  \param [in] array - the C array to be used as raw data of \a this.
3043  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
3044  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
3045  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
3046  *                     \c free(\c array ) will be called.
3047  *  \param [in] nbOfTuple - new number of tuples in \a this.
3048  *  \param [in] nbOfCompo - new number of components in \a this.
3049  */
3050 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
3051 {
3052   _info_on_compo.resize(nbOfCompo);
3053   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
3054   declareAsNew();
3055 }
3056
3057 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3058 {
3059   _info_on_compo.resize(nbOfCompo);
3060   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3061   declareAsNew();
3062 }
3063
3064 /*!
3065  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3066  * is thrown.
3067  * \throw If zero is found in \a this array.
3068  */
3069 void DataArrayDouble::checkNoNullValues() const
3070 {
3071   const double *tmp=getConstPointer();
3072   std::size_t nbOfElems=getNbOfElems();
3073   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3074   if(where!=tmp+nbOfElems)
3075     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3076 }
3077
3078 /*!
3079  * Computes minimal and maximal value in each component. An output array is filled
3080  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3081  * enough memory before calling this method.
3082  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3083  *               It is filled as follows:<br>
3084  *               \a bounds[0] = \c min_of_component_0 <br>
3085  *               \a bounds[1] = \c max_of_component_0 <br>
3086  *               \a bounds[2] = \c min_of_component_1 <br>
3087  *               \a bounds[3] = \c max_of_component_1 <br>
3088  *               ...
3089  */
3090 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3091 {
3092   checkAllocated();
3093   int dim=getNumberOfComponents();
3094   for (int idim=0; idim<dim; idim++)
3095     {
3096       bounds[idim*2]=std::numeric_limits<double>::max();
3097       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3098     } 
3099   const double *ptr=getConstPointer();
3100   int nbOfTuples=getNumberOfTuples();
3101   for(int i=0;i<nbOfTuples;i++)
3102     {
3103       for(int idim=0;idim<dim;idim++)
3104         {
3105           if(bounds[idim*2]>ptr[i*dim+idim])
3106             {
3107               bounds[idim*2]=ptr[i*dim+idim];
3108             }
3109           if(bounds[idim*2+1]<ptr[i*dim+idim])
3110             {
3111               bounds[idim*2+1]=ptr[i*dim+idim];
3112             }
3113         }
3114     }
3115 }
3116
3117 /*!
3118  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3119  * to store both the min and max per component of each tuples. 
3120  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3121  *
3122  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3123  *
3124  * \throw If \a this is not allocated yet.
3125  */
3126 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3127 {
3128   checkAllocated();
3129   const double *dataPtr=getConstPointer();
3130   int nbOfCompo=getNumberOfComponents();
3131   int nbTuples=getNumberOfTuples();
3132   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3133   bbox->alloc(nbTuples,2*nbOfCompo);
3134   double *bboxPtr=bbox->getPointer();
3135   for(int i=0;i<nbTuples;i++)
3136     {
3137       for(int j=0;j<nbOfCompo;j++)
3138         {
3139           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3140           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3141         }
3142     }
3143   return bbox.retn();
3144 }
3145
3146 /*!
3147  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3148  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3149  * 
3150  * \param [in] other a DataArrayDouble having same number of components than \a this.
3151  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3152  * \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.
3153  *             \a cI allows to extract information in \a c.
3154  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3155  *
3156  * \throw In case of:
3157  *  - \a this is not allocated
3158  *  - \a other is not allocated or null
3159  *  - \a this and \a other do not have the same number of components
3160  *  - if number of components of \a this is not in [1,2,3]
3161  *
3162  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3163  */
3164 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3165 {
3166   if(!other)
3167     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3168   checkAllocated();
3169   other->checkAllocated();
3170   int nbOfCompo=getNumberOfComponents();
3171   int otherNbOfCompo=other->getNumberOfComponents();
3172   if(nbOfCompo!=otherNbOfCompo)
3173     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3174   int nbOfTuplesOther=other->getNumberOfTuples();
3175   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3176   switch(nbOfCompo)
3177   {
3178     case 3:
3179       {
3180         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3181         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3182         break;
3183       }
3184     case 2:
3185       {
3186         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3187         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3188         break;
3189       }
3190     case 1:
3191       {
3192         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3193         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3194         break;
3195       }
3196     default:
3197       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3198   }
3199   c=cArr.retn(); cI=cIArr.retn();
3200 }
3201
3202 /*!
3203  * 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
3204  * around origin of 'radius' 1.
3205  * 
3206  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3207  */
3208 void DataArrayDouble::recenterForMaxPrecision(double eps)
3209 {
3210   checkAllocated();
3211   int dim=getNumberOfComponents();
3212   std::vector<double> bounds(2*dim);
3213   getMinMaxPerComponent(&bounds[0]);
3214   for(int i=0;i<dim;i++)
3215     {
3216       double delta=bounds[2*i+1]-bounds[2*i];
3217       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3218       if(delta>eps)
3219         applyLin(1./delta,-offset/delta,i);
3220       else
3221         applyLin(1.,-offset,i);
3222     }
3223 }
3224
3225 /*!
3226  * Returns the maximal value and its location within \a this one-dimensional array.
3227  *  \param [out] tupleId - index of the tuple holding the maximal value.
3228  *  \return double - the maximal value among all values of \a this array.
3229  *  \throw If \a this->getNumberOfComponents() != 1
3230  *  \throw If \a this->getNumberOfTuples() < 1
3231  */
3232 double DataArrayDouble::getMaxValue(int& tupleId) const
3233 {
3234   checkAllocated();
3235   if(getNumberOfComponents()!=1)
3236     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 !");
3237   int nbOfTuples=getNumberOfTuples();
3238   if(nbOfTuples<=0)
3239     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3240   const double *vals=getConstPointer();
3241   const double *loc=std::max_element(vals,vals+nbOfTuples);
3242   tupleId=(int)std::distance(vals,loc);
3243   return *loc;
3244 }
3245
3246 /*!
3247  * Returns the maximal value within \a this array that is allowed to have more than
3248  *  one component.
3249  *  \return double - the maximal value among all values of \a this array.
3250  *  \throw If \a this is not allocated.
3251  */
3252 double DataArrayDouble::getMaxValueInArray() const
3253 {
3254   checkAllocated();
3255   const double *loc=std::max_element(begin(),end());
3256   return *loc;
3257 }
3258
3259 /*!
3260  * Returns the maximal value and all its locations within \a this one-dimensional array.
3261  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3262  *               tuples holding the maximal value. The caller is to delete it using
3263  *               decrRef() as it is no more needed.
3264  *  \return double - the maximal value among all values of \a this array.
3265  *  \throw If \a this->getNumberOfComponents() != 1
3266  *  \throw If \a this->getNumberOfTuples() < 1
3267  */
3268 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3269 {
3270   int tmp;
3271   tupleIds=0;
3272   double ret=getMaxValue(tmp);
3273   tupleIds=getIdsInRange(ret,ret);
3274   return ret;
3275 }
3276
3277 /*!
3278  * Returns the minimal value and its location within \a this one-dimensional array.
3279  *  \param [out] tupleId - index of the tuple holding the minimal value.
3280  *  \return double - the minimal value among all values of \a this array.
3281  *  \throw If \a this->getNumberOfComponents() != 1
3282  *  \throw If \a this->getNumberOfTuples() < 1
3283  */
3284 double DataArrayDouble::getMinValue(int& tupleId) const
3285 {
3286   checkAllocated();
3287   if(getNumberOfComponents()!=1)
3288     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3289   int nbOfTuples=getNumberOfTuples();
3290   if(nbOfTuples<=0)
3291     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3292   const double *vals=getConstPointer();
3293   const double *loc=std::min_element(vals,vals+nbOfTuples);
3294   tupleId=(int)std::distance(vals,loc);
3295   return *loc;
3296 }
3297
3298 /*!
3299  * Returns the minimal value within \a this array that is allowed to have more than
3300  *  one component.
3301  *  \return double - the minimal value among all values of \a this array.
3302  *  \throw If \a this is not allocated.
3303  */
3304 double DataArrayDouble::getMinValueInArray() const
3305 {
3306   checkAllocated();
3307   const double *loc=std::min_element(begin(),end());
3308   return *loc;
3309 }
3310
3311 /*!
3312  * Returns the minimal value and all its locations within \a this one-dimensional array.
3313  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3314  *               tuples holding the minimal value. The caller is to delete it using
3315  *               decrRef() as it is no more needed.
3316  *  \return double - the minimal value among all values of \a this array.
3317  *  \throw If \a this->getNumberOfComponents() != 1
3318  *  \throw If \a this->getNumberOfTuples() < 1
3319  */
3320 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3321 {
3322   int tmp;
3323   tupleIds=0;
3324   double ret=getMinValue(tmp);
3325   tupleIds=getIdsInRange(ret,ret);
3326   return ret;
3327 }
3328
3329 /*!
3330  * 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.
3331  * This method only works for single component array.
3332  *
3333  * \return a value in [ 0, \c this->getNumberOfTuples() )
3334  *
3335  * \throw If \a this is not allocated
3336  *
3337  */
3338 int DataArrayDouble::count(double value, double eps) const
3339 {
3340   int ret=0;
3341   checkAllocated();
3342   if(getNumberOfComponents()!=1)
3343     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3344   const double *vals=begin();
3345   int nbOfTuples=getNumberOfTuples();
3346   for(int i=0;i<nbOfTuples;i++,vals++)
3347     if(fabs(*vals-value)<=eps)
3348       ret++;
3349   return ret;
3350 }
3351
3352 /*!
3353  * Returns the average value of \a this one-dimensional array.
3354  *  \return double - the average value over all values of \a this array.
3355  *  \throw If \a this->getNumberOfComponents() != 1
3356  *  \throw If \a this->getNumberOfTuples() < 1
3357  */
3358 double DataArrayDouble::getAverageValue() const
3359 {
3360   if(getNumberOfComponents()!=1)
3361     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3362   int nbOfTuples=getNumberOfTuples();
3363   if(nbOfTuples<=0)
3364     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3365   const double *vals=getConstPointer();
3366   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3367   return ret/nbOfTuples;
3368 }
3369
3370 /*!
3371  * Returns the Euclidean norm of the vector defined by \a this array.
3372  *  \return double - the value of the Euclidean norm, i.e.
3373  *          the square root of the inner product of vector.
3374  *  \throw If \a this is not allocated.
3375  */
3376 double DataArrayDouble::norm2() const
3377 {
3378   checkAllocated();
3379   double ret=0.;
3380   std::size_t nbOfElems=getNbOfElems();
3381   const double *pt=getConstPointer();
3382   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3383     ret+=(*pt)*(*pt);
3384   return sqrt(ret);
3385 }
3386
3387 /*!
3388  * Returns the maximum norm of the vector defined by \a this array.
3389  * This method works even if the number of components is diferent from one.
3390  * If the number of elements in \a this is 0, -1. is returned.
3391  *  \return double - the value of the maximum norm, i.e.
3392  *          the maximal absolute value among values of \a this array (whatever its number of components).
3393  *  \throw If \a this is not allocated.
3394  */
3395 double DataArrayDouble::normMax() const
3396 {
3397   checkAllocated();
3398   double ret(-1.);
3399   std::size_t nbOfElems(getNbOfElems());
3400   const double *pt(getConstPointer());
3401   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3402     {
3403       double val(std::abs(*pt));
3404       if(val>ret)
3405         ret=val;
3406     }
3407   return ret;
3408 }
3409
3410 /*!
3411  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3412  * This method works even if the number of components is diferent from one.
3413  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3414  *  \return double - the value of the minimum norm, i.e.
3415  *          the minimal absolute value among values of \a this array (whatever its number of components).
3416  *  \throw If \a this is not allocated.
3417  */
3418 double DataArrayDouble::normMin() const
3419 {
3420   checkAllocated();
3421   double ret(std::numeric_limits<double>::max());
3422   std::size_t nbOfElems(getNbOfElems());
3423   const double *pt(getConstPointer());
3424   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3425     {
3426       double val(std::abs(*pt));
3427       if(val<ret)
3428         ret=val;
3429     }
3430   return ret;
3431 }
3432
3433 /*!
3434  * Accumulates values of each component of \a this array.
3435  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3436  *         by the caller, that is filled by this method with sum value for each
3437  *         component.
3438  *  \throw If \a this is not allocated.
3439  */
3440 void DataArrayDouble::accumulate(double *res) const
3441 {
3442   checkAllocated();
3443   const double *ptr=getConstPointer();
3444   int nbTuple=getNumberOfTuples();
3445   int nbComps=getNumberOfComponents();
3446   std::fill(res,res+nbComps,0.);
3447   for(int i=0;i<nbTuple;i++)
3448     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3449 }
3450
3451 /*!
3452  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3453  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3454  *
3455  *
3456  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3457  * \a tupleEnd. If not an exception will be thrown.
3458  *
3459  * \param [in] tupleBg start pointer (included) of input external tuple
3460  * \param [in] tupleEnd end pointer (not included) of input external tuple
3461  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3462  * \return the min distance.
3463  * \sa MEDCouplingUMesh::distanceToPoint
3464  */
3465 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3466 {
3467   checkAllocated();
3468   int nbTuple=getNumberOfTuples();
3469   int nbComps=getNumberOfComponents();
3470   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3471     { 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()); }
3472   if(nbTuple==0)
3473     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3474   double ret0=std::numeric_limits<double>::max();
3475   tupleId=-1;
3476   const double *work=getConstPointer();
3477   for(int i=0;i<nbTuple;i++)
3478     {
3479       double val=0.;
3480       for(int j=0;j<nbComps;j++,work++) 
3481         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3482       if(val>=ret0)
3483         continue;
3484       else
3485         { ret0=val; tupleId=i; }
3486     }
3487   return sqrt(ret0);
3488 }
3489
3490 /*!
3491  * Accumulate values of the given component of \a this array.
3492  *  \param [in] compId - the index of the component of interest.
3493  *  \return double - a sum value of \a compId-th component.
3494  *  \throw If \a this is not allocated.
3495  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3496  *         not respected.
3497  */
3498 double DataArrayDouble::accumulate(int compId) const
3499 {
3500   checkAllocated();
3501   const double *ptr=getConstPointer();
3502   int nbTuple=getNumberOfTuples();
3503   int nbComps=getNumberOfComponents();
3504   if(compId<0 || compId>=nbComps)
3505     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3506   double ret=0.;
3507   for(int i=0;i<nbTuple;i++)
3508     ret+=ptr[i*nbComps+compId];
3509   return ret;
3510 }
3511
3512 /*!
3513  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3514  * The returned array will have same number of components than \a this and number of tuples equal to
3515  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3516  *
3517  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3518  * 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.
3519  *
3520  * \param [in] bgOfIndex - begin (included) of the input index array.
3521  * \param [in] endOfIndex - end (excluded) of the input index array.
3522  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3523  * 
3524  * \throw If bgOfIndex or end is NULL.
3525  * \throw If input index array is not ascendingly sorted.
3526  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3527  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3528  */
3529 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3530 {
3531   if(!bgOfIndex || !endOfIndex)
3532     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3533   checkAllocated();
3534   int nbCompo=getNumberOfComponents();
3535   int nbOfTuples=getNumberOfTuples();
3536   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3537   if(sz<1)
3538     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3539   sz--;
3540   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3541   const int *w=bgOfIndex;
3542   if(*w<0 || *w>=nbOfTuples)
3543     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3544   const double *srcPt=begin()+(*w)*nbCompo;
3545   double *tmp=ret->getPointer();
3546   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3547     {
3548       std::fill(tmp,tmp+nbCompo,0.);
3549       if(w[1]>=w[0])
3550         {
3551           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3552             {
3553               if(j>=0 && j<nbOfTuples)
3554                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3555               else
3556                 {
3557                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3558                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3559                 }
3560             }
3561         }
3562       else
3563         {
3564           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3565           throw INTERP_KERNEL::Exception(oss.str().c_str());
3566         }
3567     }
3568   ret->copyStringInfoFrom(*this);
3569   return ret.retn();
3570 }
3571
3572 /*!
3573  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3574  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3575  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3576  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3577  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3578  *          is to delete this array using decrRef() as it is no more needed. The array
3579  *          does not contain any textual info on components.
3580  *  \throw If \a this->getNumberOfComponents() != 2.
3581  */
3582 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3583 {
3584   checkAllocated();
3585   int nbOfComp(getNumberOfComponents());
3586   if(nbOfComp!=2)
3587     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3588   int nbOfTuple(getNumberOfTuples());
3589   DataArrayDouble *ret(DataArrayDouble::New());
3590   ret->alloc(nbOfTuple,2);
3591   double *w(ret->getPointer());
3592   const double *wIn(getConstPointer());
3593   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3594     {
3595       w[0]=wIn[0]*cos(wIn[1]);
3596       w[1]=wIn[0]*sin(wIn[1]);
3597     }
3598   return ret;
3599 }
3600
3601 /*!
3602  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3603  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3604  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3605  * the Cylindrical CS.
3606  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3607  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3608  *          on the third component is copied from \a this array. The caller
3609  *          is to delete this array using decrRef() as it is no more needed. 
3610  *  \throw If \a this->getNumberOfComponents() != 3.
3611  */
3612 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3613 {
3614   checkAllocated();
3615   int nbOfComp(getNumberOfComponents());
3616   if(nbOfComp!=3)
3617     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3618   int nbOfTuple(getNumberOfTuples());
3619   DataArrayDouble *ret(DataArrayDouble::New());
3620   ret->alloc(getNumberOfTuples(),3);
3621   double *w(ret->getPointer());
3622   const double *wIn(getConstPointer());
3623   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3624     {
3625       w[0]=wIn[0]*cos(wIn[1]);
3626       w[1]=wIn[0]*sin(wIn[1]);
3627       w[2]=wIn[2];
3628     }
3629   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3630   return ret;
3631 }
3632
3633 /*!
3634  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3635  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3636  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3637  * point in the Cylindrical CS.
3638  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3639  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3640  *          on the third component is copied from \a this array. The caller
3641  *          is to delete this array using decrRef() as it is no more needed.
3642  *  \throw If \a this->getNumberOfComponents() != 3.
3643  */
3644 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3645 {
3646   checkAllocated();
3647   int nbOfComp(getNumberOfComponents());
3648   if(nbOfComp!=3)
3649     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3650   int nbOfTuple(getNumberOfTuples());
3651   DataArrayDouble *ret(DataArrayDouble::New());
3652   ret->alloc(getNumberOfTuples(),3);
3653   double *w(ret->getPointer());
3654   const double *wIn(getConstPointer());
3655   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3656     {
3657       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3658       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3659       w[2]=wIn[0]*cos(wIn[1]);
3660     }
3661   return ret;
3662 }
3663
3664 /*!
3665  * This method returns a new array containing the same number of tuples than \a this. To do this, this method needs \a at parameter to specify the convention of \a this.
3666  * All the tuples of the returned array will be in cartesian sense. So if \a at equals to AX_CART the returned array is basically a deep copy of \a this.
3667  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
3668  *
3669  * \param [in] atOfThis - The axis type of \a this.
3670  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
3671  */
3672 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
3673 {
3674   checkAllocated();
3675   int nbOfComp(getNumberOfComponents());
3676   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret;
3677   switch(atOfThis)
3678     {
3679     case AX_CART:
3680       ret=deepCpy();
3681     case AX_CYL:
3682       if(nbOfComp==3)
3683         {
3684           ret=fromCylToCart();
3685           break;
3686         }
3687       if(nbOfComp==2)
3688         {
3689           ret=fromPolarToCart();
3690           break;
3691         }
3692       else
3693         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3694     case AX_SPHER:
3695       if(nbOfComp==3)
3696         {
3697           ret=fromSpherToCart();
3698           break;
3699         }
3700       if(nbOfComp==2)
3701         {
3702           ret=fromPolarToCart();
3703           break;
3704         }
3705       else
3706         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3707     default:
3708       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
3709     }
3710   ret->copyStringInfoFrom(*this);
3711   return ret.retn();
3712 }
3713
3714 /*!
3715  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3716  * array contating 6 components.
3717  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3718  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3719  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3720  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3721  *  \throw If \a this->getNumberOfComponents() != 6.
3722  */
3723 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3724 {
3725   checkAllocated();
3726   int nbOfComp(getNumberOfComponents());
3727   if(nbOfComp!=6)
3728     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3729   DataArrayDouble *ret=DataArrayDouble::New();
3730   int nbOfTuple=getNumberOfTuples();
3731   ret->alloc(nbOfTuple,1);
3732   const double *src=getConstPointer();
3733   double *dest=ret->getPointer();
3734   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3735     *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];
3736   return ret;
3737 }
3738
3739 /*!
3740  * Computes the determinant of every square matrix defined by the tuple of \a this
3741  * array, which contains either 4, 6 or 9 components. The case of 6 components
3742  * corresponds to that of the upper triangular matrix.
3743  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3744  *          is the determinant of matrix of the corresponding tuple of \a this array.
3745  *          The caller is to delete this result array using decrRef() as it is no more
3746  *          needed. 
3747  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3748  */
3749 DataArrayDouble *DataArrayDouble::determinant() const
3750 {
3751   checkAllocated();
3752   DataArrayDouble *ret=DataArrayDouble::New();
3753   int nbOfTuple=getNumberOfTuples();
3754   ret->alloc(nbOfTuple,1);
3755   const double *src=getConstPointer();
3756   double *dest=ret->getPointer();
3757   switch(getNumberOfComponents())
3758   {
3759     case 6:
3760       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3761         *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];
3762       return ret;
3763     case 4:
3764       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3765         *dest=src[0]*src[3]-src[1]*src[2];
3766       return ret;
3767     case 9:
3768       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3769         *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];
3770       return ret;
3771     default:
3772       ret->decrRef();
3773       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3774   }
3775 }
3776
3777 /*!
3778  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3779  * \a this array, which contains 6 components.
3780  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3781  *          components, whose each tuple contains the eigenvalues of the matrix of
3782  *          corresponding tuple of \a this array. 
3783  *          The caller is to delete this result array using decrRef() as it is no more
3784  *          needed. 
3785  *  \throw If \a this->getNumberOfComponents() != 6.
3786  */
3787 DataArrayDouble *DataArrayDouble::eigenValues() const
3788 {
3789   checkAllocated();
3790   int nbOfComp=getNumberOfComponents();
3791   if(nbOfComp!=6)
3792     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3793   DataArrayDouble *ret=DataArrayDouble::New();
3794   int nbOfTuple=getNumberOfTuples();
3795   ret->alloc(nbOfTuple,3);
3796   const double *src=getConstPointer();
3797   double *dest=ret->getPointer();
3798   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3799     INTERP_KERNEL::computeEigenValues6(src,dest);
3800   return ret;
3801 }
3802
3803 /*!
3804  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3805  * \a this array, which contains 6 components.
3806  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3807  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3808  *          corresponding tuple of \a this array.
3809  *          The caller is to delete this result array using decrRef() as it is no more
3810  *          needed.
3811  *  \throw If \a this->getNumberOfComponents() != 6.
3812  */
3813 DataArrayDouble *DataArrayDouble::eigenVectors() const
3814 {
3815   checkAllocated();
3816   int nbOfComp=getNumberOfComponents();
3817   if(nbOfComp!=6)
3818     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3819   DataArrayDouble *ret=DataArrayDouble::New();
3820   int nbOfTuple=getNumberOfTuples();
3821   ret->alloc(nbOfTuple,9);
3822   const double *src=getConstPointer();
3823   double *dest=ret->getPointer();
3824   for(int i=0;i<nbOfTuple;i++,src+=6)
3825     {
3826       double tmp[3];
3827       INTERP_KERNEL::computeEigenValues6(src,tmp);
3828       for(int j=0;j<3;j++,dest+=3)
3829         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3830     }
3831   return ret;
3832 }
3833
3834 /*!
3835  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3836  * array, which contains either 4, 6 or 9 components. The case of 6 components
3837  * corresponds to that of the upper triangular matrix.
3838  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3839  *          same number of components as \a this one, whose each tuple is the inverse
3840  *          matrix of the matrix of corresponding tuple of \a this array. 
3841  *          The caller is to delete this result array using decrRef() as it is no more
3842  *          needed. 
3843  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3844  */
3845 DataArrayDouble *DataArrayDouble::inverse() const
3846 {
3847   checkAllocated();
3848   int nbOfComp=getNumberOfComponents();
3849   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3850     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3851   DataArrayDouble *ret=DataArrayDouble::New();
3852   int nbOfTuple=getNumberOfTuples();
3853   ret->alloc(nbOfTuple,nbOfComp);
3854   const double *src=getConstPointer();
3855   double *dest=ret->getPointer();
3856   if(nbOfComp==6)
3857     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3858       {
3859         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];
3860         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3861         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3862         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3863         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3864         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3865         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3866       }
3867   else if(nbOfComp==4)
3868     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3869       {
3870         double det=src[0]*src[3]-src[1]*src[2];
3871         dest[0]=src[3]/det;
3872         dest[1]=-src[1]/det;
3873         dest[2]=-src[2]/det;
3874         dest[3]=src[0]/det;
3875       }
3876   else
3877     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3878       {
3879         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];
3880         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3881         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3882         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3883         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3884         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3885         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3886         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3887         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3888         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3889       }
3890   return ret;
3891 }
3892
3893 /*!
3894  * Computes the trace of every matrix defined by the tuple of \a this
3895  * array, which contains either 4, 6 or 9 components. The case of 6 components
3896  * corresponds to that of the upper triangular matrix.
3897  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3898  *          1 component, whose each tuple is the trace of
3899  *          the matrix of corresponding tuple of \a this array. 
3900  *          The caller is to delete this result array using decrRef() as it is no more
3901  *          needed. 
3902  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3903  */
3904 DataArrayDouble *DataArrayDouble::trace() const
3905 {
3906   checkAllocated();
3907   int nbOfComp=getNumberOfComponents();
3908   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3909     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3910   DataArrayDouble *ret=DataArrayDouble::New();
3911   int nbOfTuple=getNumberOfTuples();
3912   ret->alloc(nbOfTuple,1);
3913   const double *src=getConstPointer();
3914   double *dest=ret->getPointer();
3915   if(nbOfComp==6)
3916     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3917       *dest=src[0]+src[1]+src[2];
3918   else if(nbOfComp==4)
3919     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3920       *dest=src[0]+src[3];
3921   else
3922     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3923       *dest=src[0]+src[4]+src[8];
3924   return ret;
3925 }
3926
3927 /*!
3928  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3929  * \a this array, which contains 6 components.
3930  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3931  *          same number of components and tuples as \a this array.
3932  *          The caller is to delete this result array using decrRef() as it is no more
3933  *          needed.
3934  *  \throw If \a this->getNumberOfComponents() != 6.
3935  */
3936 DataArrayDouble *DataArrayDouble::deviator() const
3937 {
3938   checkAllocated();
3939   int nbOfComp=getNumberOfComponents();
3940   if(nbOfComp!=6)
3941     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3942   DataArrayDouble *ret=DataArrayDouble::New();
3943   int nbOfTuple=getNumberOfTuples();
3944   ret->alloc(nbOfTuple,6);
3945   const double *src=getConstPointer();
3946   double *dest=ret->getPointer();
3947   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3948     {
3949       double tr=(src[0]+src[1]+src[2])/3.;
3950       dest[0]=src[0]-tr;
3951       dest[1]=src[1]-tr;
3952       dest[2]=src[2]-tr;
3953       dest[3]=src[3];
3954       dest[4]=src[4];
3955       dest[5]=src[5];
3956     }
3957   return ret;
3958 }
3959
3960 /*!
3961  * Computes the magnitude of every vector defined by the tuple of
3962  * \a this array.
3963  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3964  *          same number of tuples as \a this array and one component.
3965  *          The caller is to delete this result array using decrRef() as it is no more
3966  *          needed.
3967  *  \throw If \a this is not allocated.
3968  */
3969 DataArrayDouble *DataArrayDouble::magnitude() const
3970 {
3971   checkAllocated();
3972   int nbOfComp=getNumberOfComponents();
3973   DataArrayDouble *ret=DataArrayDouble::New();
3974   int nbOfTuple=getNumberOfTuples();
3975   ret->alloc(nbOfTuple,1);
3976   const double *src=getConstPointer();
3977   double *dest=ret->getPointer();
3978   for(int i=0;i<nbOfTuple;i++,dest++)
3979     {
3980       double sum=0.;
3981       for(int j=0;j<nbOfComp;j++,src++)
3982         sum+=(*src)*(*src);
3983       *dest=sqrt(sum);
3984     }
3985   return ret;
3986 }
3987
3988 /*!
3989  * Computes for each tuple the sum of number of components values in the tuple and return it.
3990  * 
3991  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3992  *          same number of tuples as \a this array and one component.
3993  *          The caller is to delete this result array using decrRef() as it is no more
3994  *          needed.
3995  *  \throw If \a this is not allocated.
3996  */
3997 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3998 {
3999   checkAllocated();
4000   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4001   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
4002   ret->alloc(nbOfTuple,1);
4003   const double *src(getConstPointer());
4004   double *dest(ret->getPointer());
4005   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4006     *dest=std::accumulate(src,src+nbOfComp,0.);
4007   return ret.retn();
4008 }
4009
4010 /*!
4011  * Computes the maximal value within every tuple of \a this array.
4012  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4013  *          same number of tuples as \a this array and one component.
4014  *          The caller is to delete this result array using decrRef() as it is no more
4015  *          needed.
4016  *  \throw If \a this is not allocated.
4017  *  \sa DataArrayDouble::maxPerTupleWithCompoId
4018  */
4019 DataArrayDouble *DataArrayDouble::maxPerTuple() const
4020 {
4021   checkAllocated();
4022   int nbOfComp=getNumberOfComponents();
4023   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4024   int nbOfTuple=getNumberOfTuples();
4025   ret->alloc(nbOfTuple,1);
4026   const double *src=getConstPointer();
4027   double *dest=ret->getPointer();
4028   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4029     *dest=*std::max_element(src,src+nbOfComp);
4030   return ret.retn();
4031 }
4032
4033 /*!
4034  * Computes the maximal value within every tuple of \a this array and it returns the first component
4035  * id for each tuple that corresponds to the maximal value within the tuple.
4036  * 
4037  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
4038  *          same number of tuples and only one component.
4039  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4040  *          same number of tuples as \a this array and one component.
4041  *          The caller is to delete this result array using decrRef() as it is no more
4042  *          needed.
4043  *  \throw If \a this is not allocated.
4044  *  \sa DataArrayDouble::maxPerTuple
4045  */
4046 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
4047 {
4048   checkAllocated();
4049   int nbOfComp=getNumberOfComponents();
4050   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
4051   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
4052   int nbOfTuple=getNumberOfTuples();
4053   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
4054   const double *src=getConstPointer();
4055   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
4056   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
4057     {
4058       const double *loc=std::max_element(src,src+nbOfComp);
4059       *dest=*loc;
4060       *dest1=(int)std::distance(src,loc);
4061     }
4062   compoIdOfMaxPerTuple=ret1.retn();
4063   return ret0.retn();
4064 }
4065
4066 /*!
4067  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
4068  * \n This returned array contains the euclidian distance for each tuple in \a this. 
4069  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
4070  * \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)
4071  *
4072  * \warning use this method with care because it can leads to big amount of consumed memory !
4073  * 
4074  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4075  *
4076  * \throw If \a this is not allocated.
4077  *
4078  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
4079  */
4080 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
4081 {
4082   checkAllocated();
4083   int nbOfComp=getNumberOfComponents();
4084   int nbOfTuples=getNumberOfTuples();
4085   const double *inData=getConstPointer();
4086   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4087   ret->alloc(nbOfTuples*nbOfTuples,1);
4088   double *outData=ret->getPointer();
4089   for(int i=0;i<nbOfTuples;i++)
4090     {
4091       outData[i*nbOfTuples+i]=0.;
4092       for(int j=i+1;j<nbOfTuples;j++)
4093         {
4094           double dist=0.;
4095           for(int k=0;k<nbOfComp;k++)
4096             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4097           dist=sqrt(dist);
4098           outData[i*nbOfTuples+j]=dist;
4099           outData[j*nbOfTuples+i]=dist;
4100         }
4101     }
4102   return ret.retn();
4103 }
4104
4105 /*!
4106  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4107  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4108  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4109  * \n Output rectangular matrix is sorted along rows.
4110  * \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)
4111  *
4112  * \warning use this method with care because it can leads to big amount of consumed memory !
4113  * 
4114  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4115  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4116  *
4117  * \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.
4118  *
4119  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4120  */
4121 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4122 {
4123   if(!other)
4124     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4125   checkAllocated();
4126   other->checkAllocated();
4127   int nbOfComp=getNumberOfComponents();
4128   int otherNbOfComp=other->getNumberOfComponents();
4129   if(nbOfComp!=otherNbOfComp)
4130     {
4131       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4132       throw INTERP_KERNEL::Exception(oss.str().c_str());
4133     }
4134   int nbOfTuples=getNumberOfTuples();
4135   int otherNbOfTuples=other->getNumberOfTuples();
4136   const double *inData=getConstPointer();
4137   const double *inDataOther=other->getConstPointer();
4138   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4139   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4140   double *outData=ret->getPointer();
4141   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4142     {
4143       for(int j=0;j<nbOfTuples;j++)
4144         {
4145           double dist=0.;
4146           for(int k=0;k<nbOfComp;k++)
4147             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4148           dist=sqrt(dist);
4149           outData[i*nbOfTuples+j]=dist;
4150         }
4151     }
4152   return ret.retn();
4153 }
4154
4155 /*!
4156  * Sorts value within every tuple of \a this array.
4157  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4158  *              in descending order.
4159  *  \throw If \a this is not allocated.
4160  */
4161 void DataArrayDouble::sortPerTuple(bool asc)
4162 {
4163   checkAllocated();
4164   double *pt=getPointer();
4165   int nbOfTuple=getNumberOfTuples();
4166   int nbOfComp=getNumberOfComponents();
4167   if(asc)
4168     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4169       std::sort(pt,pt+nbOfComp);
4170   else
4171     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4172       std::sort(pt,pt+nbOfComp,std::greater<double>());
4173   declareAsNew();
4174 }
4175
4176 /*!
4177  * Converts every value of \a this array to its absolute value.
4178  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4179  * should be called instead.
4180  *
4181  * \throw If \a this is not allocated.
4182  * \sa DataArrayDouble::computeAbs
4183  */
4184 void DataArrayDouble::abs()
4185 {
4186   checkAllocated();
4187   double *ptr(getPointer());
4188   std::size_t nbOfElems(getNbOfElems());
4189   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4190   declareAsNew();
4191 }
4192
4193 /*!
4194  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4195  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4196  *
4197  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4198  *         same number of tuples and component as \a this array.
4199  *         The caller is to delete this result array using decrRef() as it is no more
4200  *         needed.
4201  * \throw If \a this is not allocated.
4202  * \sa DataArrayDouble::abs
4203  */
4204 DataArrayDouble *DataArrayDouble::computeAbs() const
4205 {
4206   checkAllocated();
4207   DataArrayDouble *newArr(DataArrayDouble::New());
4208   int nbOfTuples(getNumberOfTuples());
4209   int nbOfComp(getNumberOfComponents());
4210   newArr->alloc(nbOfTuples,nbOfComp);
4211   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4212   newArr->copyStringInfoFrom(*this);
4213   return newArr;
4214 }
4215
4216 /*!
4217  * Apply a linear function to a given component of \a this array, so that
4218  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4219  *  \param [in] a - the first coefficient of the function.
4220  *  \param [in] b - the second coefficient of the function.
4221  *  \param [in] compoId - the index of component to modify.
4222  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4223  */
4224 void DataArrayDouble::applyLin(double a, double b, int compoId)
4225 {
4226   checkAllocated();
4227   double *ptr(getPointer()+compoId);
4228   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4229   if(compoId<0 || compoId>=nbOfComp)
4230     {
4231       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4232       throw INTERP_KERNEL::Exception(oss.str().c_str());
4233     }
4234   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4235     *ptr=a*(*ptr)+b;
4236   declareAsNew();
4237 }
4238
4239 /*!
4240  * Apply a linear function to all elements of \a this array, so that
4241  * an element _x_ becomes \f$ a * x + b \f$.
4242  *  \param [in] a - the first coefficient of the function.
4243  *  \param [in] b - the second coefficient of the function.
4244  *  \throw If \a this is not allocated.
4245  */
4246 void DataArrayDouble::applyLin(double a, double b)
4247 {
4248   checkAllocated();
4249   double *ptr=getPointer();
4250   std::size_t nbOfElems=getNbOfElems();
4251   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4252     *ptr=a*(*ptr)+b;
4253   declareAsNew();
4254 }
4255
4256 /*!
4257  * Modify all elements of \a this array, so that
4258  * an element _x_ becomes \f$ numerator / x \f$.
4259  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4260  *           array, all elements processed before detection of the zero element remain
4261  *           modified.
4262  *  \param [in] numerator - the numerator used to modify array elements.
4263  *  \throw If \a this is not allocated.
4264  *  \throw If there is an element equal to 0.0 in \a this array.
4265  */
4266 void DataArrayDouble::applyInv(double numerator)
4267 {
4268   checkAllocated();
4269   double *ptr=getPointer();
4270   std::size_t nbOfElems=getNbOfElems();
4271   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4272     {
4273       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4274         {
4275           *ptr=numerator/(*ptr);
4276         }
4277       else
4278         {
4279           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4280           oss << " !";
4281           throw INTERP_KERNEL::Exception(oss.str().c_str());
4282         }
4283     }
4284   declareAsNew();
4285 }
4286
4287 /*!
4288  * Returns a full copy of \a this array except that sign of all elements is reversed.
4289  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4290  *          same number of tuples and component as \a this array.
4291  *          The caller is to delete this result array using decrRef() as it is no more
4292  *          needed.
4293  *  \throw If \a this is not allocated.
4294  */
4295 DataArrayDouble *DataArrayDouble::negate() const
4296 {
4297   checkAllocated();
4298   DataArrayDouble *newArr=DataArrayDouble::New();
4299   int nbOfTuples=getNumberOfTuples();
4300   int nbOfComp=getNumberOfComponents();
4301   newArr->alloc(nbOfTuples,nbOfComp);
4302   const double *cptr=getConstPointer();
4303   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4304   newArr->copyStringInfoFrom(*this);
4305   return newArr;
4306 }
4307
4308 /*!
4309  * Modify all elements of \a this array, so that
4310  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4311  * all values in \a this have to be >= 0 if val is \b not integer.
4312  *  \param [in] val - the value used to apply pow on all array elements.
4313  *  \throw If \a this is not allocated.
4314  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4315  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4316  *           modified.
4317  */
4318 void DataArrayDouble::applyPow(double val)
4319 {
4320   checkAllocated();
4321   double *ptr=getPointer();
4322   std::size_t nbOfElems=getNbOfElems();
4323   int val2=(int)val;
4324   bool isInt=((double)val2)==val;
4325   if(!isInt)
4326     {
4327       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4328         {
4329           if(*ptr>=0)
4330             *ptr=pow(*ptr,val);
4331           else
4332             {
4333               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4334               throw INTERP_KERNEL::Exception(oss.str().c_str());
4335             }
4336         }
4337     }
4338   else
4339     {
4340       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4341         *ptr=pow(*ptr,val2);
4342     }
4343   declareAsNew();
4344 }
4345
4346 /*!
4347  * Modify all elements of \a this array, so that
4348  * an element _x_ becomes \f$ val ^ x \f$.
4349  *  \param [in] val - the value used to apply pow on all array elements.
4350  *  \throw If \a this is not allocated.
4351  *  \throw If \a val < 0.
4352  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4353  *           array, all elements processed before detection of the zero element remain
4354  *           modified.
4355  */
4356 void DataArrayDouble::applyRPow(double val)
4357 {
4358   checkAllocated();
4359   if(val<0.)
4360     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4361   double *ptr=getPointer();
4362   std::size_t nbOfElems=getNbOfElems();
4363   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4364     *ptr=pow(val,*ptr);
4365   declareAsNew();
4366 }
4367
4368 /*!
4369  * Returns a new DataArrayDouble created from \a this one by applying \a
4370  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4371  * For more info see \ref MEDCouplingArrayApplyFunc
4372  *  \param [in] nbOfComp - number of components in the result array.
4373  *  \param [in] func - the \a FunctionToEvaluate declared as 
4374  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4375  *              where \a pos points to the first component of a tuple of \a this array
4376  *              and \a res points to the first component of a tuple of the result array.
4377  *              Note that length (number of components) of \a pos can differ from
4378  *              that of \a res.
4379  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4380  *          same number of tuples as \a this array.
4381  *          The caller is to delete this result array using decrRef() as it is no more
4382  *          needed.
4383  *  \throw If \a this is not allocated.
4384  *  \throw If \a func returns \a false.
4385  */
4386 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4387 {
4388   checkAllocated();
4389   DataArrayDouble *newArr=DataArrayDouble::New();
4390   int nbOfTuples=getNumberOfTuples();
4391   int oldNbOfComp=getNumberOfComponents();
4392   newArr->alloc(nbOfTuples,nbOfComp);
4393   const double *ptr=getConstPointer();
4394   double *ptrToFill=newArr->getPointer();
4395   for(int i=0;i<nbOfTuples;i++)
4396     {
4397       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4398         {
4399           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4400           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4401           oss << ") : Evaluation of function failed !";
4402           newArr->decrRef();
4403           throw INTERP_KERNEL::Exception(oss.str().c_str());
4404         }
4405     }
4406   return newArr;
4407 }
4408
4409 /*!
4410  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4411  * tuple of \a this array. Textual data is not copied.
4412  * For more info see \ref MEDCouplingArrayApplyFunc1.
4413  *  \param [in] nbOfComp - number of components in the result array.
4414  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4415  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4416  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4417  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4418  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4419  *          same number of tuples as \a this array and \a nbOfComp components.
4420  *          The caller is to delete this result array using decrRef() as it is no more
4421  *          needed.
4422  *  \throw If \a this is not allocated.
4423  *  \throw If computing \a func fails.
4424  */
4425 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4426 {
4427   INTERP_KERNEL::ExprParser expr(func);
4428   expr.parse();
4429   std::set<std::string> vars;
4430   expr.getTrueSetOfVars(vars);
4431   std::vector<std::string> varsV(vars.begin(),vars.end());
4432   return applyFunc3(nbOfComp,varsV,func,isSafe);
4433 }
4434
4435 /*!
4436  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4437  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4438  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4439  *
4440  * For more info see \ref MEDCouplingArrayApplyFunc0.
4441  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4442  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4443  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4444  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4445  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4446  *          same number of tuples and components as \a this array.
4447  *          The caller is to delete this result array using decrRef() as it is no more
4448  *          needed.
4449  *  \sa applyFuncOnThis
4450  *  \throw If \a this is not allocated.
4451  *  \throw If computing \a func fails.
4452  */
4453 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4454 {
4455   int nbOfComp(getNumberOfComponents());
4456   if(nbOfComp<=0)
4457     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4458   checkAllocated();
4459   int nbOfTuples(getNumberOfTuples());
4460   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4461   newArr->alloc(nbOfTuples,nbOfComp);
4462   INTERP_KERNEL::ExprParser expr(func);
4463   expr.parse();
4464   std::set<std::string> vars;
4465   expr.getTrueSetOfVars(vars);
4466   if((int)vars.size()>1)
4467     {
4468       std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : ";
4469       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4470       throw INTERP_KERNEL::Exception(oss.str().c_str());
4471     }
4472   if(vars.empty())
4473     {
4474       expr.prepareFastEvaluator();
4475       newArr->rearrange(1);
4476       newArr->fillWithValue(expr.evaluateDouble());
4477       newArr->rearrange(nbOfComp);
4478       return newArr.retn();
4479     }
4480   std::vector<std::string> vars2(vars.begin(),vars.end());
4481   double buff,*ptrToFill(newArr->getPointer());
4482   const double *ptr(begin());
4483   std::vector<double> stck;
4484   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4485   expr.prepareFastEvaluator();
4486   if(!isSafe)
4487     {
4488       for(int i=0;i<nbOfTuples;i++)
4489         {
4490           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4491             {
4492               buff=*ptr;
4493               expr.evaluateDoubleInternal(stck);
4494               *ptrToFill=stck.back();
4495               stck.pop_back();
4496             }
4497         }
4498     }
4499   else
4500     {
4501       for(int i=0;i<nbOfTuples;i++)
4502         {
4503           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4504             {
4505               buff=*ptr;
4506               try
4507               {
4508                   expr.evaluateDoubleInternalSafe(stck);
4509               }
4510               catch(INTERP_KERNEL::Exception& e)
4511               {
4512                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4513                   oss << buff;
4514                   oss << ") : Evaluation of function failed !" << e.what();
4515                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4516               }
4517               *ptrToFill=stck.back();
4518               stck.pop_back();
4519             }
4520         }
4521     }
4522   return newArr.retn();
4523 }
4524
4525 /*!
4526  * This method is a non const method that modify the array in \a this.
4527  * This method only works on one component array. It means that function \a func must
4528  * contain at most one variable.
4529  * This method is a specialization of applyFunc method with one parameter on one component array.
4530  *
4531  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4532  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4533  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4534  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4535  *
4536  * \sa applyFunc
4537  */
4538 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4539 {
4540   int nbOfComp(getNumberOfComponents());
4541   if(nbOfComp<=0)
4542     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4543   checkAllocated();
4544   int nbOfTuples(getNumberOfTuples());
4545   INTERP_KERNEL::ExprParser expr(func);
4546   expr.parse();
4547   std::set<std::string> vars;
4548   expr.getTrueSetOfVars(vars);
4549   if((int)vars.size()>1)
4550     {
4551       std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : ";
4552       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4553       throw INTERP_KERNEL::Exception(oss.str().c_str());
4554     }
4555   if(vars.empty())
4556     {
4557       expr.prepareFastEvaluator();
4558       std::vector<std::string> compInfo(getInfoOnComponents());
4559       rearrange(1);
4560       fillWithValue(expr.evaluateDouble());
4561       rearrange(nbOfComp);
4562       setInfoOnComponents(compInfo);
4563       return ;
4564     }
4565   std::vector<std::string> vars2(vars.begin(),vars.end());
4566   double buff,*ptrToFill(getPointer());
4567   const double *ptr(begin());
4568   std::vector<double> stck;
4569   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4570   expr.prepareFastEvaluator();
4571   if(!isSafe)
4572     {
4573       for(int i=0;i<nbOfTuples;i++)
4574         {
4575           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4576             {
4577               buff=*ptr;
4578               expr.evaluateDoubleInternal(stck);
4579               *ptrToFill=stck.back();
4580               stck.pop_back();
4581             }
4582         }
4583     }
4584   else
4585     {
4586       for(int i=0;i<nbOfTuples;i++)
4587         {
4588           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4589             {
4590               buff=*ptr;
4591               try
4592               {
4593                   expr.evaluateDoubleInternalSafe(stck);
4594               }
4595               catch(INTERP_KERNEL::Exception& e)
4596               {
4597                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4598                   oss << buff;
4599                   oss << ") : Evaluation of function failed !" << e.what();
4600                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4601               }
4602               *ptrToFill=stck.back();
4603               stck.pop_back();
4604             }
4605         }
4606     }
4607 }
4608
4609 /*!
4610  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4611  * tuple of \a this array. Textual data is not copied.
4612  * For more info see \ref MEDCouplingArrayApplyFunc2.
4613  *  \param [in] nbOfComp - number of components in the result array.
4614  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4615  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4616  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4617  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4618  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4619  *          same number of tuples as \a this array.
4620  *          The caller is to delete this result array using decrRef() as it is no more
4621  *          needed.
4622  *  \throw If \a this is not allocated.
4623  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4624  *  \throw If computing \a func fails.
4625  */
4626 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const
4627 {
4628   return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe);
4629 }
4630
4631 /*!
4632  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4633  * tuple of \a this array. Textual data is not copied.
4634  * For more info see \ref MEDCouplingArrayApplyFunc3.
4635  *  \param [in] nbOfComp - number of components in the result array.
4636  *  \param [in] varsOrder - sequence of vars defining their order.
4637  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4638  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4639  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4640  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4641  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4642  *          same number of tuples as \a this array.
4643  *          The caller is to delete this result array using decrRef() as it is no more
4644  *          needed.
4645  *  \throw If \a this is not allocated.
4646  *  \throw If \a func contains vars not in \a varsOrder.
4647  *  \throw If computing \a func fails.
4648  */
4649 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4650 {
4651   if(nbOfComp<=0)
4652     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !");
4653   std::vector<std::string> varsOrder2(varsOrder);
4654   int oldNbOfComp(getNumberOfComponents());
4655   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4656     varsOrder2.push_back(std::string());
4657   checkAllocated();
4658   int nbOfTuples(getNumberOfTuples());
4659   INTERP_KERNEL::ExprParser expr(func);
4660   expr.parse();
4661   std::set<std::string> vars;
4662   expr.getTrueSetOfVars(vars);
4663   if((int)vars.size()>oldNbOfComp)
4664     {
4665       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4666       oss << vars.size() << " variables : ";
4667       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4668       throw INTERP_KERNEL::Exception(oss.str().c_str());
4669     }
4670   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4671   newArr->alloc(nbOfTuples,nbOfComp);
4672   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4673   double *buffPtr(buff),*ptrToFill;
4674   std::vector<double> stck;
4675   for(int iComp=0;iComp<nbOfComp;iComp++)
4676     {
4677       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4678       expr.prepareFastEvaluator();
4679       const double *ptr(getConstPointer());
4680       ptrToFill=newArr->getPointer()+iComp;
4681       if(!isSafe)
4682         {
4683           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4684             {
4685               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4686               expr.evaluateDoubleInternal(stck);
4687               *ptrToFill=stck.back();
4688               stck.pop_back();
4689             }
4690         }
4691       else
4692         {
4693           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4694             {
4695               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4696               try
4697               {
4698                   expr.evaluateDoubleInternalSafe(stck);
4699                   *ptrToFill=stck.back();
4700                   stck.pop_back();
4701               }
4702               catch(INTERP_KERNEL::Exception& e)
4703               {
4704                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4705                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4706                   oss << ") : Evaluation of function failed !" << e.what();
4707                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4708               }
4709             }
4710         }
4711     }
4712   return newArr.retn();
4713 }
4714
4715 void DataArrayDouble::applyFuncFast32(const std::string& func)
4716 {
4717   checkAllocated();
4718   INTERP_KERNEL::ExprParser expr(func);
4719   expr.parse();
4720   char *funcStr=expr.compileX86();
4721   MYFUNCPTR funcPtr;
4722   *((void **)&funcPtr)=funcStr;//he he...
4723   //
4724   double *ptr=getPointer();
4725   int nbOfComp=getNumberOfComponents();
4726   int nbOfTuples=getNumberOfTuples();
4727   int nbOfElems=nbOfTuples*nbOfComp;
4728   for(int i=0;i<nbOfElems;i++,ptr++)
4729     *ptr=funcPtr(*ptr);
4730   declareAsNew();
4731 }
4732
4733 void DataArrayDouble::applyFuncFast64(const std::string& func)
4734 {
4735   checkAllocated();
4736   INTERP_KERNEL::ExprParser expr(func);
4737   expr.parse();
4738   char *funcStr=expr.compileX86_64();
4739   MYFUNCPTR funcPtr;
4740   *((void **)&funcPtr)=funcStr;//he he...
4741   //
4742   double *ptr=getPointer();
4743   int nbOfComp=getNumberOfComponents();
4744   int nbOfTuples=getNumberOfTuples();
4745   int nbOfElems=nbOfTuples*nbOfComp;
4746   for(int i=0;i<nbOfElems;i++,ptr++)
4747     *ptr=funcPtr(*ptr);
4748   declareAsNew();
4749 }
4750
4751 DataArrayDoubleIterator *DataArrayDouble::iterator()
4752 {
4753   return new DataArrayDoubleIterator(this);
4754 }
4755
4756 /*!
4757  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4758  * array whose values are within a given range. Textual data is not copied.
4759  *  \param [in] vmin - a lowest acceptable value (included).
4760  *  \param [in] vmax - a greatest acceptable value (included).
4761  *  \return DataArrayInt * - the new instance of DataArrayInt.
4762  *          The caller is to delete this result array using decrRef() as it is no more
4763  *          needed.
4764  *  \throw If \a this->getNumberOfComponents() != 1.
4765  *
4766  *  \sa DataArrayDouble::getIdsNotInRange
4767  *
4768  *  \if ENABLE_EXAMPLES
4769  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4770  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4771  *  \endif
4772  */
4773 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4774 {
4775   checkAllocated();
4776   if(getNumberOfComponents()!=1)
4777     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4778   const double *cptr(begin());
4779   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4780   int nbOfTuples(getNumberOfTuples());
4781   for(int i=0;i<nbOfTuples;i++,cptr++)
4782     if(*cptr>=vmin && *cptr<=vmax)
4783       ret->pushBackSilent(i);
4784   return ret.retn();
4785 }
4786
4787 /*!
4788  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4789  * array whose values are not within a given range. Textual data is not copied.
4790  *  \param [in] vmin - a lowest not acceptable value (excluded).
4791  *  \param [in] vmax - a greatest not acceptable value (excluded).
4792  *  \return DataArrayInt * - the new instance of DataArrayInt.
4793  *          The caller is to delete this result array using decrRef() as it is no more
4794  *          needed.
4795  *  \throw If \a this->getNumberOfComponents() != 1.
4796  *
4797  *  \sa DataArrayDouble::getIdsInRange
4798  */
4799 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4800 {
4801   checkAllocated();
4802   if(getNumberOfComponents()!=1)
4803     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4804   const double *cptr(begin());
4805   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4806   int nbOfTuples(getNumberOfTuples());
4807   for(int i=0;i<nbOfTuples;i++,cptr++)
4808     if(*cptr<vmin || *cptr>vmax)
4809       ret->pushBackSilent(i);
4810   return ret.retn();
4811 }
4812
4813 /*!
4814  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4815  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4816  * the number of component in the result array is same as that of each of given arrays.
4817  * Info on components is copied from the first of the given arrays. Number of components
4818  * in the given arrays must be  the same.
4819  *  \param [in] a1 - an array to include in the result array.
4820  *  \param [in] a2 - another array to include in the result array.
4821  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4822  *          The caller is to delete this result array using decrRef() as it is no more
4823  *          needed.
4824  *  \throw If both \a a1 and \a a2 are NULL.
4825  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4826  */
4827 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4828 {
4829   std::vector<const DataArrayDouble *> tmp(2);
4830   tmp[0]=a1; tmp[1]=a2;
4831   return Aggregate(tmp);
4832 }
4833
4834 /*!
4835  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4836  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4837  * the number of component in the result array is same as that of each of given arrays.
4838  * Info on components is copied from the first of the given arrays. Number of components
4839  * in the given arrays must be  the same.
4840  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4841  * not the object itself.
4842  *  \param [in] arr - a sequence of arrays to include in the result array.
4843  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4844  *          The caller is to delete this result array using decrRef() as it is no more
4845  *          needed.
4846  *  \throw If all arrays within \a arr are NULL.
4847  *  \throw If getNumberOfComponents() of arrays within \a arr.
4848  */
4849 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4850 {
4851   std::vector<const DataArrayDouble *> a;
4852   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4853     if(*it4)
4854       a.push_back(*it4);
4855   if(a.empty())
4856     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4857   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4858   int nbOfComp=(*it)->getNumberOfComponents();
4859   int nbt=(*it++)->getNumberOfTuples();
4860   for(int i=1;it!=a.end();it++,i++)
4861     {
4862       if((*it)->getNumberOfComponents()!=nbOfComp)
4863         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4864       nbt+=(*it)->getNumberOfTuples();
4865     }
4866   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4867   ret->alloc(nbt,nbOfComp);
4868   double *pt=ret->getPointer();
4869   for(it=a.begin();it!=a.end();it++)
4870     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4871   ret->copyStringInfoFrom(*(a[0]));
4872   return ret.retn();
4873 }
4874
4875 /*!
4876  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4877  * of components in the result array is a sum of the number of components of given arrays
4878  * and (2) the number of tuples in the result array is same as that of each of given
4879  * arrays. In other words the i-th tuple of result array includes all components of
4880  * i-th tuples of all given arrays.
4881  * Number of tuples in the given arrays must be  the same.
4882  *  \param [in] a1 - an array to include in the result array.
4883  *  \param [in] a2 - another array to include in the result array.
4884  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4885  *          The caller is to delete this result array using decrRef() as it is no more
4886  *          needed.
4887  *  \throw If both \a a1 and \a a2 are NULL.
4888  *  \throw If any given array is not allocated.
4889  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4890  */
4891 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4892 {
4893   std::vector<const DataArrayDouble *> arr(2);
4894   arr[0]=a1; arr[1]=a2;
4895   return Meld(arr);
4896 }
4897
4898 /*!
4899  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4900  * of components in the result array is a sum of the number of components of given arrays
4901  * and (2) the number of tuples in the result array is same as that of each of given
4902  * arrays. In other words the i-th tuple of result array includes all components of
4903  * i-th tuples of all given arrays.
4904  * Number of tuples in the given arrays must be  the same.
4905  *  \param [in] arr - a sequence of arrays to include in the result array.
4906  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4907  *          The caller is to delete this result array using decrRef() as it is no more
4908  *          needed.
4909  *  \throw If all arrays within \a arr are NULL.
4910  *  \throw If any given array is not allocated.
4911  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4912  */
4913 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4914 {
4915   std::vector<const DataArrayDouble *> a;
4916   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4917     if(*it4)
4918       a.push_back(*it4);
4919   if(a.empty())
4920     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4921   std::vector<const DataArrayDouble *>::const_iterator it;
4922   for(it=a.begin();it!=a.end();it++)
4923     (*it)->checkAllocated();
4924   it=a.begin();
4925   int nbOfTuples=(*it)->getNumberOfTuples();
4926   std::vector<int> nbc(a.size());
4927   std::vector<const double *> pts(a.size());
4928   nbc[0]=(*it)->getNumberOfComponents();
4929   pts[0]=(*it++)->getConstPointer();
4930   for(int i=1;it!=a.end();it++,i++)
4931     {
4932       if(nbOfTuples!=(*it)->getNumberOfTuples())
4933         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4934       nbc[i]=(*it)->getNumberOfComponents();
4935       pts[i]=(*it)->getConstPointer();
4936     }
4937   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4938   DataArrayDouble *ret=DataArrayDouble::New();
4939   ret->alloc(nbOfTuples,totalNbOfComp);
4940   double *retPtr=ret->getPointer();
4941   for(int i=0;i<nbOfTuples;i++)
4942     for(int j=0;j<(int)a.size();j++)
4943       {
4944         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4945         pts[j]+=nbc[j];
4946       }
4947   int k=0;
4948   for(int i=0;i<(int)a.size();i++)
4949     for(int j=0;j<nbc[i];j++,k++)
4950       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4951   return ret;
4952 }
4953
4954 /*!
4955  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4956  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4957  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4958  * Info on components and name is copied from the first of the given arrays.
4959  * Number of tuples and components in the given arrays must be the same.
4960  *  \param [in] a1 - a given array.
4961  *  \param [in] a2 - another given array.
4962  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4963  *          The caller is to delete this result array using decrRef() as it is no more
4964  *          needed.
4965  *  \throw If either \a a1 or \a a2 is NULL.
4966  *  \throw If any given array is not allocated.
4967  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4968  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4969  */
4970 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4971 {
4972   if(!a1 || !a2)
4973     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4974   a1->checkAllocated();
4975   a2->checkAllocated();
4976   int nbOfComp=a1->getNumberOfComponents();
4977   if(nbOfComp!=a2->getNumberOfComponents())
4978     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4979   int nbOfTuple=a1->getNumberOfTuples();
4980   if(nbOfTuple!=a2->getNumberOfTuples())
4981     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4982   DataArrayDouble *ret=DataArrayDouble::New();
4983   ret->alloc(nbOfTuple,1);
4984   double *retPtr=ret->getPointer();
4985   const double *a1Ptr=a1->getConstPointer();
4986   const double *a2Ptr=a2->getConstPointer();
4987   for(int i=0;i<nbOfTuple;i++)
4988     {
4989       double sum=0.;
4990       for(int j=0;j<nbOfComp;j++)
4991         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4992       retPtr[i]=sum;
4993     }
4994   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4995   ret->setName(a1->getName());
4996   return ret;
4997 }
4998
4999 /*!
5000  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
5001  * the i-th tuple of the result array contains 3 components of a vector which is a cross
5002  * product of two vectors defined by the i-th tuples of given arrays.
5003  * Info on components is copied from the first of the given arrays.
5004  * Number of tuples in the given arrays must be the same.
5005  * Number of components in the given arrays must be 3.
5006  *  \param [in] a1 - a given array.
5007  *  \param [in] a2 - another given array.
5008  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5009  *          The caller is to delete this result array using decrRef() as it is no more
5010  *          needed.
5011  *  \throw If either \a a1 or \a a2 is NULL.
5012  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5013  *  \throw If \a a1->getNumberOfComponents() != 3
5014  *  \throw If \a a2->getNumberOfComponents() != 3
5015  */
5016 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
5017 {
5018   if(!a1 || !a2)
5019     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
5020   int nbOfComp=a1->getNumberOfComponents();
5021   if(nbOfComp!=a2->getNumberOfComponents())
5022     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
5023   if(nbOfComp!=3)
5024     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
5025   int nbOfTuple=a1->getNumberOfTuples();
5026   if(nbOfTuple!=a2->getNumberOfTuples())
5027     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
5028   DataArrayDouble *ret=DataArrayDouble::New();
5029   ret->alloc(nbOfTuple,3);
5030   double *retPtr=ret->getPointer();
5031   const double *a1Ptr=a1->getConstPointer();
5032   const double *a2Ptr=a2->getConstPointer();
5033   for(int i=0;i<nbOfTuple;i++)
5034     {
5035       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
5036       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
5037       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
5038     }
5039   ret->copyStringInfoFrom(*a1);
5040   return ret;
5041 }
5042
5043 /*!
5044  * Returns a new DataArrayDouble containing maximal values of two given arrays.
5045  * Info on components is copied from the first of the given arrays.
5046  * Number of tuples and components in the given arrays must be the same.
5047  *  \param [in] a1 - an array to compare values with another one.
5048  *  \param [in] a2 - another array to compare values with the first one.
5049  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5050  *          The caller is to delete this result array using decrRef() as it is no more
5051  *          needed.
5052  *  \throw If either \a a1 or \a a2 is NULL.
5053  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5054  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5055  */
5056 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
5057 {
5058   if(!a1 || !a2)
5059     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
5060   int nbOfComp=a1->getNumberOfComponents();
5061   if(nbOfComp!=a2->getNumberOfComponents())
5062     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
5063   int nbOfTuple=a1->getNumberOfTuples();
5064   if(nbOfTuple!=a2->getNumberOfTuples())
5065     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
5066   DataArrayDouble *ret=DataArrayDouble::New();
5067   ret->alloc(nbOfTuple,nbOfComp);
5068   double *retPtr=ret->getPointer();
5069   const double *a1Ptr=a1->getConstPointer();
5070   const double *a2Ptr=a2->getConstPointer();
5071   int nbElem=nbOfTuple*nbOfComp;
5072   for(int i=0;i<nbElem;i++)
5073     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
5074   ret->copyStringInfoFrom(*a1);
5075   return ret;
5076 }
5077
5078 /*!
5079  * Returns a new DataArrayDouble containing minimal values of two given arrays.
5080  * Info on components is copied from the first of the given arrays.
5081  * Number of tuples and components in the given arrays must be the same.
5082  *  \param [in] a1 - an array to compare values with another one.
5083  *  \param [in] a2 - another array to compare values with the first one.
5084  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5085  *          The caller is to delete this result array using decrRef() as it is no more
5086  *          needed.
5087  *  \throw If either \a a1 or \a a2 is NULL.
5088  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5089  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5090  */
5091 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
5092 {
5093   if(!a1 || !a2)
5094     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
5095   int nbOfComp=a1->getNumberOfComponents();
5096   if(nbOfComp!=a2->getNumberOfComponents())
5097     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5098   int nbOfTuple=a1->getNumberOfTuples();
5099   if(nbOfTuple!=a2->getNumberOfTuples())
5100     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5101   DataArrayDouble *ret=DataArrayDouble::New();
5102   ret->alloc(nbOfTuple,nbOfComp);
5103   double *retPtr=ret->getPointer();
5104   const double *a1Ptr=a1->getConstPointer();
5105   const double *a2Ptr=a2->getConstPointer();
5106   int nbElem=nbOfTuple*nbOfComp;
5107   for(int i=0;i<nbElem;i++)
5108     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5109   ret->copyStringInfoFrom(*a1);
5110   return ret;
5111 }
5112
5113 /*!
5114  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5115  * valid cases.
5116  * 1.  The arrays have same number of tuples and components. Then each value of
5117  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5118  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5119  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5120  *   component. Then
5121  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5122  * 3.  The arrays have same number of components and one array, say _a2_, has one
5123  *   tuple. Then
5124  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5125  *
5126  * Info on components is copied either from the first array (in the first case) or from
5127  * the array with maximal number of elements (getNbOfElems()).
5128  *  \param [in] a1 - an array to sum up.
5129  *  \param [in] a2 - another array to sum up.
5130  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5131  *          The caller is to delete this result array using decrRef() as it is no more
5132  *          needed.
5133  *  \throw If either \a a1 or \a a2 is NULL.
5134  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5135  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5136  *         none of them has number of tuples or components equal to 1.
5137  */
5138 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5139 {
5140   if(!a1 || !a2)
5141     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5142   int nbOfTuple=a1->getNumberOfTuples();
5143   int nbOfTuple2=a2->getNumberOfTuples();
5144   int nbOfComp=a1->getNumberOfComponents();
5145   int nbOfComp2=a2->getNumberOfComponents();
5146   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5147   if(nbOfTuple==nbOfTuple2)
5148     {
5149       if(nbOfComp==nbOfComp2)
5150         {
5151           ret=DataArrayDouble::New();
5152           ret->alloc(nbOfTuple,nbOfComp);
5153           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5154           ret->copyStringInfoFrom(*a1);
5155         }
5156       else
5157         {
5158           int nbOfCompMin,nbOfCompMax;
5159           const DataArrayDouble *aMin, *aMax;
5160           if(nbOfComp>nbOfComp2)
5161             {
5162               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5163               aMin=a2; aMax=a1;
5164             }
5165           else
5166             {
5167               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5168               aMin=a1; aMax=a2;
5169             }
5170           if(nbOfCompMin==1)
5171             {
5172               ret=DataArrayDouble::New();
5173               ret->alloc(nbOfTuple,nbOfCompMax);
5174               const double *aMinPtr=aMin->getConstPointer();
5175               const double *aMaxPtr=aMax->getConstPointer();
5176               double *res=ret->getPointer();
5177               for(int i=0;i<nbOfTuple;i++)
5178                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5179               ret->copyStringInfoFrom(*aMax);
5180             }
5181           else
5182             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5183         }
5184     }
5185   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5186     {
5187       if(nbOfComp==nbOfComp2)
5188         {
5189           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5190           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5191           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5192           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5193           ret=DataArrayDouble::New();
5194           ret->alloc(nbOfTupleMax,nbOfComp);
5195           double *res=ret->getPointer();
5196           for(int i=0;i<nbOfTupleMax;i++)
5197             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5198           ret->copyStringInfoFrom(*aMax);
5199         }
5200       else
5201         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5202     }
5203   else
5204     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5205   return ret.retn();
5206 }
5207
5208 /*!
5209  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5210  * valid cases.
5211  * 1.  The arrays have same number of tuples and components. Then each value of
5212  *   \a other array is added to the corresponding value of \a this array, i.e.:
5213  *   _a_ [ i, j ] += _other_ [ i, j ].
5214  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5215  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5216  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5217  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5218  *
5219  *  \param [in] other - an array to add to \a this one.
5220  *  \throw If \a other is NULL.
5221  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5222  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5223  *         \a other has number of both tuples and components not equal to 1.
5224  */
5225 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5226 {
5227   if(!other)
5228     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5229   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5230   checkAllocated();
5231   other->checkAllocated();
5232   int nbOfTuple=getNumberOfTuples();
5233   int nbOfTuple2=other->getNumberOfTuples();
5234   int nbOfComp=getNumberOfComponents();
5235   int nbOfComp2=other->getNumberOfComponents();
5236   if(nbOfTuple==nbOfTuple2)
5237     {
5238       if(nbOfComp==nbOfComp2)
5239         {
5240           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5241         }
5242       else if(nbOfComp2==1)
5243         {
5244           double *ptr=getPointer();
5245           const double *ptrc=other->getConstPointer();
5246           for(int i=0;i<nbOfTuple;i++)
5247             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5248         }
5249       else
5250         throw INTERP_KERNEL::Exception(msg);
5251     }
5252   else if(nbOfTuple2==1)
5253     {
5254       if(nbOfComp2==nbOfComp)
5255         {
5256           double *ptr=getPointer();
5257           const double *ptrc=other->getConstPointer();
5258           for(int i=0;i<nbOfTuple;i++)
5259             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5260         }
5261       else
5262         throw INTERP_KERNEL::Exception(msg);
5263     }
5264   else
5265     throw INTERP_KERNEL::Exception(msg);
5266   declareAsNew();
5267 }
5268
5269 /*!
5270  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5271  * valid cases.
5272  * 1.  The arrays have same number of tuples and components. Then each value of
5273  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5274  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5275  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5276  *   component. Then
5277  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5278  * 3.  The arrays have same number of components and one array, say _a2_, has one
5279  *   tuple. Then
5280  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5281  *
5282  * Info on components is copied either from the first array (in the first case) or from
5283  * the array with maximal number of elements (getNbOfElems()).
5284  *  \param [in] a1 - an array to subtract from.
5285  *  \param [in] a2 - an array to subtract.
5286  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5287  *          The caller is to delete this result array using decrRef() as it is no more
5288  *          needed.
5289  *  \throw If either \a a1 or \a a2 is NULL.
5290  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5291  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5292  *         none of them has number of tuples or components equal to 1.
5293  */
5294 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5295 {
5296   if(!a1 || !a2)
5297     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5298   int nbOfTuple1=a1->getNumberOfTuples();
5299   int nbOfTuple2=a2->getNumberOfTuples();
5300   int nbOfComp1=a1->getNumberOfComponents();
5301   int nbOfComp2=a2->getNumberOfComponents();
5302   if(nbOfTuple2==nbOfTuple1)
5303     {
5304       if(nbOfComp1==nbOfComp2)
5305         {
5306           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5307           ret->alloc(nbOfTuple2,nbOfComp1);
5308           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5309           ret->copyStringInfoFrom(*a1);
5310           return ret.retn();
5311         }
5312       else if(nbOfComp2==1)
5313         {
5314           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5315           ret->alloc(nbOfTuple1,nbOfComp1);
5316           const double *a2Ptr=a2->getConstPointer();
5317           const double *a1Ptr=a1->getConstPointer();
5318           double *res=ret->getPointer();
5319           for(int i=0;i<nbOfTuple1;i++)
5320             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5321           ret->copyStringInfoFrom(*a1);
5322           return ret.retn();
5323         }
5324       else
5325         {
5326           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5327           return 0;
5328         }
5329     }
5330   else if(nbOfTuple2==1)
5331     {
5332       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5333       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5334       ret->alloc(nbOfTuple1,nbOfComp1);
5335       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5336       double *pt=ret->getPointer();
5337       for(int i=0;i<nbOfTuple1;i++)
5338         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5339       ret->copyStringInfoFrom(*a1);
5340       return ret.retn();
5341     }
5342   else
5343     {
5344       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5345       return 0;
5346     }
5347 }
5348
5349 /*!
5350  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5351  * valid cases.
5352  * 1.  The arrays have same number of tuples and components. Then each value of
5353  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5354  *   _a_ [ i, j ] -= _other_ [ i, j ].
5355  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5356  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5357  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5358  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5359  *
5360  *  \param [in] other - an array to subtract from \a this one.
5361  *  \throw If \a other is NULL.
5362  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5363  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5364  *         \a other has number of both tuples and components not equal to 1.
5365  */
5366 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5367 {
5368   if(!other)
5369     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5370   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5371   checkAllocated();
5372   other->checkAllocated();
5373   int nbOfTuple=getNumberOfTuples();
5374   int nbOfTuple2=other->getNumberOfTuples();
5375   int nbOfComp=getNumberOfComponents();
5376   int nbOfComp2=other->getNumberOfComponents();
5377   if(nbOfTuple==nbOfTuple2)
5378     {
5379       if(nbOfComp==nbOfComp2)
5380         {
5381           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5382         }
5383       else if(nbOfComp2==1)
5384         {
5385           double *ptr=getPointer();
5386           const double *ptrc=other->getConstPointer();
5387           for(int i=0;i<nbOfTuple;i++)
5388             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5389         }
5390       else
5391         throw INTERP_KERNEL::Exception(msg);
5392     }
5393   else if(nbOfTuple2==1)
5394     {
5395       if(nbOfComp2==nbOfComp)
5396         {
5397           double *ptr=getPointer();
5398           const double *ptrc=other->getConstPointer();
5399           for(int i=0;i<nbOfTuple;i++)
5400             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5401         }
5402       else
5403         throw INTERP_KERNEL::Exception(msg);
5404     }
5405   else
5406     throw INTERP_KERNEL::Exception(msg);
5407   declareAsNew();
5408 }
5409
5410 /*!
5411  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5412  * valid cases.
5413  * 1.  The arrays have same number of tuples and components. Then each value of
5414  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5415  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5416  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5417  *   component. Then
5418  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5419  * 3.  The arrays have same number of components and one array, say _a2_, has one
5420  *   tuple. Then
5421  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5422  *
5423  * Info on components is copied either from the first array (in the first case) or from
5424  * the array with maximal number of elements (getNbOfElems()).
5425  *  \param [in] a1 - a factor array.
5426  *  \param [in] a2 - another factor array.
5427  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5428  *          The caller is to delete this result array using decrRef() as it is no more
5429  *          needed.
5430  *  \throw If either \a a1 or \a a2 is NULL.
5431  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5432  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5433  *         none of them has number of tuples or components equal to 1.
5434  */
5435 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5436 {
5437   if(!a1 || !a2)
5438     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5439   int nbOfTuple=a1->getNumberOfTuples();
5440   int nbOfTuple2=a2->getNumberOfTuples();
5441   int nbOfComp=a1->getNumberOfComponents();
5442   int nbOfComp2=a2->getNumberOfComponents();
5443   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5444   if(nbOfTuple==nbOfTuple2)
5445     {
5446       if(nbOfComp==nbOfComp2)
5447         {
5448           ret=DataArrayDouble::New();
5449           ret->alloc(nbOfTuple,nbOfComp);
5450           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5451           ret->copyStringInfoFrom(*a1);
5452         }
5453       else
5454         {
5455           int nbOfCompMin,nbOfCompMax;
5456           const DataArrayDouble *aMin, *aMax;
5457           if(nbOfComp>nbOfComp2)
5458             {
5459               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5460               aMin=a2; aMax=a1;
5461             }
5462           else
5463             {
5464               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5465               aMin=a1; aMax=a2;
5466             }
5467           if(nbOfCompMin==1)
5468             {
5469               ret=DataArrayDouble::New();
5470               ret->alloc(nbOfTuple,nbOfCompMax);
5471               const double *aMinPtr=aMin->getConstPointer();
5472               const double *aMaxPtr=aMax->getConstPointer();
5473               double *res=ret->getPointer();
5474               for(int i=0;i<nbOfTuple;i++)
5475                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5476               ret->copyStringInfoFrom(*aMax);
5477             }
5478           else
5479             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5480         }
5481     }
5482   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5483     {
5484       if(nbOfComp==nbOfComp2)
5485         {
5486           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5487           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5488           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5489           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5490           ret=DataArrayDouble::New();
5491           ret->alloc(nbOfTupleMax,nbOfComp);
5492           double *res=ret->getPointer();
5493           for(int i=0;i<nbOfTupleMax;i++)
5494             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5495           ret->copyStringInfoFrom(*aMax);
5496         }
5497       else
5498         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5499     }
5500   else
5501     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5502   return ret.retn();
5503 }
5504
5505 /*!
5506  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5507  * valid cases.
5508  * 1.  The arrays have same number of tuples and components. Then each value of
5509  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5510  *   _this_ [ i, j ] *= _other_ [ i, j ].
5511  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5512  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5513  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5514  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5515  *
5516  *  \param [in] other - an array to multiply to \a this one.
5517  *  \throw If \a other is NULL.
5518  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5519  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5520  *         \a other has number of both tuples and components not equal to 1.
5521  */
5522 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5523 {
5524   if(!other)
5525     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5526   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5527   checkAllocated();
5528   other->checkAllocated();
5529   int nbOfTuple=getNumberOfTuples();
5530   int nbOfTuple2=other->getNumberOfTuples();
5531   int nbOfComp=getNumberOfComponents();
5532   int nbOfComp2=other->getNumberOfComponents();
5533   if(nbOfTuple==nbOfTuple2)
5534     {
5535       if(nbOfComp==nbOfComp2)
5536         {
5537           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5538         }
5539       else if(nbOfComp2==1)
5540         {
5541           double *ptr=getPointer();
5542           const double *ptrc=other->getConstPointer();
5543           for(int i=0;i<nbOfTuple;i++)
5544             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5545         }
5546       else
5547         throw INTERP_KERNEL::Exception(msg);
5548     }
5549   else if(nbOfTuple2==1)
5550     {
5551       if(nbOfComp2==nbOfComp)
5552         {
5553           double *ptr=getPointer();
5554           const double *ptrc=other->getConstPointer();
5555           for(int i=0;i<nbOfTuple;i++)
5556             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5557         }
5558       else
5559         throw INTERP_KERNEL::Exception(msg);
5560     }
5561   else
5562     throw INTERP_KERNEL::Exception(msg);
5563   declareAsNew();
5564 }
5565
5566 /*!
5567  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5568  * valid cases.
5569  * 1.  The arrays have same number of tuples and components. Then each value of
5570  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5571  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5572  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5573  *   component. Then
5574  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5575  * 3.  The arrays have same number of components and one array, say _a2_, has one
5576  *   tuple. Then
5577  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5578  *
5579  * Info on components is copied either from the first array (in the first case) or from
5580  * the array with maximal number of elements (getNbOfElems()).
5581  *  \warning No check of division by zero is performed!
5582  *  \param [in] a1 - a numerator array.
5583  *  \param [in] a2 - a denominator array.
5584  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5585  *          The caller is to delete this result array using decrRef() as it is no more
5586  *          needed.
5587  *  \throw If either \a a1 or \a a2 is NULL.
5588  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5589  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5590  *         none of them has number of tuples or components equal to 1.
5591  */
5592 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5593 {
5594   if(!a1 || !a2)
5595     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5596   int nbOfTuple1=a1->getNumberOfTuples();
5597   int nbOfTuple2=a2->getNumberOfTuples();
5598   int nbOfComp1=a1->getNumberOfComponents();
5599   int nbOfComp2=a2->getNumberOfComponents();
5600   if(nbOfTuple2==nbOfTuple1)
5601     {
5602       if(nbOfComp1==nbOfComp2)
5603         {
5604           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5605           ret->alloc(nbOfTuple2,nbOfComp1);
5606           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5607           ret->copyStringInfoFrom(*a1);
5608           return ret.retn();
5609         }
5610       else if(nbOfComp2==1)
5611         {
5612           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5613           ret->alloc(nbOfTuple1,nbOfComp1);
5614           const double *a2Ptr=a2->getConstPointer();
5615           const double *a1Ptr=a1->getConstPointer();
5616           double *res=ret->getPointer();
5617           for(int i=0;i<nbOfTuple1;i++)
5618             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5619           ret->copyStringInfoFrom(*a1);
5620           return ret.retn();
5621         }
5622       else
5623         {
5624           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5625           return 0;
5626         }
5627     }
5628   else if(nbOfTuple2==1)
5629     {
5630       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5631       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5632       ret->alloc(nbOfTuple1,nbOfComp1);
5633       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5634       double *pt=ret->getPointer();
5635       for(int i=0;i<nbOfTuple1;i++)
5636         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5637       ret->copyStringInfoFrom(*a1);
5638       return ret.retn();
5639     }
5640   else
5641     {
5642       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5643       return 0;
5644     }
5645 }
5646
5647 /*!
5648  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5649  * valid cases.
5650  * 1.  The arrays have same number of tuples and components. Then each value of
5651  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5652  *   _a_ [ i, j ] /= _other_ [ i, j ].
5653  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5654  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5655  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5656  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5657  *
5658  *  \warning No check of division by zero is performed!
5659  *  \param [in] other - an array to divide \a this one by.
5660  *  \throw If \a other is NULL.
5661  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5662  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5663  *         \a other has number of both tuples and components not equal to 1.
5664  */
5665 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5666 {
5667   if(!other)
5668     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5669   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5670   checkAllocated();
5671   other->checkAllocated();
5672   int nbOfTuple=getNumberOfTuples();
5673   int nbOfTuple2=other->getNumberOfTuples();
5674   int nbOfComp=getNumberOfComponents();
5675   int nbOfComp2=other->getNumberOfComponents();
5676   if(nbOfTuple==nbOfTuple2)
5677     {
5678       if(nbOfComp==nbOfComp2)
5679         {
5680           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5681         }
5682       else if(nbOfComp2==1)
5683         {
5684           double *ptr=getPointer();
5685           const double *ptrc=other->getConstPointer();
5686           for(int i=0;i<nbOfTuple;i++)
5687             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5688         }
5689       else
5690         throw INTERP_KERNEL::Exception(msg);
5691     }
5692   else if(nbOfTuple2==1)
5693     {
5694       if(nbOfComp2==nbOfComp)
5695         {
5696           double *ptr=getPointer();
5697           const double *ptrc=other->getConstPointer();
5698           for(int i=0;i<nbOfTuple;i++)
5699             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5700         }
5701       else
5702         throw INTERP_KERNEL::Exception(msg);
5703     }
5704   else
5705     throw INTERP_KERNEL::Exception(msg);
5706   declareAsNew();
5707 }
5708
5709 /*!
5710  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5711  * valid cases.
5712  *
5713  *  \param [in] a1 - an array to pow up.
5714  *  \param [in] a2 - another array to sum up.
5715  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5716  *          The caller is to delete this result array using decrRef() as it is no more
5717  *          needed.
5718  *  \throw If either \a a1 or \a a2 is NULL.
5719  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5720  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5721  *  \throw If there is a negative value in \a a1.
5722  */
5723 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5724 {
5725   if(!a1 || !a2)
5726     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5727   int nbOfTuple=a1->getNumberOfTuples();
5728   int nbOfTuple2=a2->getNumberOfTuples();
5729   int nbOfComp=a1->getNumberOfComponents();
5730   int nbOfComp2=a2->getNumberOfComponents();
5731   if(nbOfTuple!=nbOfTuple2)
5732     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5733   if(nbOfComp!=1 || nbOfComp2!=1)
5734     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5735   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5736   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5737   double *ptr=ret->getPointer();
5738   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5739     {
5740       if(*ptr1>=0)
5741         {
5742           *ptr=pow(*ptr1,*ptr2);
5743         }
5744       else
5745         {
5746           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5747           throw INTERP_KERNEL::Exception(oss.str().c_str());
5748         }
5749     }
5750   return ret.retn();
5751 }
5752
5753 /*!
5754  * Apply pow on values of another DataArrayDouble to values of \a this one.
5755  *
5756  *  \param [in] other - an array to pow to \a this one.
5757  *  \throw If \a other is NULL.
5758  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5759  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5760  *  \throw If there is a negative value in \a this.
5761  */
5762 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5763 {
5764   if(!other)
5765     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5766   int nbOfTuple=getNumberOfTuples();
5767   int nbOfTuple2=other->getNumberOfTuples();
5768   int nbOfComp=getNumberOfComponents();
5769   int nbOfComp2=other->getNumberOfComponents();
5770   if(nbOfTuple!=nbOfTuple2)
5771     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5772   if(nbOfComp!=1 || nbOfComp2!=1)
5773     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5774   double *ptr=getPointer();
5775   const double *ptrc=other->begin();
5776   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5777     {
5778       if(*ptr>=0)
5779         *ptr=pow(*ptr,*ptrc);
5780       else
5781         {
5782           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5783           throw INTERP_KERNEL::Exception(oss.str().c_str());
5784         }
5785     }
5786   declareAsNew();
5787 }
5788
5789 /*!
5790  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5791  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5792  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5793  *
5794  * \throw if \a this is not allocated.
5795  * \throw if \a this has not exactly one component.
5796  */
5797 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5798 {
5799   checkAllocated();
5800   if(getNumberOfComponents()!=1)
5801     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5802   int nbt(getNumberOfTuples());
5803   std::vector<bool> ret(nbt);
5804   const double *pt(begin());
5805   for(int i=0;i<nbt;i++)
5806     {
5807       if(fabs(pt[i])<eps)
5808         ret[i]=false;
5809       else if(fabs(pt[i]-1.)<eps)
5810         ret[i]=true;
5811       else
5812         {
5813           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5814           throw INTERP_KERNEL::Exception(oss.str().c_str());
5815         }
5816     }
5817   return ret;
5818 }
5819
5820 /*!
5821  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5822  * Server side.
5823  */
5824 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5825 {
5826   tinyInfo.resize(2);
5827   if(isAllocated())
5828     {
5829       tinyInfo[0]=getNumberOfTuples();
5830       tinyInfo[1]=getNumberOfComponents();
5831     }
5832   else
5833     {
5834       tinyInfo[0]=-1;
5835       tinyInfo[1]=-1;
5836     }
5837 }
5838
5839 /*!
5840  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5841  * Server side.
5842  */
5843 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5844 {
5845   if(isAllocated())
5846     {
5847       int nbOfCompo=getNumberOfComponents();
5848       tinyInfo.resize(nbOfCompo+1);
5849       tinyInfo[0]=getName();
5850       for(int i=0;i<nbOfCompo;i++)
5851         tinyInfo[i+1]=getInfoOnComponent(i);
5852     }
5853   else
5854     {
5855       tinyInfo.resize(1);
5856       tinyInfo[0]=getName();
5857     }
5858 }
5859
5860 /*!
5861  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5862  * This method returns if a feeding is needed.
5863  */
5864 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5865 {
5866   int nbOfTuple=tinyInfoI[0];
5867   int nbOfComp=tinyInfoI[1];
5868   if(nbOfTuple!=-1 || nbOfComp!=-1)
5869     {
5870       alloc(nbOfTuple,nbOfComp);
5871       return true;
5872     }
5873   return false;
5874 }
5875
5876 /*!
5877  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5878  */
5879 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5880 {
5881   setName(tinyInfoS[0]);
5882   if(isAllocated())
5883     {
5884       int nbOfCompo=getNumberOfComponents();
5885       for(int i=0;i<nbOfCompo;i++)
5886         setInfoOnComponent(i,tinyInfoS[i+1]);
5887     }
5888 }
5889
5890 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5891 {
5892   if(_da)
5893     {
5894       _da->incrRef();
5895       if(_da->isAllocated())
5896         {
5897           _nb_comp=da->getNumberOfComponents();
5898           _nb_tuple=da->getNumberOfTuples();
5899           _pt=da->getPointer();
5900         }
5901     }
5902 }
5903
5904 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5905 {
5906   if(_da)
5907     _da->decrRef();
5908 }
5909
5910 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5911 {
5912   if(_tuple_id<_nb_tuple)
5913     {
5914       _tuple_id++;
5915       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5916       _pt+=_nb_comp;
5917       return ret;
5918     }
5919   else
5920     return 0;
5921 }
5922
5923 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5924 {
5925 }
5926
5927
5928 std::string DataArrayDoubleTuple::repr() const
5929 {
5930   std::ostringstream oss; oss.precision(17); oss << "(";
5931   for(int i=0;i<_nb_of_compo-1;i++)
5932     oss << _pt[i] << ", ";
5933   oss << _pt[_nb_of_compo-1] << ")";
5934   return oss.str();
5935 }
5936
5937 double DataArrayDoubleTuple::doubleValue() const
5938 {
5939   if(_nb_of_compo==1)
5940     return *_pt;
5941   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5942 }
5943
5944 /*!
5945  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5946  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5947  * 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
5948  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5949  */
5950 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5951 {
5952   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5953     {
5954       DataArrayDouble *ret=DataArrayDouble::New();
5955       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5956       return ret;
5957     }
5958   else
5959     {
5960       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5961       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5962       throw INTERP_KERNEL::Exception(oss.str().c_str());
5963     }
5964 }
5965
5966 /*!
5967  * Returns a new instance of DataArrayInt. The caller is to delete this array
5968  * using decrRef() as it is no more needed. 
5969  */
5970 DataArrayInt *DataArrayInt::New()
5971 {
5972   return new DataArrayInt;
5973 }
5974
5975 /*!
5976  * Checks if raw data is allocated. Read more on the raw data
5977  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5978  *  \return bool - \a true if the raw data is allocated, \a false else.
5979  */
5980 bool DataArrayInt::isAllocated() const
5981 {
5982   return getConstPointer()!=0;
5983 }
5984
5985 /*!
5986  * Checks if raw data is allocated and throws an exception if it is not the case.
5987  *  \throw If the raw data is not allocated.
5988  */
5989 void DataArrayInt::checkAllocated() const
5990 {
5991   if(!isAllocated())
5992     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5993 }
5994
5995 /*!
5996  * This method desallocated \a this without modification of informations relative to the components.
5997  * After call of this method, DataArrayInt::isAllocated will return false.
5998  * If \a this is already not allocated, \a this is let unchanged.
5999  */
6000 void DataArrayInt::desallocate()
6001 {
6002   _mem.destroy();
6003 }
6004
6005 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
6006 {
6007   std::size_t sz(_mem.getNbOfElemAllocated());
6008   sz*=sizeof(int);
6009   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
6010 }
6011
6012 /*!
6013  * Returns the only one value in \a this, if and only if number of elements
6014  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
6015  *  \return double - the sole value stored in \a this array.
6016  *  \throw If at least one of conditions stated above is not fulfilled.
6017  */
6018 int DataArrayInt::intValue() const
6019 {
6020   if(isAllocated())
6021     {
6022       if(getNbOfElems()==1)
6023         {
6024           return *getConstPointer();
6025         }
6026       else
6027         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
6028     }
6029   else
6030     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
6031 }
6032
6033 /*!
6034  * Returns an integer value characterizing \a this array, which is useful for a quick
6035  * comparison of many instances of DataArrayInt.
6036  *  \return int - the hash value.
6037  *  \throw If \a this is not allocated.
6038  */
6039 int DataArrayInt::getHashCode() const
6040 {
6041   checkAllocated();
6042   std::size_t nbOfElems=getNbOfElems();
6043   int ret=nbOfElems*65536;
6044   int delta=3;
6045   if(nbOfElems>48)
6046     delta=nbOfElems/8;
6047   int ret0=0;
6048   const int *pt=begin();
6049   for(std::size_t i=0;i<nbOfElems;i+=delta)
6050     ret0+=pt[i] & 0x1FFF;
6051   return ret+ret0;
6052 }
6053
6054 /*!
6055  * Checks the number of tuples.
6056  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
6057  *  \throw If \a this is not allocated.
6058  */
6059 bool DataArrayInt::empty() const
6060 {
6061   checkAllocated();
6062   return getNumberOfTuples()==0;
6063 }
6064
6065 /*!
6066  * Returns a full copy of \a this. For more info on copying data arrays see
6067  * \ref MEDCouplingArrayBasicsCopyDeep.
6068  *  \return DataArrayInt * - a new instance of DataArrayInt.
6069  */
6070 DataArrayInt *DataArrayInt::deepCpy() const
6071 {
6072   return new DataArrayInt(*this);
6073 }
6074
6075 /*!
6076  * Returns either a \a deep or \a shallow copy of this array. For more info see
6077  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
6078  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
6079  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
6080  *          == \a true) or \a this instance (if \a dCpy == \a false).
6081  */
6082 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
6083 {
6084   if(dCpy)
6085     return deepCpy();
6086   else
6087     {
6088       incrRef();
6089       return const_cast<DataArrayInt *>(this);
6090     }
6091 }
6092
6093 /*!
6094  * Copies all the data from another DataArrayInt. For more info see
6095  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
6096  *  \param [in] other - another instance of DataArrayInt to copy data from.
6097  *  \throw If the \a other is not allocated.
6098  */
6099 void DataArrayInt::cpyFrom(const DataArrayInt& other)
6100 {
6101   other.checkAllocated();
6102   int nbOfTuples=other.getNumberOfTuples();
6103   int nbOfComp=other.getNumberOfComponents();
6104   allocIfNecessary(nbOfTuples,nbOfComp);
6105   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6106   int *pt=getPointer();
6107   const int *ptI=other.getConstPointer();
6108   for(std::size_t i=0;i<nbOfElems;i++)
6109     pt[i]=ptI[i];
6110   copyStringInfoFrom(other);
6111 }
6112
6113 /*!
6114  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6115  * 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.
6116  * If \a this has not already been allocated, number of components is set to one.
6117  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6118  * 
6119  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6120  */
6121 void DataArrayInt::reserve(std::size_t nbOfElems)
6122 {
6123   int nbCompo=getNumberOfComponents();
6124   if(nbCompo==1)
6125     {
6126       _mem.reserve(nbOfElems);
6127     }
6128   else if(nbCompo==0)
6129     {
6130       _mem.reserve(nbOfElems);
6131       _info_on_compo.resize(1);
6132     }
6133   else
6134     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6135 }
6136
6137 /*!
6138  * 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
6139  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6140  *
6141  * \param [in] val the value to be added in \a this
6142  * \throw If \a this has already been allocated with number of components different from one.
6143  * \sa DataArrayInt::pushBackValsSilent
6144  */
6145 void DataArrayInt::pushBackSilent(int val)
6146 {
6147   int nbCompo=getNumberOfComponents();
6148   if(nbCompo==1)
6149     _mem.pushBack(val);
6150   else if(nbCompo==0)
6151     {
6152       _info_on_compo.resize(1);
6153       _mem.pushBack(val);
6154     }
6155   else
6156     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6157 }
6158
6159 /*!
6160  * 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
6161  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6162  *
6163  *  \param [in] valsBg - an array of values to push at the end of \c this.
6164  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6165  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6166  * \throw If \a this has already been allocated with number of components different from one.
6167  * \sa DataArrayInt::pushBackSilent
6168  */
6169 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6170 {
6171   int nbCompo=getNumberOfComponents();
6172   if(nbCompo==1)
6173     _mem.insertAtTheEnd(valsBg,valsEnd);
6174   else if(nbCompo==0)
6175     {
6176       _info_on_compo.resize(1);
6177       _mem.insertAtTheEnd(valsBg,valsEnd);
6178     }
6179   else
6180     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6181 }
6182
6183 /*!
6184  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6185  * \throw If \a this is already empty.
6186  * \throw If \a this has number of components different from one.
6187  */
6188 int DataArrayInt::popBackSilent()
6189 {
6190   if(getNumberOfComponents()==1)
6191     return _mem.popBack();
6192   else
6193     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6194 }
6195
6196 /*!
6197  * 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.
6198  *
6199  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6200  */
6201 void DataArrayInt::pack() const
6202 {
6203   _mem.pack();
6204 }
6205
6206 /*!
6207  * Allocates the raw data in memory. If exactly as same memory as needed already
6208  * allocated, it is not re-allocated.
6209  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6210  *  \param [in] nbOfCompo - number of components of data to allocate.
6211  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6212  */
6213 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6214 {
6215   if(isAllocated())
6216     {
6217       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6218         alloc(nbOfTuple,nbOfCompo);
6219     }
6220   else
6221     alloc(nbOfTuple,nbOfCompo);
6222 }
6223
6224 /*!
6225  * Allocates the raw data in memory. If the memory was already allocated, then it is
6226  * freed and re-allocated. See an example of this method use
6227  * \ref MEDCouplingArraySteps1WC "here".
6228  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6229  *  \param [in] nbOfCompo - number of components of data to allocate.
6230  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6231  */
6232 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6233 {
6234   if(nbOfTuple<0 || nbOfCompo<0)
6235     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6236   _info_on_compo.resize(nbOfCompo);
6237   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6238   declareAsNew();
6239 }
6240
6241 /*!
6242  * Assign zero to all values in \a this array. To know more on filling arrays see
6243  * \ref MEDCouplingArrayFill.
6244  * \throw If \a this is not allocated.
6245  */
6246 void DataArrayInt::fillWithZero()
6247 {
6248   checkAllocated();
6249   _mem.fillWithValue(0);
6250   declareAsNew();
6251 }
6252
6253 /*!
6254  * Assign \a val to all values in \a this array. To know more on filling arrays see
6255  * \ref MEDCouplingArrayFill.
6256  *  \param [in] val - the value to fill with.
6257  *  \throw If \a this is not allocated.
6258  */
6259 void DataArrayInt::fillWithValue(int val)
6260 {
6261   checkAllocated();
6262   _mem.fillWithValue(val);
6263   declareAsNew();
6264 }
6265
6266 /*!
6267  * Set all values in \a this array so that the i-th element equals to \a init + i
6268  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6269  *  \param [in] init - value to assign to the first element of array.
6270  *  \throw If \a this->getNumberOfComponents() != 1
6271  *  \throw If \a this is not allocated.
6272  */
6273 void DataArrayInt::iota(int init)
6274 {
6275   checkAllocated();
6276   if(getNumberOfComponents()!=1)
6277     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6278   int *ptr=getPointer();
6279   int ntuples=getNumberOfTuples();
6280   for(int i=0;i<ntuples;i++)
6281     ptr[i]=init+i;
6282   declareAsNew();
6283 }
6284
6285 /*!
6286  * Returns a textual and human readable representation of \a this instance of
6287  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6288  * \return std::string - text describing \a this DataArrayInt.
6289  * 
6290  * \sa reprNotTooLong, reprZip
6291  */
6292 std::string DataArrayInt::repr() const
6293 {
6294   std::ostringstream ret;
6295   reprStream(ret);
6296   return ret.str();
6297 }
6298
6299 std::string DataArrayInt::reprZip() const
6300 {
6301   std::ostringstream ret;
6302   reprZipStream(ret);
6303   return ret.str();
6304 }
6305
6306 /*!
6307  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
6308  * printed out to avoid to consume too much space in interpretor.
6309  * \sa repr
6310  */
6311 std::string DataArrayInt::reprNotTooLong() const
6312 {
6313   std::ostringstream ret;
6314   reprNotTooLongStream(ret);
6315   return ret.str();
6316 }
6317
6318 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6319 {
6320   static const char SPACE[4]={' ',' ',' ',' '};
6321   checkAllocated();
6322   std::string idt(indent,' ');
6323   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6324   if(byteArr)
6325     {
6326       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6327       if(std::string(type)=="Int32")
6328         {
6329           const char *data(reinterpret_cast<const char *>(begin()));
6330           std::size_t sz(getNbOfElems()*sizeof(int));
6331           byteArr->insertAtTheEnd(data,data+sz);
6332           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6333         }
6334       else if(std::string(type)=="Int8")
6335         {
6336           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6337           std::copy(begin(),end(),(char *)tmp);
6338           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6339           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6340         }
6341       else if(std::string(type)=="UInt8")
6342         {
6343           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6344           std::copy(begin(),end(),(unsigned char *)tmp);
6345           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6346           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6347         }
6348       else
6349         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6350     }
6351   else
6352     {
6353       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6354       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6355     }
6356   ofs << std::endl << idt << "</DataArray>\n";
6357 }
6358
6359 void DataArrayInt::reprStream(std::ostream& stream) const
6360 {
6361   stream << "Name of int array : \"" << _name << "\"\n";
6362   reprWithoutNameStream(stream);
6363 }
6364
6365 void DataArrayInt::reprZipStream(std::ostream& stream) const
6366 {
6367   stream << "Name of int array : \"" << _name << "\"\n";
6368   reprZipWithoutNameStream(stream);
6369 }
6370
6371 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
6372 {
6373   stream << "Name of int array : \"" << _name << "\"\n";
6374   reprNotTooLongWithoutNameStream(stream);
6375 }
6376
6377 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6378 {
6379   DataArray::reprWithoutNameStream(stream);
6380   _mem.repr(getNumberOfComponents(),stream);
6381 }
6382
6383 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6384 {
6385   DataArray::reprWithoutNameStream(stream);
6386   _mem.reprZip(getNumberOfComponents(),stream);
6387 }
6388
6389 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
6390 {
6391   DataArray::reprWithoutNameStream(stream);
6392   stream.precision(17);
6393   _mem.reprNotTooLong(getNumberOfComponents(),stream);
6394 }
6395
6396 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6397 {
6398   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6399   const int *data=getConstPointer();
6400   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6401   if(nbTuples*nbComp>=1)
6402     {
6403       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6404       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6405       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6406       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6407     }
6408   else
6409     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6410   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6411 }
6412
6413 /*!
6414  * Method that gives a quick overvien of \a this for python.
6415  */
6416 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6417 {
6418   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6419   stream << "DataArrayInt C++ instance at " << this << ". ";
6420   if(isAllocated())
6421     {
6422       int nbOfCompo=(int)_info_on_compo.size();
6423       if(nbOfCompo>=1)
6424         {
6425           int nbOfTuples=getNumberOfTuples();
6426           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6427           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6428         }
6429       else
6430         stream << "Number of components : 0.";
6431     }
6432   else
6433     stream << "*** No data allocated ****";
6434 }
6435
6436 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6437 {
6438   const int *data=begin();
6439   int nbOfTuples=getNumberOfTuples();
6440   int nbOfCompo=(int)_info_on_compo.size();
6441   std::ostringstream oss2; oss2 << "[";
6442   std::string oss2Str(oss2.str());
6443   bool isFinished=true;
6444   for(int i=0;i<nbOfTuples && isFinished;i++)
6445     {
6446       if(nbOfCompo>1)
6447         {
6448           oss2 << "(";
6449           for(int j=0;j<nbOfCompo;j++,data++)
6450             {
6451               oss2 << *data;
6452               if(j!=nbOfCompo-1) oss2 << ", ";
6453             }
6454           oss2 << ")";
6455         }
6456       else
6457         oss2 << *data++;
6458       if(i!=nbOfTuples-1) oss2 << ", ";
6459       std::string oss3Str(oss2.str());
6460       if(oss3Str.length()<maxNbOfByteInRepr)
6461         oss2Str=oss3Str;
6462       else
6463         isFinished=false;
6464     }
6465   stream << oss2Str;
6466   if(!isFinished)
6467     stream << "... ";
6468   stream << "]";
6469 }
6470
6471 /*!
6472  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6473  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6474  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6475  *         to \a this array.
6476  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6477  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6478  *  \throw If \a this->getNumberOfComponents() != 1
6479  *  \throw If any value of \a this can't be used as a valid index for 
6480  *         [\a indArrBg, \a indArrEnd).
6481  *
6482  *  \sa replaceOneValByInThis
6483  */
6484 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6485 {
6486   checkAllocated();
6487   if(getNumberOfComponents()!=1)
6488     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6489   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6490   for(int i=0;i<nbOfTuples;i++,pt++)
6491     {
6492       if(*pt>=0 && *pt<nbElemsIn)
6493         *pt=indArrBg[*pt];
6494       else
6495         {
6496           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6497           throw INTERP_KERNEL::Exception(oss.str().c_str());
6498         }
6499     }
6500   declareAsNew();
6501 }
6502
6503 /*!
6504  * Modifies in place \a this one-dimensional array like this : each id in \a this so that this[id] equal to \a valToBeReplaced will be replaced at the same place by \a replacedBy.
6505  *
6506  * \param [in] valToBeReplaced - the value in \a this to be replaced.
6507  * \param [in] replacedBy - the value taken by each tuple previously equal to \a valToBeReplaced.
6508  *
6509  * \sa DataArrayInt::transformWithIndArr
6510  */
6511 void DataArrayInt::replaceOneValByInThis(int valToBeReplaced, int replacedBy)
6512 {
6513   checkAllocated();
6514   if(getNumberOfComponents()!=1)
6515     throw INTERP_KERNEL::Exception("Call replaceOneValByInThis method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6516   if(valToBeReplaced==replacedBy)
6517     return ;
6518   int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6519   for(int i=0;i<nbOfTuples;i++,pt++)
6520     {
6521       if(*pt==valToBeReplaced)
6522         *pt=replacedBy;
6523     }
6524 }
6525
6526 /*!
6527  * Computes distribution of values of \a this one-dimensional array between given value
6528  * ranges (casts). This method is typically useful for entity number spliting by types,
6529  * for example. 
6530  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6531  *           check of this is be done. If not, the result is not warranted. 
6532  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6533  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6534  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6535  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6536  *         should be more than every value in \a this array.
6537  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6538  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6539  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6540  *         (same number of tuples and components), the caller is to delete 
6541  *         using decrRef() as it is no more needed.
6542  *         This array contains indices of ranges for every value of \a this array. I.e.
6543  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6544  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6545  *         this in which cast it holds.
6546  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6547  *         array, the caller is to delete using decrRef() as it is no more needed.
6548  *         This array contains ranks of values of \a this array within ranges
6549  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6550  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6551  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6552  *         for each tuple its rank inside its cast. The rank is computed as difference
6553  *         between the value and the lowest value of range.
6554  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6555  *         ranges (casts) to which at least one value of \a this array belongs.
6556  *         Or, in other words, this param contains the casts that \a this contains.
6557  *         The caller is to delete this array using decrRef() as it is no more needed.
6558  *
6559  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6560  *            the output of this method will be : 
6561  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6562  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6563  * - \a castsPresent  : [0,1]
6564  *
6565  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6566  * range #1 and its rank within this range is 2; etc.
6567  *
6568  *  \throw If \a this->getNumberOfComponents() != 1.
6569  *  \throw If \a arrEnd - arrBg < 2.
6570  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6571  */
6572 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6573                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6574 {
6575   checkAllocated();
6576   if(getNumberOfComponents()!=1)
6577     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6578   int nbOfTuples=getNumberOfTuples();
6579   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6580   if(nbOfCast<2)
6581     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6582   nbOfCast--;
6583   const int *work=getConstPointer();
6584   typedef std::reverse_iterator<const int *> rintstart;
6585   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6586   rintstart end2(arrBg);
6587   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6588   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6589   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6590   ret1->alloc(nbOfTuples,1);
6591   ret2->alloc(nbOfTuples,1);
6592   int *ret1Ptr=ret1->getPointer();
6593   int *ret2Ptr=ret2->getPointer();
6594   std::set<std::size_t> castsDetected;
6595   for(int i=0;i<nbOfTuples;i++)
6596     {
6597       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6598       std::size_t pos=std::distance(bg,res);
6599       std::size_t pos2=nbOfCast-pos;
6600       if(pos2<nbOfCast)
6601         {
6602           ret1Ptr[i]=(int)pos2;
6603           ret2Ptr[i]=work[i]-arrBg[pos2];
6604           castsDetected.insert(pos2);
6605         }
6606       else
6607         {
6608           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6609           throw INTERP_KERNEL::Exception(oss.str().c_str());
6610         }
6611     }
6612   ret3->alloc((int)castsDetected.size(),1);
6613   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6614   castArr=ret1.retn();
6615   rankInsideCast=ret2.retn();
6616   castsPresent=ret3.retn();
6617 }
6618
6619 /*!
6620  * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ).
6621  * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ).
6622  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6623  *
6624  * \param [out] strt - the start of the range (included) if true is returned.
6625  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6626  * \param [out] stteepp - the step of the range if true is returned.
6627  * \return the verdict of the check.
6628  *
6629  * \sa DataArray::GetNumberOfItemGivenBES
6630  */
6631 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6632 {
6633   checkAllocated();
6634   if(getNumberOfComponents()!=1)
6635     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6636   int nbTuples(getNumberOfTuples());
6637   if(nbTuples==0)
6638     { strt=0; sttoopp=0; stteepp=1; return true; }
6639   const int *pt(begin());
6640   strt=*pt; 
6641   if(nbTuples==1)
6642     { sttoopp=strt+1; stteepp=1; return true; }
6643   strt=*pt; sttoopp=pt[nbTuples-1];
6644   if(strt==sttoopp)
6645     return false;
6646   if(sttoopp>strt)
6647     {
6648       sttoopp++;
6649       int a(sttoopp-1-strt),tmp(strt);
6650       if(a%(nbTuples-1)!=0)
6651         return false;
6652       stteepp=a/(nbTuples-1);
6653       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6654         if(pt[i]!=tmp)
6655           return false;
6656       return true;
6657     }
6658   else
6659     {
6660       sttoopp--;
6661       int a(strt-sttoopp-1),tmp(strt);
6662       if(a%(nbTuples-1)!=0)
6663         return false;
6664       stteepp=-(a/(nbTuples-1));
6665       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6666         if(pt[i]!=tmp)
6667           return false;
6668       return true;
6669     }
6670 }
6671
6672 /*!
6673  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6674  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6675  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6676  * new value in place \a indArr[ \a v ] is i.
6677  *  \param [in] indArrBg - the array holding indices within the result array to assign
6678  *         indices of values of \a this array pointing to values of \a indArrBg.
6679  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6680  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6681  *  \return DataArrayInt * - the new instance of DataArrayInt.
6682  *          The caller is to delete this result array using decrRef() as it is no more
6683  *          needed.
6684  *  \throw If \a this->getNumberOfComponents() != 1.
6685  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6686  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6687  */
6688 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6689 {
6690   checkAllocated();
6691   if(getNumberOfComponents()!=1)
6692     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6693   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6694   int nbOfTuples=getNumberOfTuples();
6695   const int *pt=getConstPointer();
6696   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6697   ret->alloc(nbOfTuples,1);
6698   ret->fillWithValue(-1);
6699   int *tmp=ret->getPointer();
6700   for(int i=0;i<nbOfTuples;i++,pt++)
6701     {
6702       if(*pt>=0 && *pt<nbElemsIn)
6703         {
6704           int pos=indArrBg[*pt];
6705           if(pos>=0 && pos<nbOfTuples)
6706             tmp[pos]=i;
6707           else
6708             {
6709               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6710               throw INTERP_KERNEL::Exception(oss.str().c_str());
6711             }
6712         }
6713       else
6714         {
6715           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6716           throw INTERP_KERNEL::Exception(oss.str().c_str());
6717         }
6718     }
6719   return ret.retn();
6720 }
6721
6722 /*!
6723  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6724  * from values of \a this array, which is supposed to contain a renumbering map in 
6725  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6726  * To know how to use the renumbering maps see \ref numbering.
6727  *  \param [in] newNbOfElem - the number of tuples in the result array.
6728  *  \return DataArrayInt * - the new instance of DataArrayInt.
6729  *          The caller is to delete this result array using decrRef() as it is no more
6730  *          needed.
6731  * 
6732  *  \if ENABLE_EXAMPLES
6733  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6734  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6735  *  \endif
6736  */
6737 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6738 {
6739   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6740   ret->alloc(newNbOfElem,1);
6741   int nbOfOldNodes=getNumberOfTuples();
6742   const int *old2New=getConstPointer();
6743   int *pt=ret->getPointer();
6744   for(int i=0;i!=nbOfOldNodes;i++)
6745     {
6746       int newp(old2New[i]);
6747       if(newp!=-1)
6748         {
6749           if(newp>=0 && newp<newNbOfElem)
6750             pt[newp]=i;
6751           else
6752             {
6753               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6754               throw INTERP_KERNEL::Exception(oss.str().c_str());
6755             }
6756         }
6757     }
6758   return ret.retn();
6759 }
6760
6761 /*!
6762  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6763  * 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]
6764  */
6765 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6766 {
6767   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6768   ret->alloc(newNbOfElem,1);
6769   int nbOfOldNodes=getNumberOfTuples();
6770   const int *old2New=getConstPointer();
6771   int *pt=ret->getPointer();
6772   for(int i=nbOfOldNodes-1;i>=0;i--)
6773     {
6774       int newp(old2New[i]);
6775       if(newp!=-1)
6776         {
6777           if(newp>=0 && newp<newNbOfElem)
6778             pt[newp]=i;
6779           else
6780             {
6781               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6782               throw INTERP_KERNEL::Exception(oss.str().c_str());
6783             }
6784         }
6785     }
6786   return ret.retn();
6787 }
6788
6789 /*!
6790  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6791  * from values of \a this array, which is supposed to contain a renumbering map in 
6792  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6793  * To know how to use the renumbering maps see \ref numbering.
6794  *  \param [in] newNbOfElem - the number of tuples in the result array.
6795  *  \return DataArrayInt * - the new instance of DataArrayInt.
6796  *          The caller is to delete this result array using decrRef() as it is no more
6797  *          needed.
6798  * 
6799  *  \if ENABLE_EXAMPLES
6800  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6801  *
6802  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6803  *  \endif
6804  */
6805 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6806 {
6807   checkAllocated();
6808   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6809   ret->alloc(oldNbOfElem,1);
6810   const int *new2Old=getConstPointer();
6811   int *pt=ret->getPointer();
6812   std::fill(pt,pt+oldNbOfElem,-1);
6813   int nbOfNewElems=getNumberOfTuples();
6814   for(int i=0;i<nbOfNewElems;i++)
6815     {
6816       int v(new2Old[i]);
6817       if(v>=0 && v<oldNbOfElem)
6818         pt[v]=i;
6819       else
6820         {
6821           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6822           throw INTERP_KERNEL::Exception(oss.str().c_str());
6823         }
6824     }
6825   return ret.retn();
6826 }
6827
6828 /*!
6829  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6830  * mismatch is given.
6831  * 
6832  * \param [in] other the instance to be compared with \a this
6833  * \param [out] reason In case of inequality returns the reason.
6834  * \sa DataArrayInt::isEqual
6835  */
6836 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6837 {
6838   if(!areInfoEqualsIfNotWhy(other,reason))
6839     return false;
6840   return _mem.isEqual(other._mem,0,reason);
6841 }
6842
6843 /*!
6844  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6845  * \ref MEDCouplingArrayBasicsCompare.
6846  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6847  *  \return bool - \a true if the two arrays are equal, \a false else.
6848  */
6849 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6850 {
6851   std::string tmp;
6852   return isEqualIfNotWhy(other,tmp);
6853 }
6854
6855 /*!
6856  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6857  * \ref MEDCouplingArrayBasicsCompare.
6858  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6859  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6860  */
6861 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6862 {
6863   std::string tmp;
6864   return _mem.isEqual(other._mem,0,tmp);
6865 }
6866
6867 /*!
6868  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6869  * performed on sorted value sequences.
6870  * For more info see\ref MEDCouplingArrayBasicsCompare.
6871  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6872  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6873  */
6874 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6875 {
6876   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6877   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6878   a->sort();
6879   b->sort();
6880   return a->isEqualWithoutConsideringStr(*b);
6881 }
6882
6883 /*!
6884  * This method compares content of input vector \a v and \a this.
6885  * 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.
6886  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6887  *
6888  * \param [in] v - the vector of 'flags' to be compared with \a this.
6889  *
6890  * \throw If \a this is not sorted ascendingly.
6891  * \throw If \a this has not exactly one component.
6892  * \throw If \a this is not allocated.
6893  */
6894 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6895 {
6896   checkAllocated();
6897   if(getNumberOfComponents()!=1)
6898     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6899   const int *w(begin()),*end2(end());
6900   int refVal=-std::numeric_limits<int>::max();
6901   int i=0;
6902   std::vector<bool>::const_iterator it(v.begin());
6903   for(;it!=v.end();it++,i++)
6904     {
6905       if(*it)
6906         {
6907           if(w!=end2)
6908             {
6909               if(*w++==i)
6910                 {
6911                   if(i>refVal)
6912                     refVal=i;
6913                   else
6914                     {
6915                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6916                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6917                     }
6918                 }
6919               else
6920                 return false;
6921             }
6922           else
6923             return false;
6924         }
6925     }
6926   return w==end2;
6927 }
6928
6929 /*!
6930  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
6931  * put True to the corresponding entry in \a vec.
6932  * \a vec is expected to be with the same size than the number of tuples of \a this.
6933  */
6934 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6935 {
6936   checkAllocated();
6937   if(getNumberOfComponents()!=1)
6938     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6939   int nbOfTuples(getNumberOfTuples());
6940   if(nbOfTuples!=(int)vec.size())
6941     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6942   const int *pt(begin());
6943   for(int i=0;i<nbOfTuples;i++)
6944     if(pt[i]==val)
6945       vec[i]=true;
6946 }
6947
6948 /*!
6949  * Sorts values of the array.
6950  *  \param [in] asc - \a true means ascending order, \a false, descending.
6951  *  \throw If \a this is not allocated.
6952  *  \throw If \a this->getNumberOfComponents() != 1.
6953  */
6954 void DataArrayInt::sort(bool asc)
6955 {
6956   checkAllocated();
6957   if(getNumberOfComponents()!=1)
6958     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6959   _mem.sort(asc);
6960   declareAsNew();
6961 }
6962
6963 /*!
6964  * Computes for each tuple the sum of number of components values in the tuple and return it.
6965  * 
6966  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6967  *          same number of tuples as \a this array and one component.
6968  *          The caller is to delete this result array using decrRef() as it is no more
6969  *          needed.
6970  *  \throw If \a this is not allocated.
6971  */
6972 DataArrayInt *DataArrayInt::sumPerTuple() const
6973 {
6974   checkAllocated();
6975   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6976   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6977   ret->alloc(nbOfTuple,1);
6978   const int *src(getConstPointer());
6979   int *dest(ret->getPointer());
6980   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6981     *dest=std::accumulate(src,src+nbOfComp,0);
6982   return ret.retn();
6983 }
6984
6985 /*!
6986  * Reverse the array values.
6987  *  \throw If \a this->getNumberOfComponents() < 1.
6988  *  \throw If \a this is not allocated.
6989  */
6990 void DataArrayInt::reverse()
6991 {
6992   checkAllocated();
6993   _mem.reverse(getNumberOfComponents());
6994   declareAsNew();
6995 }
6996
6997 /*!
6998  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6999  * If not an exception is thrown.
7000  *  \param [in] increasing - if \a true, the array values should be increasing.
7001  *  \throw If sequence of values is not strictly monotonic in agreement with \a
7002  *         increasing arg.
7003  *  \throw If \a this->getNumberOfComponents() != 1.
7004  *  \throw If \a this is not allocated.
7005  */
7006 void DataArrayInt::checkMonotonic(bool increasing) const
7007 {
7008   if(!isMonotonic(increasing))
7009     {
7010       if (increasing)
7011         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
7012       else
7013         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
7014     }
7015 }
7016
7017 /*!
7018  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
7019  *  \param [in] increasing - if \a true, array values should be increasing.
7020  *  \return bool - \a true if values change in accordance with \a increasing arg.
7021  *  \throw If \a this->getNumberOfComponents() != 1.
7022  *  \throw If \a this is not allocated.
7023  */
7024 bool DataArrayInt::isMonotonic(bool increasing) const
7025 {
7026   checkAllocated();
7027   if(getNumberOfComponents()!=1)
7028     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
7029   int nbOfElements=getNumberOfTuples();
7030   const int *ptr=getConstPointer();
7031   if(nbOfElements==0)
7032     return true;
7033   int ref=ptr[0];
7034   if(increasing)
7035     {
7036       for(int i=1;i<nbOfElements;i++)
7037         {
7038           if(ptr[i]>=ref)
7039             ref=ptr[i];
7040           else
7041             return false;
7042         }
7043     }
7044   else
7045     {
7046       for(int i=1;i<nbOfElements;i++)
7047         {
7048           if(ptr[i]<=ref)
7049             ref=ptr[i];
7050           else
7051             return false;
7052         }
7053     }
7054   return true;
7055 }
7056
7057 /*!
7058  * This method check that array consistently INCREASING or DECREASING in value.
7059  */
7060 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
7061 {
7062   checkAllocated();
7063   if(getNumberOfComponents()!=1)
7064     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
7065   int nbOfElements=getNumberOfTuples();
7066   const int *ptr=getConstPointer();
7067   if(nbOfElements==0)
7068     return true;
7069   int ref=ptr[0];
7070   if(increasing)
7071     {
7072       for(int i=1;i<nbOfElements;i++)
7073         {
7074           if(ptr[i]>ref)
7075             ref=ptr[i];
7076           else
7077             return false;
7078         }
7079     }
7080   else
7081     {
7082       for(int i=1;i<nbOfElements;i++)
7083         {
7084           if(ptr[i]<ref)
7085             ref=ptr[i];
7086           else
7087             return false;
7088         }
7089     }
7090   return true;
7091 }
7092
7093 /*!
7094  * This method check that array consistently INCREASING or DECREASING in value.
7095  */
7096 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
7097 {
7098   if(!isStrictlyMonotonic(increasing))
7099     {
7100       if (increasing)
7101         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
7102       else
7103         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
7104     }
7105 }
7106
7107 /*!
7108  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
7109  * one-dimensional arrays that must be of the same length. The result array describes
7110  * correspondence between \a this and \a other arrays, so that 
7111  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
7112  * not possible because some element in \a other is not in \a this, an exception is thrown.
7113  *  \param [in] other - an array to compute permutation to.
7114  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
7115  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
7116  * no more needed.
7117  *  \throw If \a this->getNumberOfComponents() != 1.
7118  *  \throw If \a other->getNumberOfComponents() != 1.
7119  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
7120  *  \throw If \a other includes a value which is not in \a this array.
7121  * 
7122  *  \if ENABLE_EXAMPLES
7123  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
7124  *
7125  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
7126  *  \endif
7127  */
7128 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
7129 {
7130   checkAllocated();
7131   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
7132     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
7133   int nbTuple=getNumberOfTuples();
7134   other.checkAllocated();
7135   if(nbTuple!=other.getNumberOfTuples())
7136     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
7137   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7138   ret->alloc(nbTuple,1);
7139   ret->fillWithValue(-1);
7140   const int *pt=getConstPointer();
7141   std::map<int,int> mm;
7142   for(int i=0;i<nbTuple;i++)
7143     mm[pt[i]]=i;
7144   pt=other.getConstPointer();
7145   int *retToFill=ret->getPointer();
7146   for(int i=0;i<nbTuple;i++)
7147     {
7148       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7149       if(it==mm.end())
7150         {
7151           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7152           throw INTERP_KERNEL::Exception(oss.str().c_str());
7153         }
7154       retToFill[i]=(*it).second;
7155     }
7156   return ret.retn();
7157 }
7158
7159 /*!
7160  * Sets a C array to be used as raw data of \a this. The previously set info
7161  *  of components is retained and re-sized. 
7162  * For more info see \ref MEDCouplingArraySteps1.
7163  *  \param [in] array - the C array to be used as raw data of \a this.
7164  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7165  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
7166  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
7167  *                     \c free(\c array ) will be called.
7168  *  \param [in] nbOfTuple - new number of tuples in \a this.
7169  *  \param [in] nbOfCompo - new number of components in \a this.
7170  */
7171 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7172 {
7173   _info_on_compo.resize(nbOfCompo);
7174   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7175   declareAsNew();
7176 }
7177
7178 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7179 {
7180   _info_on_compo.resize(nbOfCompo);
7181   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7182   declareAsNew();
7183 }
7184
7185 /*!
7186  * Returns a new DataArrayInt holding the same values as \a this array but differently
7187  * arranged in memory. If \a this array holds 2 components of 3 values:
7188  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7189  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7190  *  \warning Do not confuse this method with transpose()!
7191  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7192  *          is to delete using decrRef() as it is no more needed.
7193  *  \throw If \a this is not allocated.
7194  */
7195 DataArrayInt *DataArrayInt::fromNoInterlace() const
7196 {
7197   checkAllocated();
7198   if(_mem.isNull())
7199     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7200   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7201   DataArrayInt *ret=DataArrayInt::New();
7202   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7203   return ret;
7204 }
7205
7206 /*!
7207  * Returns a new DataArrayInt holding the same values as \a this array but differently
7208  * arranged in memory. If \a this array holds 2 components of 3 values:
7209  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7210  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7211  *  \warning Do not confuse this method with transpose()!
7212  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7213  *          is to delete using decrRef() as it is no more needed.
7214  *  \throw If \a this is not allocated.
7215  */
7216 DataArrayInt *DataArrayInt::toNoInterlace() const
7217 {
7218   checkAllocated();
7219   if(_mem.isNull())
7220     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7221   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7222   DataArrayInt *ret=DataArrayInt::New();
7223   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7224   return ret;
7225 }
7226
7227 /*!
7228  * Permutes values of \a this array as required by \a old2New array. The values are
7229  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7230  * the same as in \c this one.
7231  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7232  * For more info on renumbering see \ref numbering.
7233  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7234  *     giving a new position for i-th old value.
7235  */
7236 void DataArrayInt::renumberInPlace(const int *old2New)
7237 {
7238   checkAllocated();
7239   int nbTuples=getNumberOfTuples();
7240   int nbOfCompo=getNumberOfComponents();
7241   int *tmp=new int[nbTuples*nbOfCompo];
7242   const int *iptr=getConstPointer();
7243   for(int i=0;i<nbTuples;i++)
7244     {
7245       int v=old2New[i];
7246       if(v>=0 && v<nbTuples)
7247         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7248       else
7249         {
7250           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7251           throw INTERP_KERNEL::Exception(oss.str().c_str());
7252         }
7253     }
7254   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7255   delete [] tmp;
7256   declareAsNew();
7257 }
7258
7259 /*!
7260  * Permutes values of \a this array as required by \a new2Old array. The values are
7261  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7262  * the same as in \c this one.
7263  * For more info on renumbering see \ref numbering.
7264  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7265  *     giving a previous position of i-th new value.
7266  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7267  *          is to delete using decrRef() as it is no more needed.
7268  */
7269 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7270 {
7271   checkAllocated();
7272   int nbTuples=getNumberOfTuples();
7273   int nbOfCompo=getNumberOfComponents();
7274   int *tmp=new int[nbTuples*nbOfCompo];
7275   const int *iptr=getConstPointer();
7276   for(int i=0;i<nbTuples;i++)
7277     {
7278       int v=new2Old[i];
7279       if(v>=0 && v<nbTuples)
7280         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7281       else
7282         {
7283           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7284           throw INTERP_KERNEL::Exception(oss.str().c_str());
7285         }
7286     }
7287   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7288   delete [] tmp;
7289   declareAsNew();
7290 }
7291
7292 /*!
7293  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7294  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7295  * Number of tuples in the result array remains the same as in \c this one.
7296  * If a permutation reduction is needed, renumberAndReduce() should be used.
7297  * For more info on renumbering see \ref numbering.
7298  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7299  *          giving a new position for i-th old value.
7300  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7301  *          is to delete using decrRef() as it is no more needed.
7302  *  \throw If \a this is not allocated.
7303  */
7304 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7305 {
7306   checkAllocated();
7307   int nbTuples=getNumberOfTuples();
7308   int nbOfCompo=getNumberOfComponents();
7309   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7310   ret->alloc(nbTuples,nbOfCompo);
7311   ret->copyStringInfoFrom(*this);
7312   const int *iptr=getConstPointer();
7313   int *optr=ret->getPointer();
7314   for(int i=0;i<nbTuples;i++)
7315     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7316   ret->copyStringInfoFrom(*this);
7317   return ret.retn();
7318 }
7319
7320 /*!
7321  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7322  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7323  * tuples in the result array remains the same as in \c this one.
7324  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7325  * For more info on renumbering see \ref numbering.
7326  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7327  *     giving a previous position of i-th new value.
7328  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7329  *          is to delete using decrRef() as it is no more needed.
7330  */
7331 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7332 {
7333   checkAllocated();
7334   int nbTuples=getNumberOfTuples();
7335   int nbOfCompo=getNumberOfComponents();
7336   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7337   ret->alloc(nbTuples,nbOfCompo);
7338   ret->copyStringInfoFrom(*this);
7339   const int *iptr=getConstPointer();
7340   int *optr=ret->getPointer();
7341   for(int i=0;i<nbTuples;i++)
7342     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7343   ret->copyStringInfoFrom(*this);
7344   return ret.retn();
7345 }
7346
7347 /*!
7348  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7349  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7350  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7351  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7352  * \a old2New[ i ] is negative, is missing from the result array.
7353  * For more info on renumbering see \ref numbering.
7354  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7355  *     giving a new position for i-th old tuple and giving negative position for
7356  *     for i-th old tuple that should be omitted.
7357  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7358  *          is to delete using decrRef() as it is no more needed.
7359  */
7360 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7361 {
7362   checkAllocated();
7363   int nbTuples=getNumberOfTuples();
7364   int nbOfCompo=getNumberOfComponents();
7365   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7366   ret->alloc(newNbOfTuple,nbOfCompo);
7367   const int *iptr=getConstPointer();
7368   int *optr=ret->getPointer();
7369   for(int i=0;i<nbTuples;i++)
7370     {
7371       int w=old2New[i];
7372       if(w>=0)
7373         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7374     }
7375   ret->copyStringInfoFrom(*this);
7376   return ret.retn();
7377 }
7378
7379 /*!
7380  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7381  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7382  * \a new2OldBg array.
7383  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7384  * This method is equivalent to renumberAndReduce() except that convention in input is
7385  * \c new2old and \b not \c old2new.
7386  * For more info on renumbering see \ref numbering.
7387  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7388  *              tuple index in \a this array to fill the i-th tuple in the new array.
7389  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7390  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7391  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7392  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7393  *          is to delete using decrRef() as it is no more needed.
7394  */
7395 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7396 {
7397   checkAllocated();
7398   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7399   int nbComp=getNumberOfComponents();
7400   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7401   ret->copyStringInfoFrom(*this);
7402   int *pt=ret->getPointer();
7403   const int *srcPt=getConstPointer();
7404   int i=0;
7405   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7406     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7407   ret->copyStringInfoFrom(*this);
7408   return ret.retn();
7409 }
7410
7411 /*!
7412  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7413  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7414  * \a new2OldBg array.
7415  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7416  * This method is equivalent to renumberAndReduce() except that convention in input is
7417  * \c new2old and \b not \c old2new.
7418  * This method is equivalent to selectByTupleId() except that it prevents coping data
7419  * from behind the end of \a this array.
7420  * For more info on renumbering see \ref numbering.
7421  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7422  *              tuple index in \a this array to fill the i-th tuple in the new array.
7423  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7424  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7425  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7426  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7427  *          is to delete using decrRef() as it is no more needed.
7428  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7429  */
7430 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7431 {
7432   checkAllocated();
7433   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7434   int nbComp=getNumberOfComponents();
7435   int oldNbOfTuples=getNumberOfTuples();
7436   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7437   ret->copyStringInfoFrom(*this);
7438   int *pt=ret->getPointer();
7439   const int *srcPt=getConstPointer();
7440   int i=0;
7441   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7442     if(*w>=0 && *w<oldNbOfTuples)
7443       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7444     else
7445       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7446   ret->copyStringInfoFrom(*this);
7447   return ret.retn();
7448 }
7449
7450 /*!
7451  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7452  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7453  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7454  * command \c range( \a bg, \a end2, \a step ).
7455  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7456  * not constructed explicitly.
7457  * For more info on renumbering see \ref numbering.
7458  *  \param [in] bg - index of the first tuple to copy from \a this array.
7459  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7460  *  \param [in] step - index increment to get index of the next tuple to copy.
7461  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7462  *          is to delete using decrRef() as it is no more needed.
7463  *  \sa DataArrayInt::substr.
7464  */
7465 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7466 {
7467   checkAllocated();
7468   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7469   int nbComp=getNumberOfComponents();
7470   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7471   ret->alloc(newNbOfTuples,nbComp);
7472   int *pt=ret->getPointer();
7473   const int *srcPt=getConstPointer()+bg*nbComp;
7474   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7475     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7476   ret->copyStringInfoFrom(*this);
7477   return ret.retn();
7478 }
7479
7480 /*!
7481  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7482  * of tuples specified by \a ranges parameter.
7483  * For more info on renumbering see \ref numbering.
7484  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7485  *              of tuples in [\c begin,\c end) format.
7486  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7487  *          is to delete using decrRef() as it is no more needed.
7488  *  \throw If \a end < \a begin.
7489  *  \throw If \a end > \a this->getNumberOfTuples().
7490  *  \throw If \a this is not allocated.
7491  */
7492 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7493 {
7494   checkAllocated();
7495   int nbOfComp=getNumberOfComponents();
7496   int nbOfTuplesThis=getNumberOfTuples();
7497   if(ranges.empty())
7498     {
7499       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7500       ret->alloc(0,nbOfComp);
7501       ret->copyStringInfoFrom(*this);
7502       return ret.retn();
7503     }
7504   int ref=ranges.front().first;
7505   int nbOfTuples=0;
7506   bool isIncreasing=true;
7507   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7508     {
7509       if((*it).first<=(*it).second)
7510         {
7511           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7512             {
7513               nbOfTuples+=(*it).second-(*it).first;
7514               if(isIncreasing)
7515                 isIncreasing=ref<=(*it).first;
7516               ref=(*it).second;
7517             }
7518           else
7519             {
7520               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7521               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7522               throw INTERP_KERNEL::Exception(oss.str().c_str());
7523             }
7524         }
7525       else
7526         {
7527           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7528           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7529           throw INTERP_KERNEL::Exception(oss.str().c_str());
7530         }
7531     }
7532   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7533     return deepCpy();
7534   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7535   ret->alloc(nbOfTuples,nbOfComp);
7536   ret->copyStringInfoFrom(*this);
7537   const int *src=getConstPointer();
7538   int *work=ret->getPointer();
7539   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7540     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7541   return ret.retn();
7542 }
7543
7544 /*!
7545  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7546  * This map, if applied to \a this array, would make it sorted. For example, if
7547  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7548  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7549  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7550  * This method is useful for renumbering (in MED file for example). For more info
7551  * on renumbering see \ref numbering.
7552  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7553  *          array using decrRef() as it is no more needed.
7554  *  \throw If \a this is not allocated.
7555  *  \throw If \a this->getNumberOfComponents() != 1.
7556  *  \throw If there are equal values in \a this array.
7557  */
7558 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7559 {
7560   checkAllocated();
7561   if(getNumberOfComponents()!=1)
7562     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7563   int nbTuples=getNumberOfTuples();
7564   const int *pt=getConstPointer();
7565   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7566   DataArrayInt *ret=DataArrayInt::New();
7567   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7568   return ret;
7569 }
7570
7571 /*!
7572  * 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
7573  * input array \a ids2.
7574  * \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.
7575  * 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
7576  * inversely.
7577  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7578  *
7579  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7580  *          array using decrRef() as it is no more needed.
7581  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7582  * 
7583  */
7584 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7585 {
7586   if(!ids1 || !ids2)
7587     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7588   if(!ids1->isAllocated() || !ids2->isAllocated())
7589     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7590   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7591     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7592   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7593     {
7594       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 !";
7595       throw INTERP_KERNEL::Exception(oss.str().c_str());
7596     }
7597   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7598   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7599   p1->sort(true); p2->sort(true);
7600   if(!p1->isEqualWithoutConsideringStr(*p2))
7601     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7602   p1=ids1->checkAndPreparePermutation();
7603   p2=ids2->checkAndPreparePermutation();
7604   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7605   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7606   return p2.retn();
7607 }
7608
7609 /*!
7610  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7611  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7612  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7613  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7614  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7615  * The first of out arrays returns indices of elements of \a this array, grouped by their
7616  * place in the set \a B. The second out array is the index of the first one; it shows how
7617  * many elements of \a A are mapped into each element of \a B. <br>
7618  * For more info on
7619  * mapping and its usage in renumbering see \ref numbering. <br>
7620  * \b Example:
7621  * - \a this: [0,3,2,3,2,2,1,2]
7622  * - \a targetNb: 4
7623  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7624  * - \a arrI: [0,1,2,6,8]
7625  *
7626  * This result means: <br>
7627  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7628  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7629  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7630  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7631  * \a arrI[ 2+1 ]]); <br> etc.
7632  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7633  *         than the maximal value of \a A.
7634  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7635  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7636  *         this array using decrRef() as it is no more needed.
7637  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7638  *         elements of \a this. The caller is to delete this array using decrRef() as it
7639  *         is no more needed.
7640  *  \throw If \a this is not allocated.
7641  *  \throw If \a this->getNumberOfComponents() != 1.
7642  *  \throw If any value in \a this is more or equal to \a targetNb.
7643  */
7644 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7645 {
7646   checkAllocated();
7647   if(getNumberOfComponents()!=1)
7648     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7649   int nbOfTuples=getNumberOfTuples();
7650   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7651   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7652   retI->alloc(targetNb+1,1);
7653   const int *input=getConstPointer();
7654   std::vector< std::vector<int> > tmp(targetNb);
7655   for(int i=0;i<nbOfTuples;i++)
7656     {
7657       int tmp2=input[i];
7658       if(tmp2>=0 && tmp2<targetNb)
7659         tmp[tmp2].push_back(i);
7660       else
7661         {
7662           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7663           throw INTERP_KERNEL::Exception(oss.str().c_str());
7664         }
7665     }
7666   int *retIPtr=retI->getPointer();
7667   *retIPtr=0;
7668   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7669     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7670   if(nbOfTuples!=retI->getIJ(targetNb,0))
7671     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7672   ret->alloc(nbOfTuples,1);
7673   int *retPtr=ret->getPointer();
7674   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7675     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7676   arr=ret.retn();
7677   arrI=retI.retn();
7678 }
7679
7680
7681 /*!
7682  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7683  * from a zip representation of a surjective format (returned e.g. by
7684  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7685  * for example). The result array minimizes the permutation. <br>
7686  * For more info on renumbering see \ref numbering. <br>
7687  * \b Example: <br>
7688  * - \a nbOfOldTuples: 10 
7689  * - \a arr          : [0,3, 5,7,9]
7690  * - \a arrIBg       : [0,2,5]
7691  * - \a newNbOfTuples: 7
7692  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7693  *
7694  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7695  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7696  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7697  *         (indices of) equal values. Its every element (except the last one) points to
7698  *         the first element of a group of equal values.
7699  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7700  *          arrIBg is \a arrIEnd[ -1 ].
7701  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7702  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7703  *          array using decrRef() as it is no more needed.
7704  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7705  */
7706 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7707 {
7708   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7709   ret->alloc(nbOfOldTuples,1);
7710   int *pt=ret->getPointer();
7711   std::fill(pt,pt+nbOfOldTuples,-1);
7712   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7713   const int *cIPtr=arrIBg;
7714   for(int i=0;i<nbOfGrps;i++)
7715     pt[arr[cIPtr[i]]]=-(i+2);
7716   int newNb=0;
7717   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7718     {
7719       if(pt[iNode]<0)
7720         {
7721           if(pt[iNode]==-1)
7722             pt[iNode]=newNb++;
7723           else
7724             {
7725               int grpId=-(pt[iNode]+2);
7726               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7727                 {
7728                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7729                     pt[arr[j]]=newNb;
7730                   else
7731                     {
7732                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7733                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7734                     }
7735                 }
7736               newNb++;
7737             }
7738         }
7739     }
7740   newNbOfTuples=newNb;
7741   return ret.retn();
7742 }
7743
7744 /*!
7745  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7746  * which if applied to \a this array would make it sorted ascendingly.
7747  * For more info on renumbering see \ref numbering. <br>
7748  * \b Example: <br>
7749  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7750  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7751  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7752  *
7753  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7754  *          array using decrRef() as it is no more needed.
7755  *  \throw If \a this is not allocated.
7756  *  \throw If \a this->getNumberOfComponents() != 1.
7757  */
7758 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7759 {
7760   checkAllocated();
7761   if(getNumberOfComponents()!=1)
7762     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7763   int nbOfTuples=getNumberOfTuples();
7764   const int *pt=getConstPointer();
7765   std::map<int,int> m;
7766   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7767   ret->alloc(nbOfTuples,1);
7768   int *opt=ret->getPointer();
7769   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7770     {
7771       int val=*pt;
7772       std::map<int,int>::iterator it=m.find(val);
7773       if(it!=m.end())
7774         {
7775           *opt=(*it).second;
7776           (*it).second++;
7777         }
7778       else
7779         {
7780           *opt=0;
7781           m.insert(std::pair<int,int>(val,1));
7782         }
7783     }
7784   int sum=0;
7785   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7786     {
7787       int vt=(*it).second;
7788       (*it).second=sum;
7789       sum+=vt;
7790     }
7791   pt=getConstPointer();
7792   opt=ret->getPointer();
7793   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7794     *opt+=m[*pt];
7795   //
7796   return ret.retn();
7797 }
7798
7799 /*!
7800  * Checks if contents of \a this array are equal to that of an array filled with
7801  * iota(). This method is particularly useful for DataArrayInt instances that represent
7802  * a renumbering array to check the real need in renumbering. In this case it is better to use isIdentity2
7803  * method of isIdentity method.
7804  *
7805  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7806  *  \throw If \a this is not allocated.
7807  *  \throw If \a this->getNumberOfComponents() != 1.
7808  *  \sa isIdentity2
7809  */
7810 bool DataArrayInt::isIdentity() const
7811 {
7812   checkAllocated();
7813   if(getNumberOfComponents()!=1)
7814     return false;
7815   int nbOfTuples(getNumberOfTuples());
7816   const int *pt=getConstPointer();
7817   for(int i=0;i<nbOfTuples;i++,pt++)
7818     if(*pt!=i)
7819       return false;
7820   return true;
7821 }
7822
7823 /*!
7824  * This method is stronger than isIdentity method. This method checks than \a this can be considered as an identity function
7825  * of a set having \a sizeExpected elements into itself.
7826  *
7827  * \param [in] sizeExpected - The number of elements
7828  * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) and if \a this has \a sizeExpected tuples in it.
7829  *
7830  *  \throw If \a this is not allocated.
7831  *  \throw If \a this->getNumberOfComponents() != 1.
7832  * \sa isIdentity
7833  */
7834 bool DataArrayInt::isIdentity2(int sizeExpected) const
7835 {
7836   bool ret0(isIdentity());
7837   if(!ret0)
7838     return false;
7839   return getNumberOfTuples()==sizeExpected;
7840 }
7841
7842 /*!
7843  * Checks if all values in \a this array are equal to \a val.
7844  *  \param [in] val - value to check equality of array values to.
7845  *  \return bool - \a true if all values are \a val.
7846  *  \throw If \a this is not allocated.
7847  *  \throw If \a this->getNumberOfComponents() != 1
7848  */
7849 bool DataArrayInt::isUniform(int val) const
7850 {
7851   checkAllocated();
7852   if(getNumberOfComponents()!=1)
7853     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7854   int nbOfTuples=getNumberOfTuples();
7855   const int *w=getConstPointer();
7856   const int *end2=w+nbOfTuples;
7857   for(;w!=end2;w++)
7858     if(*w!=val)
7859       return false;
7860   return true;
7861 }
7862
7863 /*!
7864  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7865  * array to the new one.
7866  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7867  */
7868 DataArrayDouble *DataArrayInt::convertToDblArr() const
7869 {
7870   checkAllocated();
7871   DataArrayDouble *ret=DataArrayDouble::New();
7872   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7873   std::size_t nbOfVals=getNbOfElems();
7874   const int *src=getConstPointer();
7875   double *dest=ret->getPointer();
7876   std::copy(src,src+nbOfVals,dest);
7877   ret->copyStringInfoFrom(*this);
7878   return ret;
7879 }
7880
7881 /*!
7882  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7883  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7884  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7885  * This method is a specialization of selectByTupleId2().
7886  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7887  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7888  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7889  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7890  *          is to delete using decrRef() as it is no more needed.
7891  *  \throw If \a tupleIdBg < 0.
7892  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7893     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7894  *  \sa DataArrayInt::selectByTupleId2
7895  */
7896 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7897 {
7898   checkAllocated();
7899   int nbt=getNumberOfTuples();
7900   if(tupleIdBg<0)
7901     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7902   if(tupleIdBg>nbt)
7903     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7904   int trueEnd=tupleIdEnd;
7905   if(tupleIdEnd!=-1)
7906     {
7907       if(tupleIdEnd>nbt)
7908         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7909     }
7910   else
7911     trueEnd=nbt;
7912   int nbComp=getNumberOfComponents();
7913   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7914   ret->alloc(trueEnd-tupleIdBg,nbComp);
7915   ret->copyStringInfoFrom(*this);
7916   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7917   return ret.retn();
7918 }
7919
7920 /*!
7921  * Changes the number of components within \a this array so that its raw data **does
7922  * not** change, instead splitting this data into tuples changes.
7923  *  \warning This method erases all (name and unit) component info set before!
7924  *  \param [in] newNbOfComp - number of components for \a this array to have.
7925  *  \throw If \a this is not allocated
7926  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7927  *  \throw If \a newNbOfCompo is lower than 1.
7928  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7929  *  \warning This method erases all (name and unit) component info set before!
7930  */
7931 void DataArrayInt::rearrange(int newNbOfCompo)
7932 {
7933   checkAllocated();
7934   if(newNbOfCompo<1)
7935     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7936   std::size_t nbOfElems=getNbOfElems();
7937   if(nbOfElems%newNbOfCompo!=0)
7938     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7939   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7940     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7941   _info_on_compo.clear();
7942   _info_on_compo.resize(newNbOfCompo);
7943   declareAsNew();
7944 }
7945
7946 /*!
7947  * Changes the number of components within \a this array to be equal to its number
7948  * of tuples, and inversely its number of tuples to become equal to its number of 
7949  * components. So that its raw data **does not** change, instead splitting this
7950  * data into tuples changes.
7951  *  \warning This method erases all (name and unit) component info set before!
7952  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7953  *  \throw If \a this is not allocated.
7954  *  \sa rearrange()
7955  */
7956 void DataArrayInt::transpose()
7957 {
7958   checkAllocated();
7959   int nbOfTuples=getNumberOfTuples();
7960   rearrange(nbOfTuples);
7961 }
7962
7963 /*!
7964  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7965  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7966  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7967  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7968  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7969  * components.  
7970  *  \param [in] newNbOfComp - number of components for the new array to have.
7971  *  \param [in] dftValue - value assigned to new values added to the new array.
7972  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7973  *          is to delete using decrRef() as it is no more needed.
7974  *  \throw If \a this is not allocated.
7975  */
7976 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7977 {
7978   checkAllocated();
7979   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7980   ret->alloc(getNumberOfTuples(),newNbOfComp);
7981   const int *oldc=getConstPointer();
7982   int *nc=ret->getPointer();
7983   int nbOfTuples=getNumberOfTuples();
7984   int oldNbOfComp=getNumberOfComponents();
7985   int dim=std::min(oldNbOfComp,newNbOfComp);
7986   for(int i=0;i<nbOfTuples;i++)
7987     {
7988       int j=0;
7989       for(;j<dim;j++)
7990         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7991       for(;j<newNbOfComp;j++)
7992         nc[newNbOfComp*i+j]=dftValue;
7993     }
7994   ret->setName(getName());
7995   for(int i=0;i<dim;i++)
7996     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7997   ret->setName(getName());
7998   return ret.retn();
7999 }
8000
8001 /*!
8002  * Changes number of tuples in the array. If the new number of tuples is smaller
8003  * than the current number the array is truncated, otherwise the array is extended.
8004  *  \param [in] nbOfTuples - new number of tuples. 
8005  *  \throw If \a this is not allocated.
8006  *  \throw If \a nbOfTuples is negative.
8007  */
8008 void DataArrayInt::reAlloc(int nbOfTuples)
8009 {
8010   if(nbOfTuples<0)
8011     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
8012   checkAllocated();
8013   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
8014   declareAsNew();
8015 }
8016
8017
8018 /*!
8019  * Returns a copy of \a this array composed of selected components.
8020  * The new DataArrayInt has the same number of tuples but includes components
8021  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
8022  * can be either less, same or more than \a this->getNbOfElems().
8023  *  \param [in] compoIds - sequence of zero based indices of components to include
8024  *              into the new array.
8025  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
8026  *          is to delete using decrRef() as it is no more needed.
8027  *  \throw If \a this is not allocated.
8028  *  \throw If a component index (\a i) is not valid: 
8029  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
8030  *
8031  *  \if ENABLE_EXAMPLES
8032  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
8033  *  \endif
8034  */
8035 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
8036 {
8037   checkAllocated();
8038   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
8039   int newNbOfCompo=(int)compoIds.size();
8040   int oldNbOfCompo=getNumberOfComponents();
8041   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
8042     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
8043   int nbOfTuples=getNumberOfTuples();
8044   ret->alloc(nbOfTuples,newNbOfCompo);
8045   ret->copyPartOfStringInfoFrom(*this,compoIds);
8046   const int *oldc=getConstPointer();
8047   int *nc=ret->getPointer();
8048   for(int i=0;i<nbOfTuples;i++)
8049     for(int j=0;j<newNbOfCompo;j++,nc++)
8050       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
8051   return ret.retn();
8052 }
8053
8054 /*!
8055  * Appends components of another array to components of \a this one, tuple by tuple.
8056  * So that the number of tuples of \a this array remains the same and the number of 
8057  * components increases.
8058  *  \param [in] other - the DataArrayInt to append to \a this one.
8059  *  \throw If \a this is not allocated.
8060  *  \throw If \a this and \a other arrays have different number of tuples.
8061  *
8062  *  \if ENABLE_EXAMPLES
8063  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
8064  *
8065  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
8066  *  \endif
8067  */
8068 void DataArrayInt::meldWith(const DataArrayInt *other)
8069 {
8070   if(!other)
8071     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
8072   checkAllocated();
8073   other->checkAllocated();
8074   int nbOfTuples=getNumberOfTuples();
8075   if(nbOfTuples!=other->getNumberOfTuples())
8076     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
8077   int nbOfComp1=getNumberOfComponents();
8078   int nbOfComp2=other->getNumberOfComponents();
8079   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
8080   int *w=newArr;
8081   const int *inp1=getConstPointer();
8082   const int *inp2=other->getConstPointer();
8083   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
8084     {
8085       w=std::copy(inp1,inp1+nbOfComp1,w);
8086       w=std::copy(inp2,inp2+nbOfComp2,w);
8087     }
8088   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
8089   std::vector<int> compIds(nbOfComp2);
8090   for(int i=0;i<nbOfComp2;i++)
8091     compIds[i]=nbOfComp1+i;
8092   copyPartOfStringInfoFrom2(compIds,*other);
8093 }
8094
8095 /*!
8096  * Copy all components in a specified order from another DataArrayInt.
8097  * The specified components become the first ones in \a this array.
8098  * Both numerical and textual data is copied. The number of tuples in \a this and
8099  * the other array can be different.
8100  *  \param [in] a - the array to copy data from.
8101  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
8102  *              to be copied.
8103  *  \throw If \a a is NULL.
8104  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
8105  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
8106  *
8107  *  \if ENABLE_EXAMPLES
8108  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
8109  *  \endif
8110  */
8111 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
8112 {
8113   if(!a)
8114     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
8115   checkAllocated();
8116   a->checkAllocated();
8117   copyPartOfStringInfoFrom2(compoIds,*a);
8118   std::size_t partOfCompoSz=compoIds.size();
8119   int nbOfCompo=getNumberOfComponents();
8120   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
8121   const int *ac=a->getConstPointer();
8122   int *nc=getPointer();
8123   for(int i=0;i<nbOfTuples;i++)
8124     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
8125       nc[nbOfCompo*i+compoIds[j]]=*ac;
8126 }
8127
8128 /*!
8129  * Copy all values from another DataArrayInt into specified tuples and components
8130  * of \a this array. Textual data is not copied.
8131  * The tree parameters defining set of indices of tuples and components are similar to
8132  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
8133  *  \param [in] a - the array to copy values from.
8134  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
8135  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8136  *              are located.
8137  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8138  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
8139  *  \param [in] endComp - index of the component before which the components to assign
8140  *              to are located.
8141  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8142  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
8143  *              must be equal to the number of columns to assign to, else an
8144  *              exception is thrown; if \a false, then it is only required that \a
8145  *              a->getNbOfElems() equals to number of values to assign to (this condition
8146  *              must be respected even if \a strictCompoCompare is \a true). The number of 
8147  *              values to assign to is given by following Python expression:
8148  *              \a nbTargetValues = 
8149  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
8150  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8151  *  \throw If \a a is NULL.
8152  *  \throw If \a a is not allocated.
8153  *  \throw If \a this is not allocated.
8154  *  \throw If parameters specifying tuples and components to assign to do not give a
8155  *            non-empty range of increasing indices.
8156  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
8157  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
8158  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8159  *
8160  *  \if ENABLE_EXAMPLES
8161  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
8162  *  \endif
8163  */
8164 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8165 {
8166   if(!a)
8167     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8168   const char msg[]="DataArrayInt::setPartOfValues1";
8169   checkAllocated();
8170   a->checkAllocated();
8171   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8172   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8173   int nbComp=getNumberOfComponents();
8174   int nbOfTuples=getNumberOfTuples();
8175   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8176   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8177   bool assignTech=true;
8178   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8179     {
8180       if(strictCompoCompare)
8181         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8182     }
8183   else
8184     {
8185       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8186       assignTech=false;
8187     }
8188   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8189   const int *srcPt=a->getConstPointer();
8190   if(assignTech)
8191     {
8192       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8193         for(int j=0;j<newNbOfComp;j++,srcPt++)
8194           pt[j*stepComp]=*srcPt;
8195     }
8196   else
8197     {
8198       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8199         {
8200           const int *srcPt2=srcPt;
8201           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8202             pt[j*stepComp]=*srcPt2;
8203         }
8204     }
8205 }
8206
8207 /*!
8208  * Assign a given value to values at specified tuples and components of \a this array.
8209  * The tree parameters defining set of indices of tuples and components are similar to
8210  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8211  *  \param [in] a - the value to assign.
8212  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8213  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8214  *              are located.
8215  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8216  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8217  *  \param [in] endComp - index of the component before which the components to assign
8218  *              to are located.
8219  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8220  *  \throw If \a this is not allocated.
8221  *  \throw If parameters specifying tuples and components to assign to, do not give a
8222  *            non-empty range of increasing indices or indices are out of a valid range
8223  *            for \c this array.
8224  *
8225  *  \if ENABLE_EXAMPLES
8226  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8227  *  \endif
8228  */
8229 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8230 {
8231   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8232   checkAllocated();
8233   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8234   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8235   int nbComp=getNumberOfComponents();
8236   int nbOfTuples=getNumberOfTuples();
8237   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8238   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8239   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8240   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8241     for(int j=0;j<newNbOfComp;j++)
8242       pt[j*stepComp]=a;
8243 }
8244
8245
8246 /*!
8247  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8248  * components of \a this array. Textual data is not copied.
8249  * The tuples and components to assign to are defined by C arrays of indices.
8250  * There are two *modes of usage*:
8251  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8252  *   of \a a is assigned to its own location within \a this array. 
8253  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8254  *   components of every specified tuple of \a this array. In this mode it is required
8255  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8256  * 
8257  *  \param [in] a - the array to copy values from.
8258  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8259  *              assign values of \a a to.
8260  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8261  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8262  *              \a bgTuples <= \a pi < \a endTuples.
8263  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8264  *              assign values of \a a to.
8265  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8266  *              pointer to a component index <em>(pi)</em> varies as this: 
8267  *              \a bgComp <= \a pi < \a endComp.
8268  *  \param [in] strictCompoCompare - this parameter is checked only if the
8269  *               *mode of usage* is the first; if it is \a true (default), 
8270  *               then \a a->getNumberOfComponents() must be equal 
8271  *               to the number of specified columns, else this is not required.
8272  *  \throw If \a a is NULL.
8273  *  \throw If \a a is not allocated.
8274  *  \throw If \a this is not allocated.
8275  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8276  *         out of a valid range for \a this array.
8277  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8278  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8279  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8280  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8281  *
8282  *  \if ENABLE_EXAMPLES
8283  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8284  *  \endif
8285  */
8286 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8287 {
8288   if(!a)
8289     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8290   const char msg[]="DataArrayInt::setPartOfValues2";
8291   checkAllocated();
8292   a->checkAllocated();
8293   int nbComp=getNumberOfComponents();
8294   int nbOfTuples=getNumberOfTuples();
8295   for(const int *z=bgComp;z!=endComp;z++)
8296     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8297   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8298   int newNbOfComp=(int)std::distance(bgComp,endComp);
8299   bool assignTech=true;
8300   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8301     {
8302       if(strictCompoCompare)
8303         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8304     }
8305   else
8306     {
8307       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8308       assignTech=false;
8309     }
8310   int *pt=getPointer();
8311   const int *srcPt=a->getConstPointer();
8312   if(assignTech)
8313     {    
8314       for(const int *w=bgTuples;w!=endTuples;w++)
8315         {
8316           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8317           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8318             {    
8319               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8320             }
8321         }
8322     }
8323   else
8324     {
8325       for(const int *w=bgTuples;w!=endTuples;w++)
8326         {
8327           const int *srcPt2=srcPt;
8328           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8329           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8330             {    
8331               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8332             }
8333         }
8334     }
8335 }
8336
8337 /*!
8338  * Assign a given value to values at specified tuples and components of \a this array.
8339  * The tuples and components to assign to are defined by C arrays of indices.
8340  *  \param [in] a - the value to assign.
8341  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8342  *              assign \a a to.
8343  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8344  *              pointer to a tuple index (\a pi) varies as this: 
8345  *              \a bgTuples <= \a pi < \a endTuples.
8346  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8347  *              assign \a a to.
8348  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8349  *              pointer to a component index (\a pi) varies as this: 
8350  *              \a bgComp <= \a pi < \a endComp.
8351  *  \throw If \a this is not allocated.
8352  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8353  *         out of a valid range for \a this array.
8354  *
8355  *  \if ENABLE_EXAMPLES
8356  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8357  *  \endif
8358  */
8359 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8360 {
8361   checkAllocated();
8362   int nbComp=getNumberOfComponents();
8363   int nbOfTuples=getNumberOfTuples();
8364   for(const int *z=bgComp;z!=endComp;z++)
8365     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8366   int *pt=getPointer();
8367   for(const int *w=bgTuples;w!=endTuples;w++)
8368     for(const int *z=bgComp;z!=endComp;z++)
8369       {
8370         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8371         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8372       }
8373 }
8374
8375 /*!
8376  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8377  * components of \a this array. Textual data is not copied.
8378  * The tuples to assign to are defined by a C array of indices.
8379  * The components to assign to are defined by three values similar to parameters of
8380  * the Python function \c range(\c start,\c stop,\c step).
8381  * There are two *modes of usage*:
8382  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8383  *   of \a a is assigned to its own location within \a this array. 
8384  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8385  *   components of every specified tuple of \a this array. In this mode it is required
8386  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8387  *
8388  *  \param [in] a - the array to copy values from.
8389  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8390  *              assign values of \a a to.
8391  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8392  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8393  *              \a bgTuples <= \a pi < \a endTuples.
8394  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8395  *  \param [in] endComp - index of the component before which the components to assign
8396  *              to are located.
8397  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8398  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8399  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8400  *               then \a a->getNumberOfComponents() must be equal 
8401  *               to the number of specified columns, else this is not required.
8402  *  \throw If \a a is NULL.
8403  *  \throw If \a a is not allocated.
8404  *  \throw If \a this is not allocated.
8405  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8406  *         \a this array.
8407  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8408  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8409  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8410  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8411  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8412  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8413  *  \throw If parameters specifying components to assign to, do not give a
8414  *            non-empty range of increasing indices or indices are out of a valid range
8415  *            for \c this array.
8416  *
8417  *  \if ENABLE_EXAMPLES
8418  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8419  *  \endif
8420  */
8421 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8422 {
8423   if(!a)
8424     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8425   const char msg[]="DataArrayInt::setPartOfValues3";
8426   checkAllocated();
8427   a->checkAllocated();
8428   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8429   int nbComp=getNumberOfComponents();
8430   int nbOfTuples=getNumberOfTuples();
8431   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8432   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8433   bool assignTech=true;
8434   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8435     {
8436       if(strictCompoCompare)
8437         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8438     }
8439   else
8440     {
8441       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8442       assignTech=false;
8443     }
8444   int *pt=getPointer()+bgComp;
8445   const int *srcPt=a->getConstPointer();
8446   if(assignTech)
8447     {
8448       for(const int *w=bgTuples;w!=endTuples;w++)
8449         for(int j=0;j<newNbOfComp;j++,srcPt++)
8450           {
8451             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8452             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8453           }
8454     }
8455   else
8456     {
8457       for(const int *w=bgTuples;w!=endTuples;w++)
8458         {
8459           const int *srcPt2=srcPt;
8460           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8461             {
8462               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8463               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8464             }
8465         }
8466     }
8467 }
8468
8469 /*!
8470  * Assign a given value to values at specified tuples and components of \a this array.
8471  * The tuples to assign to are defined by a C array of indices.
8472  * The components to assign to are defined by three values similar to parameters of
8473  * the Python function \c range(\c start,\c stop,\c step).
8474  *  \param [in] a - the value to assign.
8475  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8476  *              assign \a a to.
8477  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8478  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8479  *              \a bgTuples <= \a pi < \a endTuples.
8480  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8481  *  \param [in] endComp - index of the component before which the components to assign
8482  *              to are located.
8483  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8484  *  \throw If \a this is not allocated.
8485  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8486  *         \a this array.
8487  *  \throw If parameters specifying components to assign to, do not give a
8488  *            non-empty range of increasing indices or indices are out of a valid range
8489  *            for \c this array.
8490  *
8491  *  \if ENABLE_EXAMPLES
8492  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8493  *  \endif
8494  */
8495 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8496 {
8497   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8498   checkAllocated();
8499   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8500   int nbComp=getNumberOfComponents();
8501   int nbOfTuples=getNumberOfTuples();
8502   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8503   int *pt=getPointer()+bgComp;
8504   for(const int *w=bgTuples;w!=endTuples;w++)
8505     for(int j=0;j<newNbOfComp;j++)
8506       {
8507         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8508         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8509       }
8510 }
8511
8512 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8513 {
8514   if(!a)
8515     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8516   const char msg[]="DataArrayInt::setPartOfValues4";
8517   checkAllocated();
8518   a->checkAllocated();
8519   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8520   int newNbOfComp=(int)std::distance(bgComp,endComp);
8521   int nbComp=getNumberOfComponents();
8522   for(const int *z=bgComp;z!=endComp;z++)
8523     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8524   int nbOfTuples=getNumberOfTuples();
8525   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8526   bool assignTech=true;
8527   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8528     {
8529       if(strictCompoCompare)
8530         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8531     }
8532   else
8533     {
8534       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8535       assignTech=false;
8536     }
8537   const int *srcPt=a->getConstPointer();
8538   int *pt=getPointer()+bgTuples*nbComp;
8539   if(assignTech)
8540     {
8541       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8542         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8543           pt[*z]=*srcPt;
8544     }
8545   else
8546     {
8547       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8548         {
8549           const int *srcPt2=srcPt;
8550           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8551             pt[*z]=*srcPt2;
8552         }
8553     }
8554 }
8555
8556 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8557 {
8558   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8559   checkAllocated();
8560   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8561   int nbComp=getNumberOfComponents();
8562   for(const int *z=bgComp;z!=endComp;z++)
8563     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8564   int nbOfTuples=getNumberOfTuples();
8565   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8566   int *pt=getPointer()+bgTuples*nbComp;
8567   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8568     for(const int *z=bgComp;z!=endComp;z++)
8569       pt[*z]=a;
8570 }
8571
8572 /*!
8573  * Copy some tuples from another DataArrayInt into specified tuples
8574  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8575  * components.
8576  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8577  * All components of selected tuples are copied.
8578  *  \param [in] a - the array to copy values from.
8579  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8580  *              target tuples of \a this. \a tuplesSelec has two components, and the
8581  *              first component specifies index of the source tuple and the second
8582  *              one specifies index of the target tuple.
8583  *  \throw If \a this is not allocated.
8584  *  \throw If \a a is NULL.
8585  *  \throw If \a a is not allocated.
8586  *  \throw If \a tuplesSelec is NULL.
8587  *  \throw If \a tuplesSelec is not allocated.
8588  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8589  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8590  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8591  *         the corresponding (\a this or \a a) array.
8592  */
8593 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8594 {
8595   if(!a || !tuplesSelec)
8596     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8597   checkAllocated();
8598   a->checkAllocated();
8599   tuplesSelec->checkAllocated();
8600   int nbOfComp=getNumberOfComponents();
8601   if(nbOfComp!=a->getNumberOfComponents())
8602     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8603   if(tuplesSelec->getNumberOfComponents()!=2)
8604     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8605   int thisNt=getNumberOfTuples();
8606   int aNt=a->getNumberOfTuples();
8607   int *valsToSet=getPointer();
8608   const int *valsSrc=a->getConstPointer();
8609   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8610     {
8611       if(tuple[1]>=0 && tuple[1]<aNt)
8612         {
8613           if(tuple[0]>=0 && tuple[0]<thisNt)
8614             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8615           else
8616             {
8617               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8618               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8619               throw INTERP_KERNEL::Exception(oss.str().c_str());
8620             }
8621         }
8622       else
8623         {
8624           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8625           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8626           throw INTERP_KERNEL::Exception(oss.str().c_str());
8627         }
8628     }
8629 }
8630
8631 /*!
8632  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8633  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8634  * components.
8635  * The tuples to assign to are defined by index of the first tuple, and
8636  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8637  * The tuples to copy are defined by values of a DataArrayInt.
8638  * All components of selected tuples are copied.
8639  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8640  *              values to.
8641  *  \param [in] aBase - the array to copy values from.
8642  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8643  *  \throw If \a this is not allocated.
8644  *  \throw If \a aBase is NULL.
8645  *  \throw If \a aBase is not allocated.
8646  *  \throw If \a tuplesSelec is NULL.
8647  *  \throw If \a tuplesSelec is not allocated.
8648  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8649  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8650  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8651  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8652  *         \a aBase array.
8653  */
8654 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8655 {
8656   if(!aBase || !tuplesSelec)
8657     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8658   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8659   if(!a)
8660     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8661   checkAllocated();
8662   a->checkAllocated();
8663   tuplesSelec->checkAllocated();
8664   int nbOfComp=getNumberOfComponents();
8665   if(nbOfComp!=a->getNumberOfComponents())
8666     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8667   if(tuplesSelec->getNumberOfComponents()!=1)
8668     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8669   int thisNt=getNumberOfTuples();
8670   int aNt=a->getNumberOfTuples();
8671   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8672   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8673   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8674     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8675   const int *valsSrc=a->getConstPointer();
8676   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8677     {
8678       if(*tuple>=0 && *tuple<aNt)
8679         {
8680           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8681         }
8682       else
8683         {
8684           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8685           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8686           throw INTERP_KERNEL::Exception(oss.str().c_str());
8687         }
8688     }
8689 }
8690
8691 /*!
8692  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8693  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8694  * components.
8695  * The tuples to copy are defined by three values similar to parameters of
8696  * the Python function \c range(\c start,\c stop,\c step).
8697  * The tuples to assign to are defined by index of the first tuple, and
8698  * their number is defined by number of tuples to copy.
8699  * All components of selected tuples are copied.
8700  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8701  *              values to.
8702  *  \param [in] aBase - the array to copy values from.
8703  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8704  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8705  *              are located.
8706  *  \param [in] step - index increment to get index of the next tuple to copy.
8707  *  \throw If \a this is not allocated.
8708  *  \throw If \a aBase is NULL.
8709  *  \throw If \a aBase is not allocated.
8710  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8711  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8712  *  \throw If parameters specifying tuples to copy, do not give a
8713  *            non-empty range of increasing indices or indices are out of a valid range
8714  *            for the array \a aBase.
8715  */
8716 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8717 {
8718   if(!aBase)
8719     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8720   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8721   if(!a)
8722     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8723   checkAllocated();
8724   a->checkAllocated();
8725   int nbOfComp=getNumberOfComponents();
8726   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8727   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8728   if(nbOfComp!=a->getNumberOfComponents())
8729     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8730   int thisNt=getNumberOfTuples();
8731   int aNt=a->getNumberOfTuples();
8732   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8733   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8734     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8735   if(end2>aNt)
8736     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8737   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8738   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8739     {
8740       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8741     }
8742 }
8743
8744 /*!
8745  * Returns a value located at specified tuple and component.
8746  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8747  * parameters is checked. So this method is safe but expensive if used to go through
8748  * all values of \a this.
8749  *  \param [in] tupleId - index of tuple of interest.
8750  *  \param [in] compoId - index of component of interest.
8751  *  \return double - value located by \a tupleId and \a compoId.
8752  *  \throw If \a this is not allocated.
8753  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8754  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8755  */
8756 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8757 {
8758   checkAllocated();
8759   if(tupleId<0 || tupleId>=getNumberOfTuples())
8760     {
8761       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8762       throw INTERP_KERNEL::Exception(oss.str().c_str());
8763     }
8764   if(compoId<0 || compoId>=getNumberOfComponents())
8765     {
8766       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8767       throw INTERP_KERNEL::Exception(oss.str().c_str());
8768     }
8769   return _mem[tupleId*_info_on_compo.size()+compoId];
8770 }
8771
8772 /*!
8773  * Returns the first value of \a this. 
8774  *  \return int - the last value of \a this array.
8775  *  \throw If \a this is not allocated.
8776  *  \throw If \a this->getNumberOfComponents() != 1.
8777  *  \throw If \a this->getNumberOfTuples() < 1.
8778  */
8779 int DataArrayInt::front() const
8780 {
8781   checkAllocated();
8782   if(getNumberOfComponents()!=1)
8783     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8784   int nbOfTuples=getNumberOfTuples();
8785   if(nbOfTuples<1)
8786     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8787   return *(getConstPointer());
8788 }
8789
8790 /*!
8791  * Returns the last value of \a this. 
8792  *  \return int - the last value of \a this array.
8793  *  \throw If \a this is not allocated.
8794  *  \throw If \a this->getNumberOfComponents() != 1.
8795  *  \throw If \a this->getNumberOfTuples() < 1.
8796  */
8797 int DataArrayInt::back() const
8798 {
8799   checkAllocated();
8800   if(getNumberOfComponents()!=1)
8801     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8802   int nbOfTuples=getNumberOfTuples();
8803   if(nbOfTuples<1)
8804     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8805   return *(getConstPointer()+nbOfTuples-1);
8806 }
8807
8808 /*!
8809  * Assign pointer to one array to a pointer to another appay. Reference counter of
8810  * \a arrayToSet is incremented / decremented.
8811  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8812  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8813  */
8814 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8815 {
8816   if(newArray!=arrayToSet)
8817     {
8818       if(arrayToSet)
8819         arrayToSet->decrRef();
8820       arrayToSet=newArray;
8821       if(arrayToSet)
8822         arrayToSet->incrRef();
8823     }
8824 }
8825
8826 DataArrayIntIterator *DataArrayInt::iterator()
8827 {
8828   return new DataArrayIntIterator(this);
8829 }
8830
8831 /*!
8832  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8833  * given one. The ids are sorted in the ascending order.
8834  *  \param [in] val - the value to find within \a this.
8835  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8836  *          array using decrRef() as it is no more needed.
8837  *  \throw If \a this is not allocated.
8838  *  \throw If \a this->getNumberOfComponents() != 1.
8839  *  \sa DataArrayInt::getIdsEqualTuple
8840  */
8841 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8842 {
8843   checkAllocated();
8844   if(getNumberOfComponents()!=1)
8845     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8846   const int *cptr(getConstPointer());
8847   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8848   int nbOfTuples=getNumberOfTuples();
8849   for(int i=0;i<nbOfTuples;i++,cptr++)
8850     if(*cptr==val)
8851       ret->pushBackSilent(i);
8852   return ret.retn();
8853 }
8854
8855 /*!
8856  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8857  * equal to a given one. 
8858  *  \param [in] val - the value to ignore within \a this.
8859  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8860  *          array using decrRef() as it is no more needed.
8861  *  \throw If \a this is not allocated.
8862  *  \throw If \a this->getNumberOfComponents() != 1.
8863  */
8864 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8865 {
8866   checkAllocated();
8867   if(getNumberOfComponents()!=1)
8868     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8869   const int *cptr(getConstPointer());
8870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8871   int nbOfTuples=getNumberOfTuples();
8872   for(int i=0;i<nbOfTuples;i++,cptr++)
8873     if(*cptr!=val)
8874       ret->pushBackSilent(i);
8875   return ret.retn();
8876 }
8877
8878 /*!
8879  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8880  * This method is an extension of  DataArrayInt::getIdsEqual method.
8881  *
8882  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8883  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8884  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8885  *          array using decrRef() as it is no more needed.
8886  *  \throw If \a this is not allocated.
8887  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8888  * \throw If \a this->getNumberOfComponents() is equal to 0.
8889  * \sa DataArrayInt::getIdsEqual
8890  */
8891 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8892 {
8893   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8894   checkAllocated();
8895   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8896     {
8897       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8898       throw INTERP_KERNEL::Exception(oss.str().c_str());
8899     }
8900   if(nbOfCompoExp==0)
8901     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8902   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8903   const int *bg(begin()),*end2(end()),*work(begin());
8904   while(work!=end2)
8905     {
8906       work=std::search(work,end2,tupleBg,tupleEnd);
8907       if(work!=end2)
8908         {
8909           std::size_t pos(std::distance(bg,work));
8910           if(pos%nbOfCompoExp==0)
8911             ret->pushBackSilent(pos/nbOfCompoExp);
8912           work++;
8913         }
8914     }
8915   return ret.retn();
8916 }
8917
8918 /*!
8919  * Assigns \a newValue to all elements holding \a oldValue within \a this
8920  * one-dimensional array.
8921  *  \param [in] oldValue - the value to replace.
8922  *  \param [in] newValue - the value to assign.
8923  *  \return int - number of replacements performed.
8924  *  \throw If \a this is not allocated.
8925  *  \throw If \a this->getNumberOfComponents() != 1.
8926  */
8927 int DataArrayInt::changeValue(int oldValue, int newValue)
8928 {
8929   checkAllocated();
8930   if(getNumberOfComponents()!=1)
8931     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8932   int *start=getPointer();
8933   int *end2=start+getNbOfElems();
8934   int ret=0;
8935   for(int *val=start;val!=end2;val++)
8936     {
8937       if(*val==oldValue)
8938         {
8939           *val=newValue;
8940           ret++;
8941         }
8942     }
8943   return ret;
8944 }
8945
8946 /*!
8947  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8948  * one of given values.
8949  *  \param [in] valsBg - an array of values to find within \a this array.
8950  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8951  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8952  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8953  *          array using decrRef() as it is no more needed.
8954  *  \throw If \a this->getNumberOfComponents() != 1.
8955  */
8956 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8957 {
8958   if(getNumberOfComponents()!=1)
8959     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8960   std::set<int> vals2(valsBg,valsEnd);
8961   const int *cptr=getConstPointer();
8962   std::vector<int> res;
8963   int nbOfTuples=getNumberOfTuples();
8964   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8965   for(int i=0;i<nbOfTuples;i++,cptr++)
8966     if(vals2.find(*cptr)!=vals2.end())
8967       ret->pushBackSilent(i);
8968   return ret.retn();
8969 }
8970
8971 /*!
8972  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8973  * equal to any of given values.
8974  *  \param [in] valsBg - an array of values to ignore within \a this array.
8975  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8976  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8977  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8978  *          array using decrRef() as it is no more needed.
8979  *  \throw If \a this->getNumberOfComponents() != 1.
8980  */
8981 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8982 {
8983   if(getNumberOfComponents()!=1)
8984     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8985   std::set<int> vals2(valsBg,valsEnd);
8986   const int *cptr=getConstPointer();
8987   std::vector<int> res;
8988   int nbOfTuples=getNumberOfTuples();
8989   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8990   for(int i=0;i<nbOfTuples;i++,cptr++)
8991     if(vals2.find(*cptr)==vals2.end())
8992       ret->pushBackSilent(i);
8993   return ret.retn();
8994 }
8995
8996 /*!
8997  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8998  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8999  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9000  * If any the tuple id is returned. If not -1 is returned.
9001  * 
9002  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9003  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9004  *
9005  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
9006  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
9007  */
9008 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
9009 {
9010   checkAllocated();
9011   int nbOfCompo=getNumberOfComponents();
9012   if(nbOfCompo==0)
9013     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
9014   if(nbOfCompo!=(int)tupl.size())
9015     {
9016       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
9017       throw INTERP_KERNEL::Exception(oss.str().c_str());
9018     }
9019   const int *cptr=getConstPointer();
9020   std::size_t nbOfVals=getNbOfElems();
9021   for(const int *work=cptr;work!=cptr+nbOfVals;)
9022     {
9023       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
9024       if(work!=cptr+nbOfVals)
9025         {
9026           if(std::distance(cptr,work)%nbOfCompo!=0)
9027             work++;
9028           else
9029             return std::distance(cptr,work)/nbOfCompo;
9030         }
9031     }
9032   return -1;
9033 }
9034
9035 /*!
9036  * This method searches the sequence specified in input parameter \b vals in \b this.
9037  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
9038  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
9039  * \sa DataArrayInt::locateTuple
9040  */
9041 int DataArrayInt::search(const std::vector<int>& vals) const
9042 {
9043   checkAllocated();
9044   int nbOfCompo=getNumberOfComponents();
9045   if(nbOfCompo!=1)
9046     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
9047   const int *cptr=getConstPointer();
9048   std::size_t nbOfVals=getNbOfElems();
9049   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
9050   if(loc!=cptr+nbOfVals)
9051     return std::distance(cptr,loc);
9052   return -1;
9053 }
9054
9055 /*!
9056  * This method expects to be called when number of components of this is equal to one.
9057  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
9058  * If not any tuple contains \b value -1 is returned.
9059  * \sa DataArrayInt::presenceOfValue
9060  */
9061 int DataArrayInt::locateValue(int value) const
9062 {
9063   checkAllocated();
9064   if(getNumberOfComponents()!=1)
9065     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9066   const int *cptr=getConstPointer();
9067   int nbOfTuples=getNumberOfTuples();
9068   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
9069   if(ret!=cptr+nbOfTuples)
9070     return std::distance(cptr,ret);
9071   return -1;
9072 }
9073
9074 /*!
9075  * This method expects to be called when number of components of this is equal to one.
9076  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
9077  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
9078  * \sa DataArrayInt::presenceOfValue
9079  */
9080 int DataArrayInt::locateValue(const std::vector<int>& vals) const
9081 {
9082   checkAllocated();
9083   if(getNumberOfComponents()!=1)
9084     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9085   std::set<int> vals2(vals.begin(),vals.end());
9086   const int *cptr=getConstPointer();
9087   int nbOfTuples=getNumberOfTuples();
9088   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
9089     if(vals2.find(*w)!=vals2.end())
9090       return std::distance(cptr,w);
9091   return -1;
9092 }
9093
9094 /*!
9095  * This method returns the number of values in \a this that are equals to input parameter \a value.
9096  * This method only works for single component array.
9097  *
9098  * \return a value in [ 0, \c this->getNumberOfTuples() )
9099  *
9100  * \throw If \a this is not allocated
9101  *
9102  */
9103 int DataArrayInt::count(int value) const
9104 {
9105   int ret=0;
9106   checkAllocated();
9107   if(getNumberOfComponents()!=1)
9108     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
9109   const int *vals=begin();
9110   int nbOfTuples=getNumberOfTuples();
9111   for(int i=0;i<nbOfTuples;i++,vals++)
9112     if(*vals==value)
9113       ret++;
9114   return ret;
9115 }
9116
9117 /*!
9118  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
9119  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9120  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9121  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9122  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9123  * \sa DataArrayInt::locateTuple
9124  */
9125 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
9126 {
9127   return locateTuple(tupl)!=-1;
9128 }
9129
9130
9131 /*!
9132  * Returns \a true if a given value is present within \a this one-dimensional array.
9133  *  \param [in] value - the value to find within \a this array.
9134  *  \return bool - \a true in case if \a value is present within \a this array.
9135  *  \throw If \a this is not allocated.
9136  *  \throw If \a this->getNumberOfComponents() != 1.
9137  *  \sa locateValue()
9138  */
9139 bool DataArrayInt::presenceOfValue(int value) const
9140 {
9141   return locateValue(value)!=-1;
9142 }
9143
9144 /*!
9145  * This method expects to be called when number of components of this is equal to one.
9146  * This method returns true if it exists a tuple so that the value is contained in \b vals.
9147  * If not any tuple contains one of the values contained in 'vals' false is returned.
9148  * \sa DataArrayInt::locateValue
9149  */
9150 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
9151 {
9152   return locateValue(vals)!=-1;
9153 }
9154
9155 /*!
9156  * Accumulates values of each component of \a this array.
9157  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
9158  *         by the caller, that is filled by this method with sum value for each
9159  *         component.
9160  *  \throw If \a this is not allocated.
9161  */
9162 void DataArrayInt::accumulate(int *res) const
9163 {
9164   checkAllocated();
9165   const int *ptr=getConstPointer();
9166   int nbTuple=getNumberOfTuples();
9167   int nbComps=getNumberOfComponents();
9168   std::fill(res,res+nbComps,0);
9169   for(int i=0;i<nbTuple;i++)
9170     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9171 }
9172
9173 int DataArrayInt::accumulate(int compId) const
9174 {
9175   checkAllocated();
9176   const int *ptr=getConstPointer();
9177   int nbTuple=getNumberOfTuples();
9178   int nbComps=getNumberOfComponents();
9179   if(compId<0 || compId>=nbComps)
9180     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9181   int ret=0;
9182   for(int i=0;i<nbTuple;i++)
9183     ret+=ptr[i*nbComps+compId];
9184   return ret;
9185 }
9186
9187 /*!
9188  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9189  * The returned array will have same number of components than \a this and number of tuples equal to
9190  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9191  *
9192  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9193  *
9194  * \param [in] bgOfIndex - begin (included) of the input index array.
9195  * \param [in] endOfIndex - end (excluded) of the input index array.
9196  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9197  * 
9198  * \throw If bgOfIndex or end is NULL.
9199  * \throw If input index array is not ascendingly sorted.
9200  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9201  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9202  */
9203 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9204 {
9205   if(!bgOfIndex || !endOfIndex)
9206     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9207   checkAllocated();
9208   int nbCompo=getNumberOfComponents();
9209   int nbOfTuples=getNumberOfTuples();
9210   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9211   if(sz<1)
9212     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9213   sz--;
9214   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9215   const int *w=bgOfIndex;
9216   if(*w<0 || *w>=nbOfTuples)
9217     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9218   const int *srcPt=begin()+(*w)*nbCompo;
9219   int *tmp=ret->getPointer();
9220   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9221     {
9222       std::fill(tmp,tmp+nbCompo,0);
9223       if(w[1]>=w[0])
9224         {
9225           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9226             {
9227               if(j>=0 && j<nbOfTuples)
9228                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9229               else
9230                 {
9231                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9232                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9233                 }
9234             }
9235         }
9236       else
9237         {
9238           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9239           throw INTERP_KERNEL::Exception(oss.str().c_str());
9240         }
9241     }
9242   ret->copyStringInfoFrom(*this);
9243   return ret.retn();
9244 }
9245
9246 /*!
9247  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9248  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9249  * offsetA2</em> and (2)
9250  * the number of component in the result array is same as that of each of given arrays.
9251  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9252  * Info on components is copied from the first of the given arrays. Number of components
9253  * in the given arrays must be the same.
9254  *  \param [in] a1 - an array to include in the result array.
9255  *  \param [in] a2 - another array to include in the result array.
9256  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9257  *  \return DataArrayInt * - the new instance of DataArrayInt.
9258  *          The caller is to delete this result array using decrRef() as it is no more
9259  *          needed.
9260  *  \throw If either \a a1 or \a a2 is NULL.
9261  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9262  */
9263 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9264 {
9265   if(!a1 || !a2)
9266     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9267   int nbOfComp=a1->getNumberOfComponents();
9268   if(nbOfComp!=a2->getNumberOfComponents())
9269     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9270   int nbOfTuple1=a1->getNumberOfTuples();
9271   int nbOfTuple2=a2->getNumberOfTuples();
9272   DataArrayInt *ret=DataArrayInt::New();
9273   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9274   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9275   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9276   ret->copyStringInfoFrom(*a1);
9277   return ret;
9278 }
9279
9280 /*!
9281  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9282  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9283  * the number of component in the result array is same as that of each of given arrays.
9284  * Info on components is copied from the first of the given arrays. Number of components
9285  * in the given arrays must be  the same.
9286  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9287  * not the object itself.
9288  *  \param [in] arr - a sequence of arrays to include in the result array.
9289  *  \return DataArrayInt * - the new instance of DataArrayInt.
9290  *          The caller is to delete this result array using decrRef() as it is no more
9291  *          needed.
9292  *  \throw If all arrays within \a arr are NULL.
9293  *  \throw If getNumberOfComponents() of arrays within \a arr.
9294  */
9295 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9296 {
9297   std::vector<const DataArrayInt *> a;
9298   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9299     if(*it4)
9300       a.push_back(*it4);
9301   if(a.empty())
9302     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9303   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9304   int nbOfComp=(*it)->getNumberOfComponents();
9305   int nbt=(*it++)->getNumberOfTuples();
9306   for(int i=1;it!=a.end();it++,i++)
9307     {
9308       if((*it)->getNumberOfComponents()!=nbOfComp)
9309         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9310       nbt+=(*it)->getNumberOfTuples();
9311     }
9312   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9313   ret->alloc(nbt,nbOfComp);
9314   int *pt=ret->getPointer();
9315   for(it=a.begin();it!=a.end();it++)
9316     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9317   ret->copyStringInfoFrom(*(a[0]));
9318   return ret.retn();
9319 }
9320
9321 /*!
9322  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9323  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9324  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9325  * 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.
9326  * 
9327  * \return DataArrayInt * - a new object to be managed by the caller.
9328  */
9329 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9330 {
9331   int retSz=1;
9332   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9333     {
9334       if(*it4)
9335         {
9336           (*it4)->checkAllocated();
9337           if((*it4)->getNumberOfComponents()!=1)
9338             {
9339               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9340               throw INTERP_KERNEL::Exception(oss.str().c_str());
9341             }
9342           int nbTupl=(*it4)->getNumberOfTuples();
9343           if(nbTupl<1)
9344             {
9345               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9346               throw INTERP_KERNEL::Exception(oss.str().c_str());
9347             }
9348           if((*it4)->front()!=0)
9349             {
9350               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9351               throw INTERP_KERNEL::Exception(oss.str().c_str());
9352             }
9353           retSz+=nbTupl-1;
9354         }
9355       else
9356         {
9357           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9358           throw INTERP_KERNEL::Exception(oss.str().c_str());
9359         }
9360     }
9361   if(arrs.empty())
9362     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9363   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9364   ret->alloc(retSz,1);
9365   int *pt=ret->getPointer(); *pt++=0;
9366   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9367     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9368   ret->copyStringInfoFrom(*(arrs[0]));
9369   return ret.retn();
9370 }
9371
9372 /*!
9373  * Returns the maximal value and its location within \a this one-dimensional array.
9374  *  \param [out] tupleId - index of the tuple holding the maximal value.
9375  *  \return int - the maximal value among all values of \a this array.
9376  *  \throw If \a this->getNumberOfComponents() != 1
9377  *  \throw If \a this->getNumberOfTuples() < 1
9378  */
9379 int DataArrayInt::getMaxValue(int& tupleId) const
9380 {
9381   checkAllocated();
9382   if(getNumberOfComponents()!=1)
9383     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9384   int nbOfTuples=getNumberOfTuples();
9385   if(nbOfTuples<=0)
9386     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9387   const int *vals=getConstPointer();
9388   const int *loc=std::max_element(vals,vals+nbOfTuples);
9389   tupleId=(int)std::distance(vals,loc);
9390   return *loc;
9391 }
9392
9393 /*!
9394  * Returns the maximal value within \a this array that is allowed to have more than
9395  *  one component.
9396  *  \return int - the maximal value among all values of \a this array.
9397  *  \throw If \a this is not allocated.
9398  */
9399 int DataArrayInt::getMaxValueInArray() const
9400 {
9401   checkAllocated();
9402   const int *loc=std::max_element(begin(),end());
9403   return *loc;
9404 }
9405
9406 /*!
9407  * Returns the minimal value and its location within \a this one-dimensional array.
9408  *  \param [out] tupleId - index of the tuple holding the minimal value.
9409  *  \return int - the minimal value among all values of \a this array.
9410  *  \throw If \a this->getNumberOfComponents() != 1
9411  *  \throw If \a this->getNumberOfTuples() < 1
9412  */
9413 int DataArrayInt::getMinValue(int& tupleId) const
9414 {
9415   checkAllocated();
9416   if(getNumberOfComponents()!=1)
9417     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9418   int nbOfTuples=getNumberOfTuples();
9419   if(nbOfTuples<=0)
9420     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9421   const int *vals=getConstPointer();
9422   const int *loc=std::min_element(vals,vals+nbOfTuples);
9423   tupleId=(int)std::distance(vals,loc);
9424   return *loc;
9425 }
9426
9427 /*!
9428  * Returns the minimal value within \a this array that is allowed to have more than
9429  *  one component.
9430  *  \return int - the minimal value among all values of \a this array.
9431  *  \throw If \a this is not allocated.
9432  */
9433 int DataArrayInt::getMinValueInArray() const
9434 {
9435   checkAllocated();
9436   const int *loc=std::min_element(begin(),end());
9437   return *loc;
9438 }
9439
9440 /*!
9441  * Returns in a single walk in \a this the min value and the max value in \a this.
9442  * \a this is expected to be single component array.
9443  *
9444  * \param [out] minValue - the min value in \a this.
9445  * \param [out] maxValue - the max value in \a this.
9446  *
9447  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9448  */
9449 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9450 {
9451   checkAllocated();
9452   if(getNumberOfComponents()!=1)
9453     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9454   int nbTuples(getNumberOfTuples());
9455   const int *pt(begin());
9456   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9457   for(int i=0;i<nbTuples;i++,pt++)
9458     {
9459       if(*pt<minValue)
9460         minValue=*pt;
9461       if(*pt>maxValue)
9462         maxValue=*pt;
9463     }
9464 }
9465
9466 /*!
9467  * Converts every value of \a this array to its absolute value.
9468  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9469  * should be called instead.
9470  *
9471  * \throw If \a this is not allocated.
9472  * \sa DataArrayInt::computeAbs
9473  */
9474 void DataArrayInt::abs()
9475 {
9476   checkAllocated();
9477   int *ptr(getPointer());
9478   std::size_t nbOfElems(getNbOfElems());
9479   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9480   declareAsNew();
9481 }
9482
9483 /*!
9484  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9485  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9486  *
9487  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9488  *         same number of tuples and component as \a this array.
9489  *         The caller is to delete this result array using decrRef() as it is no more
9490  *         needed.
9491  * \throw If \a this is not allocated.
9492  * \sa DataArrayInt::abs
9493  */
9494 DataArrayInt *DataArrayInt::computeAbs() const
9495 {
9496   checkAllocated();
9497   DataArrayInt *newArr(DataArrayInt::New());
9498   int nbOfTuples(getNumberOfTuples());
9499   int nbOfComp(getNumberOfComponents());
9500   newArr->alloc(nbOfTuples,nbOfComp);
9501   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9502   newArr->copyStringInfoFrom(*this);
9503   return newArr;
9504 }
9505
9506 /*!
9507  * Apply a liner function to a given component of \a this array, so that
9508  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9509  *  \param [in] a - the first coefficient of the function.
9510  *  \param [in] b - the second coefficient of the function.
9511  *  \param [in] compoId - the index of component to modify.
9512  *  \throw If \a this is not allocated.
9513  */
9514 void DataArrayInt::applyLin(int a, int b, int compoId)
9515 {
9516   checkAllocated();
9517   int *ptr=getPointer()+compoId;
9518   int nbOfComp=getNumberOfComponents();
9519   int nbOfTuple=getNumberOfTuples();
9520   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9521     *ptr=a*(*ptr)+b;
9522   declareAsNew();
9523 }
9524
9525 /*!
9526  * Apply a liner function to all elements of \a this array, so that
9527  * an element _x_ becomes \f$ a * x + b \f$.
9528  *  \param [in] a - the first coefficient of the function.
9529  *  \param [in] b - the second coefficient of the function.
9530  *  \throw If \a this is not allocated.
9531  */
9532 void DataArrayInt::applyLin(int a, int b)
9533 {
9534   checkAllocated();
9535   int *ptr=getPointer();
9536   std::size_t nbOfElems=getNbOfElems();
9537   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9538     *ptr=a*(*ptr)+b;
9539   declareAsNew();
9540 }
9541
9542 /*!
9543  * Returns a full copy of \a this array except that sign of all elements is reversed.
9544  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9545  *          same number of tuples and component as \a this array.
9546  *          The caller is to delete this result array using decrRef() as it is no more
9547  *          needed.
9548  *  \throw If \a this is not allocated.
9549  */
9550 DataArrayInt *DataArrayInt::negate() const
9551 {
9552   checkAllocated();
9553   DataArrayInt *newArr=DataArrayInt::New();
9554   int nbOfTuples=getNumberOfTuples();
9555   int nbOfComp=getNumberOfComponents();
9556   newArr->alloc(nbOfTuples,nbOfComp);
9557   const int *cptr=getConstPointer();
9558   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9559   newArr->copyStringInfoFrom(*this);
9560   return newArr;
9561 }
9562
9563 /*!
9564  * Modify all elements of \a this array, so that
9565  * an element _x_ becomes \f$ numerator / x \f$.
9566  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9567  *           array, all elements processed before detection of the zero element remain
9568  *           modified.
9569  *  \param [in] numerator - the numerator used to modify array elements.
9570  *  \throw If \a this is not allocated.
9571  *  \throw If there is an element equal to 0 in \a this array.
9572  */
9573 void DataArrayInt::applyInv(int numerator)
9574 {
9575   checkAllocated();
9576   int *ptr=getPointer();
9577   std::size_t nbOfElems=getNbOfElems();
9578   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9579     {
9580       if(*ptr!=0)
9581         {
9582           *ptr=numerator/(*ptr);
9583         }
9584       else
9585         {
9586           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9587           oss << " !";
9588           throw INTERP_KERNEL::Exception(oss.str().c_str());
9589         }
9590     }
9591   declareAsNew();
9592 }
9593
9594 /*!
9595  * Modify all elements of \a this array, so that
9596  * an element _x_ becomes \f$ x / val \f$.
9597  *  \param [in] val - the denominator used to modify array elements.
9598  *  \throw If \a this is not allocated.
9599  *  \throw If \a val == 0.
9600  */
9601 void DataArrayInt::applyDivideBy(int val)
9602 {
9603   if(val==0)
9604     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9605   checkAllocated();
9606   int *ptr=getPointer();
9607   std::size_t nbOfElems=getNbOfElems();
9608   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9609   declareAsNew();
9610 }
9611
9612 /*!
9613  * Modify all elements of \a this array, so that
9614  * an element _x_ becomes  <em> x % val </em>.
9615  *  \param [in] val - the divisor used to modify array elements.
9616  *  \throw If \a this is not allocated.
9617  *  \throw If \a val <= 0.
9618  */
9619 void DataArrayInt::applyModulus(int val)
9620 {
9621   if(val<=0)
9622     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9623   checkAllocated();
9624   int *ptr=getPointer();
9625   std::size_t nbOfElems=getNbOfElems();
9626   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9627   declareAsNew();
9628 }
9629
9630 /*!
9631  * This method works only on data array with one component.
9632  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9633  * this[*id] in [\b vmin,\b vmax)
9634  * 
9635  * \param [in] vmin begin of range. This value is included in range (included).
9636  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9637  * \return a newly allocated data array that the caller should deal with.
9638  *
9639  * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative
9640  */
9641 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9642 {
9643   checkAllocated();
9644   if(getNumberOfComponents()!=1)
9645     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9646   const int *cptr(begin());
9647   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9648   int nbOfTuples(getNumberOfTuples());
9649   for(int i=0;i<nbOfTuples;i++,cptr++)
9650     if(*cptr>=vmin && *cptr<vmax)
9651       ret->pushBackSilent(i);
9652   return ret.retn();
9653 }
9654
9655 /*!
9656  * This method works only on data array with one component.
9657  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9658  * this[*id] \b not in [\b vmin,\b vmax)
9659  * 
9660  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9661  * \param [in] vmax end of range. This value is included in range (included).
9662  * \return a newly allocated data array that the caller should deal with.
9663  * 
9664  * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative
9665  */
9666 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9667 {
9668   checkAllocated();
9669   if(getNumberOfComponents()!=1)
9670     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9671   const int *cptr(getConstPointer());
9672   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9673   int nbOfTuples(getNumberOfTuples());
9674   for(int i=0;i<nbOfTuples;i++,cptr++)
9675     if(*cptr<vmin || *cptr>=vmax)
9676       ret->pushBackSilent(i);
9677   return ret.retn();
9678 }
9679
9680 /*!
9681  * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
9682  *
9683  * \return a newly allocated data array that the caller should deal with.
9684  * \sa DataArrayInt::getIdsInRange
9685  */
9686 DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const
9687 {
9688   checkAllocated();
9689   if(getNumberOfComponents()!=1)
9690     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !");
9691   const int *cptr(getConstPointer());
9692   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9693   int nbOfTuples(getNumberOfTuples());
9694   for(int i=0;i<nbOfTuples;i++,cptr++)
9695     if(*cptr<0)
9696       ret->pushBackSilent(i);
9697   return ret.retn();
9698 }
9699
9700 /*!
9701  * This method works only on data array with one component.
9702  * 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.
9703  * 
9704  * \param [in] vmin begin of range. This value is included in range (included).
9705  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9706  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9707 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9708 {
9709   checkAllocated();
9710   if(getNumberOfComponents()!=1)
9711     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9712   int nbOfTuples=getNumberOfTuples();
9713   bool ret=true;
9714   const int *cptr=getConstPointer();
9715   for(int i=0;i<nbOfTuples;i++,cptr++)
9716     {
9717       if(*cptr>=vmin && *cptr<vmax)
9718         { ret=ret && *cptr==i; }
9719       else
9720         {
9721           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9722           throw INTERP_KERNEL::Exception(oss.str().c_str());
9723         }
9724     }
9725   return ret;
9726 }
9727
9728 /*!
9729  * Modify all elements of \a this array, so that
9730  * an element _x_ becomes <em> val % x </em>.
9731  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9732  *           array, all elements processed before detection of the zero element remain
9733  *           modified.
9734  *  \param [in] val - the divident used to modify array elements.
9735  *  \throw If \a this is not allocated.
9736  *  \throw If there is an element equal to or less than 0 in \a this array.
9737  */
9738 void DataArrayInt::applyRModulus(int val)
9739 {
9740   checkAllocated();
9741   int *ptr=getPointer();
9742   std::size_t nbOfElems=getNbOfElems();
9743   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9744     {
9745       if(*ptr>0)
9746         {
9747           *ptr=val%(*ptr);
9748         }
9749       else
9750         {
9751           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9752           oss << " !";
9753           throw INTERP_KERNEL::Exception(oss.str().c_str());
9754         }
9755     }
9756   declareAsNew();
9757 }
9758
9759 /*!
9760  * Modify all elements of \a this array, so that
9761  * an element _x_ becomes <em> val ^ x </em>.
9762  *  \param [in] val - the value used to apply pow on all array elements.
9763  *  \throw If \a this is not allocated.
9764  *  \throw If \a val < 0.
9765  */
9766 void DataArrayInt::applyPow(int val)
9767 {
9768   checkAllocated();
9769   if(val<0)
9770     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9771   int *ptr=getPointer();
9772   std::size_t nbOfElems=getNbOfElems();
9773   if(val==0)
9774     {
9775       std::fill(ptr,ptr+nbOfElems,1);
9776       return ;
9777     }
9778   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9779     {
9780       int tmp=1;
9781       for(int j=0;j<val;j++)
9782         tmp*=*ptr;
9783       *ptr=tmp;
9784     }
9785   declareAsNew();
9786 }
9787
9788 /*!
9789  * Modify all elements of \a this array, so that
9790  * an element _x_ becomes \f$ val ^ x \f$.
9791  *  \param [in] val - the value used to apply pow on all array elements.
9792  *  \throw If \a this is not allocated.
9793  *  \throw If there is an element < 0 in \a this array.
9794  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9795  *           array, all elements processed before detection of the zero element remain
9796  *           modified.
9797  */
9798 void DataArrayInt::applyRPow(int val)
9799 {
9800   checkAllocated();
9801   int *ptr=getPointer();
9802   std::size_t nbOfElems=getNbOfElems();
9803   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9804     {
9805       if(*ptr>=0)
9806         {
9807           int tmp=1;
9808           for(int j=0;j<*ptr;j++)
9809             tmp*=val;
9810           *ptr=tmp;
9811         }
9812       else
9813         {
9814           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9815           oss << " !";
9816           throw INTERP_KERNEL::Exception(oss.str().c_str());
9817         }
9818     }
9819   declareAsNew();
9820 }
9821
9822 /*!
9823  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9824  * of components in the result array is a sum of the number of components of given arrays
9825  * and (2) the number of tuples in the result array is same as that of each of given
9826  * arrays. In other words the i-th tuple of result array includes all components of
9827  * i-th tuples of all given arrays.
9828  * Number of tuples in the given arrays must be the same.
9829  *  \param [in] a1 - an array to include in the result array.
9830  *  \param [in] a2 - another array to include in the result array.
9831  *  \return DataArrayInt * - the new instance of DataArrayInt.
9832  *          The caller is to delete this result array using decrRef() as it is no more
9833  *          needed.
9834  *  \throw If both \a a1 and \a a2 are NULL.
9835  *  \throw If any given array is not allocated.
9836  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9837  */
9838 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9839 {
9840   std::vector<const DataArrayInt *> arr(2);
9841   arr[0]=a1; arr[1]=a2;
9842   return Meld(arr);
9843 }
9844
9845 /*!
9846  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9847  * of components in the result array is a sum of the number of components of given arrays
9848  * and (2) the number of tuples in the result array is same as that of each of given
9849  * arrays. In other words the i-th tuple of result array includes all components of
9850  * i-th tuples of all given arrays.
9851  * Number of tuples in the given arrays must be  the same.
9852  *  \param [in] arr - a sequence of arrays to include in the result array.
9853  *  \return DataArrayInt * - the new instance of DataArrayInt.
9854  *          The caller is to delete this result array using decrRef() as it is no more
9855  *          needed.
9856  *  \throw If all arrays within \a arr are NULL.
9857  *  \throw If any given array is not allocated.
9858  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9859  */
9860 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9861 {
9862   std::vector<const DataArrayInt *> a;
9863   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9864     if(*it4)
9865       a.push_back(*it4);
9866   if(a.empty())
9867     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9868   std::vector<const DataArrayInt *>::const_iterator it;
9869   for(it=a.begin();it!=a.end();it++)
9870     (*it)->checkAllocated();
9871   it=a.begin();
9872   int nbOfTuples=(*it)->getNumberOfTuples();
9873   std::vector<int> nbc(a.size());
9874   std::vector<const int *> pts(a.size());
9875   nbc[0]=(*it)->getNumberOfComponents();
9876   pts[0]=(*it++)->getConstPointer();
9877   for(int i=1;it!=a.end();it++,i++)
9878     {
9879       if(nbOfTuples!=(*it)->getNumberOfTuples())
9880         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9881       nbc[i]=(*it)->getNumberOfComponents();
9882       pts[i]=(*it)->getConstPointer();
9883     }
9884   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9885   DataArrayInt *ret=DataArrayInt::New();
9886   ret->alloc(nbOfTuples,totalNbOfComp);
9887   int *retPtr=ret->getPointer();
9888   for(int i=0;i<nbOfTuples;i++)
9889     for(int j=0;j<(int)a.size();j++)
9890       {
9891         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9892         pts[j]+=nbc[j];
9893       }
9894   int k=0;
9895   for(int i=0;i<(int)a.size();i++)
9896     for(int j=0;j<nbc[i];j++,k++)
9897       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9898   return ret;
9899 }
9900
9901 /*!
9902  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9903  * The i-th item of the result array is an ID of a set of elements belonging to a
9904  * unique set of groups, which the i-th element is a part of. This set of elements
9905  * belonging to a unique set of groups is called \a family, so the result array contains
9906  * IDs of families each element belongs to.
9907  *
9908  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9909  * then there are 3 families:
9910  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9911  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9912  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9913  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9914  * stands for the element #3 which is in none of groups.
9915  *
9916  *  \param [in] groups - sequence of groups of element IDs.
9917  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9918  *         in \a groups.
9919  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9920  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9921  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9922  *         delete this array using decrRef() as it is no more needed.
9923  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9924  */
9925 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9926 {
9927   std::vector<const DataArrayInt *> groups2;
9928   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9929     if(*it4)
9930       groups2.push_back(*it4);
9931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9932   ret->alloc(newNb,1);
9933   int *retPtr=ret->getPointer();
9934   std::fill(retPtr,retPtr+newNb,0);
9935   int fid=1;
9936   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9937     {
9938       const int *ptr=(*iter)->getConstPointer();
9939       std::size_t nbOfElem=(*iter)->getNbOfElems();
9940       int sfid=fid;
9941       for(int j=0;j<sfid;j++)
9942         {
9943           bool found=false;
9944           for(std::size_t i=0;i<nbOfElem;i++)
9945             {
9946               if(ptr[i]>=0 && ptr[i]<newNb)
9947                 {
9948                   if(retPtr[ptr[i]]==j)
9949                     {
9950                       retPtr[ptr[i]]=fid;
9951                       found=true;
9952                     }
9953                 }
9954               else
9955                 {
9956                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9957                   oss << ") !";
9958                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9959                 }
9960             }
9961           if(found)
9962             fid++;
9963         }
9964     }
9965   fidsOfGroups.clear();
9966   fidsOfGroups.resize(groups2.size());
9967   int grId=0;
9968   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9969     {
9970       std::set<int> tmp;
9971       const int *ptr=(*iter)->getConstPointer();
9972       std::size_t nbOfElem=(*iter)->getNbOfElems();
9973       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9974         tmp.insert(retPtr[*p]);
9975       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9976     }
9977   return ret.retn();
9978 }
9979
9980 /*!
9981  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9982  * arrays. The result array does not contain any duplicates and its values
9983  * are sorted in ascending order.
9984  *  \param [in] arr - sequence of DataArrayInt's to unite.
9985  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9986  *         array using decrRef() as it is no more needed.
9987  *  \throw If any \a arr[i] is not allocated.
9988  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9989  */
9990 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9991 {
9992   std::vector<const DataArrayInt *> a;
9993   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9994     if(*it4)
9995       a.push_back(*it4);
9996   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9997     {
9998       (*it)->checkAllocated();
9999       if((*it)->getNumberOfComponents()!=1)
10000         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
10001     }
10002   //
10003   std::set<int> r;
10004   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10005     {
10006       const int *pt=(*it)->getConstPointer();
10007       int nbOfTuples=(*it)->getNumberOfTuples();
10008       r.insert(pt,pt+nbOfTuples);
10009     }
10010   DataArrayInt *ret=DataArrayInt::New();
10011   ret->alloc((int)r.size(),1);
10012   std::copy(r.begin(),r.end(),ret->getPointer());
10013   return ret;
10014 }
10015
10016 /*!
10017  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
10018  * arrays. The result array does not contain any duplicates and its values
10019  * are sorted in ascending order.
10020  *  \param [in] arr - sequence of DataArrayInt's to intersect.
10021  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10022  *         array using decrRef() as it is no more needed.
10023  *  \throw If any \a arr[i] is not allocated.
10024  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
10025  */
10026 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
10027 {
10028   std::vector<const DataArrayInt *> a;
10029   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
10030     if(*it4)
10031       a.push_back(*it4);
10032   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10033     {
10034       (*it)->checkAllocated();
10035       if((*it)->getNumberOfComponents()!=1)
10036         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
10037     }
10038   //
10039   std::set<int> r;
10040   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10041     {
10042       const int *pt=(*it)->getConstPointer();
10043       int nbOfTuples=(*it)->getNumberOfTuples();
10044       std::set<int> s1(pt,pt+nbOfTuples);
10045       if(it!=a.begin())
10046         {
10047           std::set<int> r2;
10048           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
10049           r=r2;
10050         }
10051       else
10052         r=s1;
10053     }
10054   DataArrayInt *ret(DataArrayInt::New());
10055   ret->alloc((int)r.size(),1);
10056   std::copy(r.begin(),r.end(),ret->getPointer());
10057   return ret;
10058 }
10059
10060 /// @cond INTERNAL
10061 namespace ParaMEDMEMImpl
10062 {
10063   class OpSwitchedOn
10064   {
10065   public:
10066     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
10067     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
10068   private:
10069     int *_pt;
10070     int _cnt;
10071   };
10072
10073   class OpSwitchedOff
10074   {
10075   public:
10076     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
10077     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
10078   private:
10079     int *_pt;
10080     int _cnt;
10081   };
10082 }
10083 /// @endcond
10084
10085 /*!
10086  * This method returns the list of ids in ascending mode so that v[id]==true.
10087  */
10088 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
10089 {
10090   int sz((int)std::count(v.begin(),v.end(),true));
10091   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10092   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
10093   return ret.retn();
10094 }
10095
10096 /*!
10097  * This method returns the list of ids in ascending mode so that v[id]==false.
10098  */
10099 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
10100 {
10101   int sz((int)std::count(v.begin(),v.end(),false));
10102   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10103   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
10104   return ret.retn();
10105 }
10106
10107 /*!
10108  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
10109  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
10110  *
10111  * \param [in] v the input data structure to be translate into skyline format.
10112  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
10113  * \param [out] dataIndex the second element of the skyline format.
10114  */
10115 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
10116 {
10117   int sz((int)v.size());
10118   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
10119   ret1->alloc(sz+1,1);
10120   int *pt(ret1->getPointer()); *pt=0;
10121   for(int i=0;i<sz;i++,pt++)
10122     pt[1]=pt[0]+(int)v[i].size();
10123   ret0->alloc(ret1->back(),1);
10124   pt=ret0->getPointer();
10125   for(int i=0;i<sz;i++)
10126     pt=std::copy(v[i].begin(),v[i].end(),pt);
10127   data=ret0.retn(); dataIndex=ret1.retn();
10128 }
10129
10130 /*!
10131  * Returns a new DataArrayInt which contains a complement of elements of \a this
10132  * one-dimensional array. I.e. the result array contains all elements from the range [0,
10133  * \a nbOfElement) not present in \a this array.
10134  *  \param [in] nbOfElement - maximal size of the result array.
10135  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10136  *         array using decrRef() as it is no more needed.
10137  *  \throw If \a this is not allocated.
10138  *  \throw If \a this->getNumberOfComponents() != 1.
10139  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
10140  *         nbOfElement ).
10141  */
10142 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
10143 {
10144   checkAllocated();
10145   if(getNumberOfComponents()!=1)
10146     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
10147   std::vector<bool> tmp(nbOfElement);
10148   const int *pt=getConstPointer();
10149   int nbOfTuples=getNumberOfTuples();
10150   for(const int *w=pt;w!=pt+nbOfTuples;w++)
10151     if(*w>=0 && *w<nbOfElement)
10152       tmp[*w]=true;
10153     else
10154       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
10155   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
10156   DataArrayInt *ret=DataArrayInt::New();
10157   ret->alloc(nbOfRetVal,1);
10158   int j=0;
10159   int *retPtr=ret->getPointer();
10160   for(int i=0;i<nbOfElement;i++)
10161     if(!tmp[i])
10162       retPtr[j++]=i;
10163   return ret;
10164 }
10165
10166 /*!
10167  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10168  * from an \a other one-dimensional array.
10169  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10170  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10171  *         caller is to delete this array using decrRef() as it is no more needed.
10172  *  \throw If \a other is NULL.
10173  *  \throw If \a other is not allocated.
10174  *  \throw If \a other->getNumberOfComponents() != 1.
10175  *  \throw If \a this is not allocated.
10176  *  \throw If \a this->getNumberOfComponents() != 1.
10177  *  \sa DataArrayInt::buildSubstractionOptimized()
10178  */
10179 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10180 {
10181   if(!other)
10182     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10183   checkAllocated();
10184   other->checkAllocated();
10185   if(getNumberOfComponents()!=1)
10186     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10187   if(other->getNumberOfComponents()!=1)
10188     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10189   const int *pt=getConstPointer();
10190   int nbOfTuples=getNumberOfTuples();
10191   std::set<int> s1(pt,pt+nbOfTuples);
10192   pt=other->getConstPointer();
10193   nbOfTuples=other->getNumberOfTuples();
10194   std::set<int> s2(pt,pt+nbOfTuples);
10195   std::vector<int> r;
10196   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10197   DataArrayInt *ret=DataArrayInt::New();
10198   ret->alloc((int)r.size(),1);
10199   std::copy(r.begin(),r.end(),ret->getPointer());
10200   return ret;
10201 }
10202
10203 /*!
10204  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10205  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10206  * 
10207  * \param [in] other an array with one component and expected to be sorted ascendingly.
10208  * \ret list of ids in \a this but not in \a other.
10209  * \sa DataArrayInt::buildSubstraction
10210  */
10211 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10212 {
10213   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10214   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10215   checkAllocated(); other->checkAllocated();
10216   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10217   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10218   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10219   const int *work1(pt1Bg),*work2(pt2Bg);
10220   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10221   for(;work1!=pt1End;work1++)
10222     {
10223       if(work2!=pt2End && *work1==*work2)
10224         work2++;
10225       else
10226         ret->pushBackSilent(*work1);
10227     }
10228   return ret.retn();
10229 }
10230
10231
10232 /*!
10233  * Returns a new DataArrayInt which contains all elements of \a this and a given
10234  * one-dimensional arrays. The result array does not contain any duplicates
10235  * and its values are sorted in ascending order.
10236  *  \param [in] other - an array to unite with \a this one.
10237  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10238  *         array using decrRef() as it is no more needed.
10239  *  \throw If \a this or \a other is not allocated.
10240  *  \throw If \a this->getNumberOfComponents() != 1.
10241  *  \throw If \a other->getNumberOfComponents() != 1.
10242  */
10243 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10244 {
10245   std::vector<const DataArrayInt *>arrs(2);
10246   arrs[0]=this; arrs[1]=other;
10247   return BuildUnion(arrs);
10248 }
10249
10250
10251 /*!
10252  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10253  * one-dimensional arrays. The result array does not contain any duplicates
10254  * and its values are sorted in ascending order.
10255  *  \param [in] other - an array to intersect with \a this one.
10256  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10257  *         array using decrRef() as it is no more needed.
10258  *  \throw If \a this or \a other is not allocated.
10259  *  \throw If \a this->getNumberOfComponents() != 1.
10260  *  \throw If \a other->getNumberOfComponents() != 1.
10261  */
10262 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10263 {
10264   std::vector<const DataArrayInt *>arrs(2);
10265   arrs[0]=this; arrs[1]=other;
10266   return BuildIntersection(arrs);
10267 }
10268
10269 /*!
10270  * This method can be applied on allocated with one component DataArrayInt instance.
10271  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10272  * 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]
10273  * 
10274  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10275  * \throw if \a this is not allocated or if \a this has not exactly one component.
10276  * \sa DataArrayInt::buildUniqueNotSorted
10277  */
10278 DataArrayInt *DataArrayInt::buildUnique() const
10279 {
10280   checkAllocated();
10281   if(getNumberOfComponents()!=1)
10282     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10283   int nbOfTuples=getNumberOfTuples();
10284   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
10285   int *data=tmp->getPointer();
10286   int *last=std::unique(data,data+nbOfTuples);
10287   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10288   ret->alloc(std::distance(data,last),1);
10289   std::copy(data,last,ret->getPointer());
10290   return ret.retn();
10291 }
10292
10293 /*!
10294  * This method can be applied on allocated with one component DataArrayInt instance.
10295  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10296  *
10297  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10298  *
10299  * \throw if \a this is not allocated or if \a this has not exactly one component.
10300  *
10301  * \sa DataArrayInt::buildUnique
10302  */
10303 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10304 {
10305   checkAllocated();
10306     if(getNumberOfComponents()!=1)
10307       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10308   int minVal,maxVal;
10309   getMinMaxValues(minVal,maxVal);
10310   std::vector<bool> b(maxVal-minVal+1,false);
10311   const int *ptBg(begin()),*endBg(end());
10312   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10313   for(const int *pt=ptBg;pt!=endBg;pt++)
10314     {
10315       if(!b[*pt-minVal])
10316         {
10317           ret->pushBackSilent(*pt);
10318           b[*pt-minVal]=true;
10319         }
10320     }
10321   ret->copyStringInfoFrom(*this);
10322   return ret.retn();
10323 }
10324
10325 /*!
10326  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10327  * "index" array. Such "index" array is returned for example by 
10328  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
10329  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10330  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
10331  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10332  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
10333  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10334  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10335  *          The caller is to delete this array using decrRef() as it is no more needed. 
10336  *  \throw If \a this is not allocated.
10337  *  \throw If \a this->getNumberOfComponents() != 1.
10338  *  \throw If \a this->getNumberOfTuples() < 2.
10339  *
10340  *  \b Example: <br> 
10341  *         - this contains [1,3,6,7,7,9,15]
10342  *         - result array contains [2,3,1,0,2,6],
10343  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10344  *
10345  * \sa DataArrayInt::computeOffsets2
10346  */
10347 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10348 {
10349   checkAllocated();
10350   if(getNumberOfComponents()!=1)
10351     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10352   int nbOfTuples=getNumberOfTuples();
10353   if(nbOfTuples<2)
10354     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10355   const int *ptr=getConstPointer();
10356   DataArrayInt *ret=DataArrayInt::New();
10357   ret->alloc(nbOfTuples-1,1);
10358   int *out=ret->getPointer();
10359   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10360   return ret;
10361 }
10362
10363 /*!
10364  * Modifies \a this one-dimensional array so that value of each element \a x
10365  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10366  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10367  * and components remains the same.<br>
10368  * This method is useful for allToAllV in MPI with contiguous policy. This method
10369  * differs from computeOffsets2() in that the number of tuples is \b not changed by
10370  * this one.
10371  *  \throw If \a this is not allocated.
10372  *  \throw If \a this->getNumberOfComponents() != 1.
10373  *
10374  *  \b Example: <br>
10375  *          - Before \a this contains [3,5,1,2,0,8]
10376  *          - After \a this contains  [0,3,8,9,11,11]<br>
10377  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10378  *          array is retained and thus there is no space to store the last element.
10379  */
10380 void DataArrayInt::computeOffsets()
10381 {
10382   checkAllocated();
10383   if(getNumberOfComponents()!=1)
10384     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10385   int nbOfTuples=getNumberOfTuples();
10386   if(nbOfTuples==0)
10387     return ;
10388   int *work=getPointer();
10389   int tmp=work[0];
10390   work[0]=0;
10391   for(int i=1;i<nbOfTuples;i++)
10392     {
10393       int tmp2=work[i];
10394       work[i]=work[i-1]+tmp;
10395       tmp=tmp2;
10396     }
10397   declareAsNew();
10398 }
10399
10400
10401 /*!
10402  * Modifies \a this one-dimensional array so that value of each element \a x
10403  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10404  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10405  * components remains the same and number of tuples is inceamented by one.<br>
10406  * This method is useful for allToAllV in MPI with contiguous policy. This method
10407  * differs from computeOffsets() in that the number of tuples is changed by this one.
10408  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10409  *  \throw If \a this is not allocated.
10410  *  \throw If \a this->getNumberOfComponents() != 1.
10411  *
10412  *  \b Example: <br>
10413  *          - Before \a this contains [3,5,1,2,0,8]
10414  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10415  * \sa DataArrayInt::deltaShiftIndex
10416  */
10417 void DataArrayInt::computeOffsets2()
10418 {
10419   checkAllocated();
10420   if(getNumberOfComponents()!=1)
10421     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
10422   int nbOfTuples=getNumberOfTuples();
10423   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10424   const int *work=getConstPointer();
10425   ret[0]=0;
10426   for(int i=0;i<nbOfTuples;i++)
10427     ret[i+1]=work[i]+ret[i];
10428   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10429   declareAsNew();
10430 }
10431
10432 /*!
10433  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10434  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10435  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10436  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10437  * filling completely one of the ranges in \a this.
10438  *
10439  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10440  * \param [out] rangeIdsFetched the range ids fetched
10441  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10442  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10443  *
10444  * \sa DataArrayInt::computeOffsets2
10445  *
10446  *  \b Example: <br>
10447  *          - \a this : [0,3,7,9,15,18]
10448  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10449  *          - \a rangeIdsFetched result array: [0,2,4]
10450  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10451  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10452  * <br>
10453  */
10454 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10455 {
10456   if(!listOfIds)
10457     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10458   listOfIds->checkAllocated(); checkAllocated();
10459   if(listOfIds->getNumberOfComponents()!=1)
10460     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10461   if(getNumberOfComponents()!=1)
10462     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10463   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10464   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10465   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10466   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10467   while(tupPtr!=tupEnd && offPtr!=offEnd)
10468     {
10469       if(*tupPtr==*offPtr)
10470         {
10471           int i=offPtr[0];
10472           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10473           if(i==offPtr[1])
10474             {
10475               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10476               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10477               offPtr++;
10478             }
10479         }
10480       else
10481         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10482     }
10483   rangeIdsFetched=ret0.retn();
10484   idsInInputListThatFetch=ret1.retn();
10485 }
10486
10487 /*!
10488  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10489  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10490  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10491  * beginning within the "iota" array. And \a this is a one-dimensional array
10492  * considered as a selector of groups described by \a offsets to include into the result array.
10493  *  \throw If \a offsets is NULL.
10494  *  \throw If \a offsets is not allocated.
10495  *  \throw If \a offsets->getNumberOfComponents() != 1.
10496  *  \throw If \a offsets is not monotonically increasing.
10497  *  \throw If \a this is not allocated.
10498  *  \throw If \a this->getNumberOfComponents() != 1.
10499  *  \throw If any element of \a this is not a valid index for \a offsets array.
10500  *
10501  *  \b Example: <br>
10502  *          - \a this: [0,2,3]
10503  *          - \a offsets: [0,3,6,10,14,20]
10504  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10505  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10506  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10507  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10508  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10509  */
10510 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10511 {
10512   if(!offsets)
10513     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10514   checkAllocated();
10515   if(getNumberOfComponents()!=1)
10516     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10517   offsets->checkAllocated();
10518   if(offsets->getNumberOfComponents()!=1)
10519     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10520   int othNbTuples=offsets->getNumberOfTuples()-1;
10521   int nbOfTuples=getNumberOfTuples();
10522   int retNbOftuples=0;
10523   const int *work=getConstPointer();
10524   const int *offPtr=offsets->getConstPointer();
10525   for(int i=0;i<nbOfTuples;i++)
10526     {
10527       int val=work[i];
10528       if(val>=0 && val<othNbTuples)
10529         {
10530           int delta=offPtr[val+1]-offPtr[val];
10531           if(delta>=0)
10532             retNbOftuples+=delta;
10533           else
10534             {
10535               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10536               throw INTERP_KERNEL::Exception(oss.str().c_str());
10537             }
10538         }
10539       else
10540         {
10541           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10542           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10543           throw INTERP_KERNEL::Exception(oss.str().c_str());
10544         }
10545     }
10546   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10547   ret->alloc(retNbOftuples,1);
10548   int *retPtr=ret->getPointer();
10549   for(int i=0;i<nbOfTuples;i++)
10550     {
10551       int val=work[i];
10552       int start=offPtr[val];
10553       int off=offPtr[val+1]-start;
10554       for(int j=0;j<off;j++,retPtr++)
10555         *retPtr=start+j;
10556     }
10557   return ret.retn();
10558 }
10559
10560 /*!
10561  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10562  * scaled array (monotonically increasing).
10563 from that of \a this and \a
10564  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10565  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10566  * beginning within the "iota" array. And \a this is a one-dimensional array
10567  * considered as a selector of groups described by \a offsets to include into the result array.
10568  *  \throw If \a  is NULL.
10569  *  \throw If \a this is not allocated.
10570  *  \throw If \a this->getNumberOfComponents() != 1.
10571  *  \throw If \a this->getNumberOfTuples() == 0.
10572  *  \throw If \a this is not monotonically increasing.
10573  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10574  *
10575  *  \b Example: <br>
10576  *          - \a bg , \a stop and \a step : (0,5,2)
10577  *          - \a this: [0,3,6,10,14,20]
10578  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10579  */
10580 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10581 {
10582   if(!isAllocated())
10583     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10584   if(getNumberOfComponents()!=1)
10585     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10586   int nbOfTuples(getNumberOfTuples());
10587   if(nbOfTuples==0)
10588     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10589   const int *ids(begin());
10590   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10591   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10592     {
10593       if(pos>=0 && pos<nbOfTuples-1)
10594         {
10595           int delta(ids[pos+1]-ids[pos]);
10596           sz+=delta;
10597           if(delta<0)
10598             {
10599               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10600               throw INTERP_KERNEL::Exception(oss.str().c_str());
10601             }          
10602         }
10603       else
10604         {
10605           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10606           throw INTERP_KERNEL::Exception(oss.str().c_str());
10607         }
10608     }
10609   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10610   int *retPtr(ret->getPointer());
10611   pos=bg;
10612   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10613     {
10614       int delta(ids[pos+1]-ids[pos]);
10615       for(int j=0;j<delta;j++,retPtr++)
10616         *retPtr=pos;
10617     }
10618   return ret.retn();
10619 }
10620
10621 /*!
10622  * 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.
10623  * 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
10624  * in tuple **i** of returned DataArrayInt.
10625  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10626  *
10627  * 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)]
10628  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10629  * 
10630  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10631  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10632  * \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
10633  *        is thrown if no ranges in \a ranges contains value in \a this.
10634  * 
10635  * \sa DataArrayInt::findIdInRangeForEachTuple
10636  */
10637 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10638 {
10639   if(!ranges)
10640     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10641   if(ranges->getNumberOfComponents()!=2)
10642     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10643   checkAllocated();
10644   if(getNumberOfComponents()!=1)
10645     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10646   int nbTuples=getNumberOfTuples();
10647   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10648   int nbOfRanges=ranges->getNumberOfTuples();
10649   const int *rangesPtr=ranges->getConstPointer();
10650   int *retPtr=ret->getPointer();
10651   const int *inPtr=getConstPointer();
10652   for(int i=0;i<nbTuples;i++,retPtr++)
10653     {
10654       int val=inPtr[i];
10655       bool found=false;
10656       for(int j=0;j<nbOfRanges && !found;j++)
10657         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10658           { *retPtr=j; found=true; }
10659       if(found)
10660         continue;
10661       else
10662         {
10663           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10664           throw INTERP_KERNEL::Exception(oss.str().c_str());
10665         }
10666     }
10667   return ret.retn();
10668 }
10669
10670 /*!
10671  * 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.
10672  * 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
10673  * in tuple **i** of returned DataArrayInt.
10674  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10675  *
10676  * 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)]
10677  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10678  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10679  * 
10680  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10681  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10682  * \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
10683  *        is thrown if no ranges in \a ranges contains value in \a this.
10684  * \sa DataArrayInt::findRangeIdForEachTuple
10685  */
10686 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10687 {
10688   if(!ranges)
10689     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10690   if(ranges->getNumberOfComponents()!=2)
10691     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10692   checkAllocated();
10693   if(getNumberOfComponents()!=1)
10694     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10695   int nbTuples=getNumberOfTuples();
10696   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10697   int nbOfRanges=ranges->getNumberOfTuples();
10698   const int *rangesPtr=ranges->getConstPointer();
10699   int *retPtr=ret->getPointer();
10700   const int *inPtr=getConstPointer();
10701   for(int i=0;i<nbTuples;i++,retPtr++)
10702     {
10703       int val=inPtr[i];
10704       bool found=false;
10705       for(int j=0;j<nbOfRanges && !found;j++)
10706         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10707           { *retPtr=val-rangesPtr[2*j]; found=true; }
10708       if(found)
10709         continue;
10710       else
10711         {
10712           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10713           throw INTERP_KERNEL::Exception(oss.str().c_str());
10714         }
10715     }
10716   return ret.retn();
10717 }
10718
10719 /*!
10720  * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2).
10721  * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0).
10722  * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified !
10723  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10724  * This method does nothing if number of tuples is lower of equal to 1.
10725  *
10726  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10727  *
10728  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10729  */
10730 void DataArrayInt::sortEachPairToMakeALinkedList()
10731 {
10732   checkAllocated();
10733   if(getNumberOfComponents()!=2)
10734     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10735   int nbOfTuples(getNumberOfTuples());
10736   if(nbOfTuples<=1)
10737     return ;
10738   int *conn(getPointer());
10739   for(int i=1;i<nbOfTuples;i++,conn+=2)
10740     {
10741       if(i>1)
10742         {
10743           if(conn[2]==conn[3])
10744             {
10745               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10746               throw INTERP_KERNEL::Exception(oss.str().c_str());
10747             }
10748           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10749             std::swap(conn[2],conn[3]);
10750           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10751           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10752             {
10753               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10754               throw INTERP_KERNEL::Exception(oss.str().c_str());
10755             }
10756         }
10757       else
10758         {
10759           if(conn[0]==conn[1] || conn[2]==conn[3])
10760             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10761           int tmp[4];
10762           std::set<int> s;
10763           s.insert(conn,conn+4);
10764           if(s.size()!=3)
10765             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10766           if(std::count(conn,conn+4,conn[0])==2)
10767             {
10768               tmp[0]=conn[1];
10769               tmp[1]=conn[0];
10770               tmp[2]=conn[0];
10771               if(conn[2]==conn[0])
10772                 { tmp[3]=conn[3]; }
10773               else
10774                 { tmp[3]=conn[2];}
10775               std::copy(tmp,tmp+4,conn);
10776             }
10777         }
10778     }
10779 }
10780
10781 /*!
10782  * 
10783  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10784  *             \a nbTimes  should be at least equal to 1.
10785  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10786  * \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.
10787  */
10788 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10789 {
10790   checkAllocated();
10791   if(getNumberOfComponents()!=1)
10792     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10793   if(nbTimes<1)
10794     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10795   int nbTuples=getNumberOfTuples();
10796   const int *inPtr=getConstPointer();
10797   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10798   int *retPtr=ret->getPointer();
10799   for(int i=0;i<nbTuples;i++,inPtr++)
10800     {
10801       int val=*inPtr;
10802       for(int j=0;j<nbTimes;j++,retPtr++)
10803         *retPtr=val;
10804     }
10805   ret->copyStringInfoFrom(*this);
10806   return ret.retn();
10807 }
10808
10809 /*!
10810  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10811  * But the number of components can be different from one.
10812  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10813  */
10814 DataArrayInt *DataArrayInt::getDifferentValues() const
10815 {
10816   checkAllocated();
10817   std::set<int> ret;
10818   ret.insert(begin(),end());
10819   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10820   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10821   return ret2.retn();
10822 }
10823
10824 /*!
10825  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10826  * them it tells which tuple id have this id.
10827  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10828  * This method returns two arrays having same size.
10829  * 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.
10830  * 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]]
10831  */
10832 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10833 {
10834   checkAllocated();
10835   if(getNumberOfComponents()!=1)
10836     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10837   int id=0;
10838   std::map<int,int> m,m2,m3;
10839   for(const int *w=begin();w!=end();w++)
10840     m[*w]++;
10841   differentIds.resize(m.size());
10842   std::vector<DataArrayInt *> ret(m.size());
10843   std::vector<int *> retPtr(m.size());
10844   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10845     {
10846       m2[(*it).first]=id;
10847       ret[id]=DataArrayInt::New();
10848       ret[id]->alloc((*it).second,1);
10849       retPtr[id]=ret[id]->getPointer();
10850       differentIds[id]=(*it).first;
10851     }
10852   id=0;
10853   for(const int *w=begin();w!=end();w++,id++)
10854     {
10855       retPtr[m2[*w]][m3[*w]++]=id;
10856     }
10857   return ret;
10858 }
10859
10860 /*!
10861  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10862  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10863  *
10864  * \param [in] nbOfSlices - number of slices expected.
10865  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10866  * 
10867  * \sa DataArray::GetSlice
10868  * \throw If \a this is not allocated or not with exactly one component.
10869  * \throw If an element in \a this if < 0.
10870  */
10871 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10872 {
10873   if(!isAllocated() || getNumberOfComponents()!=1)
10874     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10875   if(nbOfSlices<=0)
10876     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10877   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10878   int sumPerSlc(sum/nbOfSlices),pos(0);
10879   const int *w(begin());
10880   std::vector< std::pair<int,int> > ret(nbOfSlices);
10881   for(int i=0;i<nbOfSlices;i++)
10882     {
10883       std::pair<int,int> p(pos,-1);
10884       int locSum(0);
10885       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10886       if(i!=nbOfSlices-1)
10887         p.second=pos;
10888       else
10889         p.second=nbOfTuples;
10890       ret[i]=p;
10891     }
10892   return ret;
10893 }
10894
10895 /*!
10896  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10897  * valid cases.
10898  * 1.  The arrays have same number of tuples and components. Then each value of
10899  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10900  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10901  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10902  *   component. Then
10903  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10904  * 3.  The arrays have same number of components and one array, say _a2_, has one
10905  *   tuple. Then
10906  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10907  *
10908  * Info on components is copied either from the first array (in the first case) or from
10909  * the array with maximal number of elements (getNbOfElems()).
10910  *  \param [in] a1 - an array to sum up.
10911  *  \param [in] a2 - another array to sum up.
10912  *  \return DataArrayInt * - the new instance of DataArrayInt.
10913  *          The caller is to delete this result array using decrRef() as it is no more
10914  *          needed.
10915  *  \throw If either \a a1 or \a a2 is NULL.
10916  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10917  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10918  *         none of them has number of tuples or components equal to 1.
10919  */
10920 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10921 {
10922   if(!a1 || !a2)
10923     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10924   int nbOfTuple=a1->getNumberOfTuples();
10925   int nbOfTuple2=a2->getNumberOfTuples();
10926   int nbOfComp=a1->getNumberOfComponents();
10927   int nbOfComp2=a2->getNumberOfComponents();
10928   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10929   if(nbOfTuple==nbOfTuple2)
10930     {
10931       if(nbOfComp==nbOfComp2)
10932         {
10933           ret=DataArrayInt::New();
10934           ret->alloc(nbOfTuple,nbOfComp);
10935           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10936           ret->copyStringInfoFrom(*a1);
10937         }
10938       else
10939         {
10940           int nbOfCompMin,nbOfCompMax;
10941           const DataArrayInt *aMin, *aMax;
10942           if(nbOfComp>nbOfComp2)
10943             {
10944               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10945               aMin=a2; aMax=a1;
10946             }
10947           else
10948             {
10949               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10950               aMin=a1; aMax=a2;
10951             }
10952           if(nbOfCompMin==1)
10953             {
10954               ret=DataArrayInt::New();
10955               ret->alloc(nbOfTuple,nbOfCompMax);
10956               const int *aMinPtr=aMin->getConstPointer();
10957               const int *aMaxPtr=aMax->getConstPointer();
10958               int *res=ret->getPointer();
10959               for(int i=0;i<nbOfTuple;i++)
10960                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10961               ret->copyStringInfoFrom(*aMax);
10962             }
10963           else
10964             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10965         }
10966     }
10967   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10968     {
10969       if(nbOfComp==nbOfComp2)
10970         {
10971           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10972           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10973           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10974           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10975           ret=DataArrayInt::New();
10976           ret->alloc(nbOfTupleMax,nbOfComp);
10977           int *res=ret->getPointer();
10978           for(int i=0;i<nbOfTupleMax;i++)
10979             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10980           ret->copyStringInfoFrom(*aMax);
10981         }
10982       else
10983         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10984     }
10985   else
10986     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10987   return ret.retn();
10988 }
10989
10990 /*!
10991  * Adds values of another DataArrayInt to values of \a this one. There are 3
10992  * valid cases.
10993  * 1.  The arrays have same number of tuples and components. Then each value of
10994  *   \a other array is added to the corresponding value of \a this array, i.e.:
10995  *   _a_ [ i, j ] += _other_ [ i, j ].
10996  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10997  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10998  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10999  *   _a_ [ i, j ] += _a2_ [ 0, j ].
11000  *
11001  *  \param [in] other - an array to add to \a this one.
11002  *  \throw If \a other is NULL.
11003  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11004  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11005  *         \a other has number of both tuples and components not equal to 1.
11006  */
11007 void DataArrayInt::addEqual(const DataArrayInt *other)
11008 {
11009   if(!other)
11010     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
11011   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
11012   checkAllocated(); other->checkAllocated();
11013   int nbOfTuple=getNumberOfTuples();
11014   int nbOfTuple2=other->getNumberOfTuples();
11015   int nbOfComp=getNumberOfComponents();
11016   int nbOfComp2=other->getNumberOfComponents();
11017   if(nbOfTuple==nbOfTuple2)
11018     {
11019       if(nbOfComp==nbOfComp2)
11020         {
11021           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
11022         }
11023       else if(nbOfComp2==1)
11024         {
11025           int *ptr=getPointer();
11026           const int *ptrc=other->getConstPointer();
11027           for(int i=0;i<nbOfTuple;i++)
11028             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
11029         }
11030       else
11031         throw INTERP_KERNEL::Exception(msg);
11032     }
11033   else if(nbOfTuple2==1)
11034     {
11035       if(nbOfComp2==nbOfComp)
11036         {
11037           int *ptr=getPointer();
11038           const int *ptrc=other->getConstPointer();
11039           for(int i=0;i<nbOfTuple;i++)
11040             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
11041         }
11042       else
11043         throw INTERP_KERNEL::Exception(msg);
11044     }
11045   else
11046     throw INTERP_KERNEL::Exception(msg);
11047   declareAsNew();
11048 }
11049
11050 /*!
11051  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
11052  * valid cases.
11053  * 1.  The arrays have same number of tuples and components. Then each value of
11054  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
11055  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
11056  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11057  *   component. Then
11058  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
11059  * 3.  The arrays have same number of components and one array, say _a2_, has one
11060  *   tuple. Then
11061  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
11062  *
11063  * Info on components is copied either from the first array (in the first case) or from
11064  * the array with maximal number of elements (getNbOfElems()).
11065  *  \param [in] a1 - an array to subtract from.
11066  *  \param [in] a2 - an array to subtract.
11067  *  \return DataArrayInt * - the new instance of DataArrayInt.
11068  *          The caller is to delete this result array using decrRef() as it is no more
11069  *          needed.
11070  *  \throw If either \a a1 or \a a2 is NULL.
11071  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11072  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11073  *         none of them has number of tuples or components equal to 1.
11074  */
11075 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
11076 {
11077   if(!a1 || !a2)
11078     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
11079   int nbOfTuple1=a1->getNumberOfTuples();
11080   int nbOfTuple2=a2->getNumberOfTuples();
11081   int nbOfComp1=a1->getNumberOfComponents();
11082   int nbOfComp2=a2->getNumberOfComponents();
11083   if(nbOfTuple2==nbOfTuple1)
11084     {
11085       if(nbOfComp1==nbOfComp2)
11086         {
11087           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11088           ret->alloc(nbOfTuple2,nbOfComp1);
11089           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
11090           ret->copyStringInfoFrom(*a1);
11091           return ret.retn();
11092         }
11093       else if(nbOfComp2==1)
11094         {
11095           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11096           ret->alloc(nbOfTuple1,nbOfComp1);
11097           const int *a2Ptr=a2->getConstPointer();
11098           const int *a1Ptr=a1->getConstPointer();
11099           int *res=ret->getPointer();
11100           for(int i=0;i<nbOfTuple1;i++)
11101             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
11102           ret->copyStringInfoFrom(*a1);
11103           return ret.retn();
11104         }
11105       else
11106         {
11107           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11108           return 0;
11109         }
11110     }
11111   else if(nbOfTuple2==1)
11112     {
11113       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11114       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11115       ret->alloc(nbOfTuple1,nbOfComp1);
11116       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11117       int *pt=ret->getPointer();
11118       for(int i=0;i<nbOfTuple1;i++)
11119         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
11120       ret->copyStringInfoFrom(*a1);
11121       return ret.retn();
11122     }
11123   else
11124     {
11125       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
11126       return 0;
11127     }
11128 }
11129
11130 /*!
11131  * Subtract values of another DataArrayInt from values of \a this one. There are 3
11132  * valid cases.
11133  * 1.  The arrays have same number of tuples and components. Then each value of
11134  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
11135  *   _a_ [ i, j ] -= _other_ [ i, j ].
11136  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11137  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
11138  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11139  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
11140  *
11141  *  \param [in] other - an array to subtract from \a this one.
11142  *  \throw If \a other is NULL.
11143  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11144  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11145  *         \a other has number of both tuples and components not equal to 1.
11146  */
11147 void DataArrayInt::substractEqual(const DataArrayInt *other)
11148 {
11149   if(!other)
11150     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
11151   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
11152   checkAllocated(); other->checkAllocated();
11153   int nbOfTuple=getNumberOfTuples();
11154   int nbOfTuple2=other->getNumberOfTuples();
11155   int nbOfComp=getNumberOfComponents();
11156   int nbOfComp2=other->getNumberOfComponents();
11157   if(nbOfTuple==nbOfTuple2)
11158     {
11159       if(nbOfComp==nbOfComp2)
11160         {
11161           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
11162         }
11163       else if(nbOfComp2==1)
11164         {
11165           int *ptr=getPointer();
11166           const int *ptrc=other->getConstPointer();
11167           for(int i=0;i<nbOfTuple;i++)
11168             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11169         }
11170       else
11171         throw INTERP_KERNEL::Exception(msg);
11172     }
11173   else if(nbOfTuple2==1)
11174     {
11175       int *ptr=getPointer();
11176       const int *ptrc=other->getConstPointer();
11177       for(int i=0;i<nbOfTuple;i++)
11178         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11179     }
11180   else
11181     throw INTERP_KERNEL::Exception(msg);
11182   declareAsNew();
11183 }
11184
11185 /*!
11186  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11187  * valid cases.
11188  * 1.  The arrays have same number of tuples and components. Then each value of
11189  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11190  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11191  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11192  *   component. Then
11193  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11194  * 3.  The arrays have same number of components and one array, say _a2_, has one
11195  *   tuple. Then
11196  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11197  *
11198  * Info on components is copied either from the first array (in the first case) or from
11199  * the array with maximal number of elements (getNbOfElems()).
11200  *  \param [in] a1 - a factor array.
11201  *  \param [in] a2 - another factor array.
11202  *  \return DataArrayInt * - the new instance of DataArrayInt.
11203  *          The caller is to delete this result array using decrRef() as it is no more
11204  *          needed.
11205  *  \throw If either \a a1 or \a a2 is NULL.
11206  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11207  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11208  *         none of them has number of tuples or components equal to 1.
11209  */
11210 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11211 {
11212   if(!a1 || !a2)
11213     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11214   int nbOfTuple=a1->getNumberOfTuples();
11215   int nbOfTuple2=a2->getNumberOfTuples();
11216   int nbOfComp=a1->getNumberOfComponents();
11217   int nbOfComp2=a2->getNumberOfComponents();
11218   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
11219   if(nbOfTuple==nbOfTuple2)
11220     {
11221       if(nbOfComp==nbOfComp2)
11222         {
11223           ret=DataArrayInt::New();
11224           ret->alloc(nbOfTuple,nbOfComp);
11225           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11226           ret->copyStringInfoFrom(*a1);
11227         }
11228       else
11229         {
11230           int nbOfCompMin,nbOfCompMax;
11231           const DataArrayInt *aMin, *aMax;
11232           if(nbOfComp>nbOfComp2)
11233             {
11234               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11235               aMin=a2; aMax=a1;
11236             }
11237           else
11238             {
11239               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11240               aMin=a1; aMax=a2;
11241             }
11242           if(nbOfCompMin==1)
11243             {
11244               ret=DataArrayInt::New();
11245               ret->alloc(nbOfTuple,nbOfCompMax);
11246               const int *aMinPtr=aMin->getConstPointer();
11247               const int *aMaxPtr=aMax->getConstPointer();
11248               int *res=ret->getPointer();
11249               for(int i=0;i<nbOfTuple;i++)
11250                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11251               ret->copyStringInfoFrom(*aMax);
11252             }
11253           else
11254             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11255         }
11256     }
11257   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11258     {
11259       if(nbOfComp==nbOfComp2)
11260         {
11261           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11262           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11263           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11264           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11265           ret=DataArrayInt::New();
11266           ret->alloc(nbOfTupleMax,nbOfComp);
11267           int *res=ret->getPointer();
11268           for(int i=0;i<nbOfTupleMax;i++)
11269             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11270           ret->copyStringInfoFrom(*aMax);
11271         }
11272       else
11273         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11274     }
11275   else
11276     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11277   return ret.retn();
11278 }
11279
11280
11281 /*!
11282  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11283  * valid cases.
11284  * 1.  The arrays have same number of tuples and components. Then each value of
11285  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11286  *   _a_ [ i, j ] *= _other_ [ i, j ].
11287  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11288  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11289  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11290  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11291  *
11292  *  \param [in] other - an array to multiply to \a this one.
11293  *  \throw If \a other is NULL.
11294  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11295  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11296  *         \a other has number of both tuples and components not equal to 1.
11297  */
11298 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11299 {
11300   if(!other)
11301     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11302   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11303   checkAllocated(); other->checkAllocated();
11304   int nbOfTuple=getNumberOfTuples();
11305   int nbOfTuple2=other->getNumberOfTuples();
11306   int nbOfComp=getNumberOfComponents();
11307   int nbOfComp2=other->getNumberOfComponents();
11308   if(nbOfTuple==nbOfTuple2)
11309     {
11310       if(nbOfComp==nbOfComp2)
11311         {
11312           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11313         }
11314       else if(nbOfComp2==1)
11315         {
11316           int *ptr=getPointer();
11317           const int *ptrc=other->getConstPointer();
11318           for(int i=0;i<nbOfTuple;i++)
11319             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11320         }
11321       else
11322         throw INTERP_KERNEL::Exception(msg);
11323     }
11324   else if(nbOfTuple2==1)
11325     {
11326       if(nbOfComp2==nbOfComp)
11327         {
11328           int *ptr=getPointer();
11329           const int *ptrc=other->getConstPointer();
11330           for(int i=0;i<nbOfTuple;i++)
11331             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11332         }
11333       else
11334         throw INTERP_KERNEL::Exception(msg);
11335     }
11336   else
11337     throw INTERP_KERNEL::Exception(msg);
11338   declareAsNew();
11339 }
11340
11341
11342 /*!
11343  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11344  * valid cases.
11345  * 1.  The arrays have same number of tuples and components. Then each value of
11346  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11347  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11348  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11349  *   component. Then
11350  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11351  * 3.  The arrays have same number of components and one array, say _a2_, has one
11352  *   tuple. Then
11353  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11354  *
11355  * Info on components is copied either from the first array (in the first case) or from
11356  * the array with maximal number of elements (getNbOfElems()).
11357  *  \warning No check of division by zero is performed!
11358  *  \param [in] a1 - a numerator array.
11359  *  \param [in] a2 - a denominator array.
11360  *  \return DataArrayInt * - the new instance of DataArrayInt.
11361  *          The caller is to delete this result array using decrRef() as it is no more
11362  *          needed.
11363  *  \throw If either \a a1 or \a a2 is NULL.
11364  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11365  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11366  *         none of them has number of tuples or components equal to 1.
11367  */
11368 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11369 {
11370   if(!a1 || !a2)
11371     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11372   int nbOfTuple1=a1->getNumberOfTuples();
11373   int nbOfTuple2=a2->getNumberOfTuples();
11374   int nbOfComp1=a1->getNumberOfComponents();
11375   int nbOfComp2=a2->getNumberOfComponents();
11376   if(nbOfTuple2==nbOfTuple1)
11377     {
11378       if(nbOfComp1==nbOfComp2)
11379         {
11380           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11381           ret->alloc(nbOfTuple2,nbOfComp1);
11382           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11383           ret->copyStringInfoFrom(*a1);
11384           return ret.retn();
11385         }
11386       else if(nbOfComp2==1)
11387         {
11388           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11389           ret->alloc(nbOfTuple1,nbOfComp1);
11390           const int *a2Ptr=a2->getConstPointer();
11391           const int *a1Ptr=a1->getConstPointer();
11392           int *res=ret->getPointer();
11393           for(int i=0;i<nbOfTuple1;i++)
11394             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11395           ret->copyStringInfoFrom(*a1);
11396           return ret.retn();
11397         }
11398       else
11399         {
11400           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11401           return 0;
11402         }
11403     }
11404   else if(nbOfTuple2==1)
11405     {
11406       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11407       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11408       ret->alloc(nbOfTuple1,nbOfComp1);
11409       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11410       int *pt=ret->getPointer();
11411       for(int i=0;i<nbOfTuple1;i++)
11412         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11413       ret->copyStringInfoFrom(*a1);
11414       return ret.retn();
11415     }
11416   else
11417     {
11418       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11419       return 0;
11420     }
11421 }
11422
11423 /*!
11424  * Divide values of \a this array by values of another DataArrayInt. There are 3
11425  * valid cases.
11426  * 1.  The arrays have same number of tuples and components. Then each value of
11427  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11428  *   _a_ [ i, j ] /= _other_ [ i, j ].
11429  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11430  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11431  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11432  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11433  *
11434  *  \warning No check of division by zero is performed!
11435  *  \param [in] other - an array to divide \a this one by.
11436  *  \throw If \a other is NULL.
11437  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11438  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11439  *         \a other has number of both tuples and components not equal to 1.
11440  */
11441 void DataArrayInt::divideEqual(const DataArrayInt *other)
11442 {
11443   if(!other)
11444     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11445   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11446   checkAllocated(); other->checkAllocated();
11447   int nbOfTuple=getNumberOfTuples();
11448   int nbOfTuple2=other->getNumberOfTuples();
11449   int nbOfComp=getNumberOfComponents();
11450   int nbOfComp2=other->getNumberOfComponents();
11451   if(nbOfTuple==nbOfTuple2)
11452     {
11453       if(nbOfComp==nbOfComp2)
11454         {
11455           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11456         }
11457       else if(nbOfComp2==1)
11458         {
11459           int *ptr=getPointer();
11460           const int *ptrc=other->getConstPointer();
11461           for(int i=0;i<nbOfTuple;i++)
11462             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11463         }
11464       else
11465         throw INTERP_KERNEL::Exception(msg);
11466     }
11467   else if(nbOfTuple2==1)
11468     {
11469       if(nbOfComp2==nbOfComp)
11470         {
11471           int *ptr=getPointer();
11472           const int *ptrc=other->getConstPointer();
11473           for(int i=0;i<nbOfTuple;i++)
11474             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11475         }
11476       else
11477         throw INTERP_KERNEL::Exception(msg);
11478     }
11479   else
11480     throw INTERP_KERNEL::Exception(msg);
11481   declareAsNew();
11482 }
11483
11484
11485 /*!
11486  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11487  * valid cases.
11488  * 1.  The arrays have same number of tuples and components. Then each value of
11489  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11490  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11491  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11492  *   component. Then
11493  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11494  * 3.  The arrays have same number of components and one array, say _a2_, has one
11495  *   tuple. Then
11496  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11497  *
11498  * Info on components is copied either from the first array (in the first case) or from
11499  * the array with maximal number of elements (getNbOfElems()).
11500  *  \warning No check of division by zero is performed!
11501  *  \param [in] a1 - a dividend array.
11502  *  \param [in] a2 - a divisor array.
11503  *  \return DataArrayInt * - the new instance of DataArrayInt.
11504  *          The caller is to delete this result array using decrRef() as it is no more
11505  *          needed.
11506  *  \throw If either \a a1 or \a a2 is NULL.
11507  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11508  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11509  *         none of them has number of tuples or components equal to 1.
11510  */
11511 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11512 {
11513   if(!a1 || !a2)
11514     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11515   int nbOfTuple1=a1->getNumberOfTuples();
11516   int nbOfTuple2=a2->getNumberOfTuples();
11517   int nbOfComp1=a1->getNumberOfComponents();
11518   int nbOfComp2=a2->getNumberOfComponents();
11519   if(nbOfTuple2==nbOfTuple1)
11520     {
11521       if(nbOfComp1==nbOfComp2)
11522         {
11523           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11524           ret->alloc(nbOfTuple2,nbOfComp1);
11525           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11526           ret->copyStringInfoFrom(*a1);
11527           return ret.retn();
11528         }
11529       else if(nbOfComp2==1)
11530         {
11531           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11532           ret->alloc(nbOfTuple1,nbOfComp1);
11533           const int *a2Ptr=a2->getConstPointer();
11534           const int *a1Ptr=a1->getConstPointer();
11535           int *res=ret->getPointer();
11536           for(int i=0;i<nbOfTuple1;i++)
11537             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11538           ret->copyStringInfoFrom(*a1);
11539           return ret.retn();
11540         }
11541       else
11542         {
11543           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11544           return 0;
11545         }
11546     }
11547   else if(nbOfTuple2==1)
11548     {
11549       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11550       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11551       ret->alloc(nbOfTuple1,nbOfComp1);
11552       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11553       int *pt=ret->getPointer();
11554       for(int i=0;i<nbOfTuple1;i++)
11555         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11556       ret->copyStringInfoFrom(*a1);
11557       return ret.retn();
11558     }
11559   else
11560     {
11561       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11562       return 0;
11563     }
11564 }
11565
11566 /*!
11567  * Modify \a this array so that each value becomes a modulus of division of this value by
11568  * a value of another DataArrayInt. There are 3 valid cases.
11569  * 1.  The arrays have same number of tuples and components. Then each value of
11570  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11571  *   _a_ [ i, j ] %= _other_ [ i, j ].
11572  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11573  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11574  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11575  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11576  *
11577  *  \warning No check of division by zero is performed!
11578  *  \param [in] other - a divisor array.
11579  *  \throw If \a other is NULL.
11580  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11581  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11582  *         \a other has number of both tuples and components not equal to 1.
11583  */
11584 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11585 {
11586   if(!other)
11587     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11588   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11589   checkAllocated(); other->checkAllocated();
11590   int nbOfTuple=getNumberOfTuples();
11591   int nbOfTuple2=other->getNumberOfTuples();
11592   int nbOfComp=getNumberOfComponents();
11593   int nbOfComp2=other->getNumberOfComponents();
11594   if(nbOfTuple==nbOfTuple2)
11595     {
11596       if(nbOfComp==nbOfComp2)
11597         {
11598           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11599         }
11600       else if(nbOfComp2==1)
11601         {
11602           if(nbOfComp2==nbOfComp)
11603             {
11604               int *ptr=getPointer();
11605               const int *ptrc=other->getConstPointer();
11606               for(int i=0;i<nbOfTuple;i++)
11607                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11608             }
11609           else
11610             throw INTERP_KERNEL::Exception(msg);
11611         }
11612       else
11613         throw INTERP_KERNEL::Exception(msg);
11614     }
11615   else if(nbOfTuple2==1)
11616     {
11617       int *ptr=getPointer();
11618       const int *ptrc=other->getConstPointer();
11619       for(int i=0;i<nbOfTuple;i++)
11620         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11621     }
11622   else
11623     throw INTERP_KERNEL::Exception(msg);
11624   declareAsNew();
11625 }
11626
11627 /*!
11628  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11629  * valid cases.
11630  *
11631  *  \param [in] a1 - an array to pow up.
11632  *  \param [in] a2 - another array to sum up.
11633  *  \return DataArrayInt * - the new instance of DataArrayInt.
11634  *          The caller is to delete this result array using decrRef() as it is no more
11635  *          needed.
11636  *  \throw If either \a a1 or \a a2 is NULL.
11637  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11638  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11639  *  \throw If there is a negative value in \a a2.
11640  */
11641 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11642 {
11643   if(!a1 || !a2)
11644     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11645   int nbOfTuple=a1->getNumberOfTuples();
11646   int nbOfTuple2=a2->getNumberOfTuples();
11647   int nbOfComp=a1->getNumberOfComponents();
11648   int nbOfComp2=a2->getNumberOfComponents();
11649   if(nbOfTuple!=nbOfTuple2)
11650     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11651   if(nbOfComp!=1 || nbOfComp2!=1)
11652     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11653   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11654   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11655   int *ptr=ret->getPointer();
11656   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11657     {
11658       if(*ptr2>=0)
11659         {
11660           int tmp=1;
11661           for(int j=0;j<*ptr2;j++)
11662             tmp*=*ptr1;
11663           *ptr=tmp;
11664         }
11665       else
11666         {
11667           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11668           throw INTERP_KERNEL::Exception(oss.str().c_str());
11669         }
11670     }
11671   return ret.retn();
11672 }
11673
11674 /*!
11675  * Apply pow on values of another DataArrayInt to values of \a this one.
11676  *
11677  *  \param [in] other - an array to pow to \a this one.
11678  *  \throw If \a other is NULL.
11679  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11680  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11681  *  \throw If there is a negative value in \a other.
11682  */
11683 void DataArrayInt::powEqual(const DataArrayInt *other)
11684 {
11685   if(!other)
11686     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11687   int nbOfTuple=getNumberOfTuples();
11688   int nbOfTuple2=other->getNumberOfTuples();
11689   int nbOfComp=getNumberOfComponents();
11690   int nbOfComp2=other->getNumberOfComponents();
11691   if(nbOfTuple!=nbOfTuple2)
11692     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11693   if(nbOfComp!=1 || nbOfComp2!=1)
11694     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11695   int *ptr=getPointer();
11696   const int *ptrc=other->begin();
11697   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11698     {
11699       if(*ptrc>=0)
11700         {
11701           int tmp=1;
11702           for(int j=0;j<*ptrc;j++)
11703             tmp*=*ptr;
11704           *ptr=tmp;
11705         }
11706       else
11707         {
11708           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11709           throw INTERP_KERNEL::Exception(oss.str().c_str());
11710         }
11711     }
11712   declareAsNew();
11713 }
11714
11715 /*!
11716  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11717  * This map, if applied to \a start array, would make it sorted. For example, if
11718  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11719  * [5,6,0,3,2,7,1,4].
11720  *  \param [in] start - pointer to the first element of the array for which the
11721  *         permutation map is computed.
11722  *  \param [in] end - pointer specifying the end of the array \a start, so that
11723  *         the last value of \a start is \a end[ -1 ].
11724  *  \return int * - the result permutation array that the caller is to delete as it is no
11725  *         more needed.
11726  *  \throw If there are equal values in the input array.
11727  */
11728 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11729 {
11730   std::size_t sz=std::distance(start,end);
11731   int *ret=(int *)malloc(sz*sizeof(int));
11732   int *work=new int[sz];
11733   std::copy(start,end,work);
11734   std::sort(work,work+sz);
11735   if(std::unique(work,work+sz)!=work+sz)
11736     {
11737       delete [] work;
11738       free(ret);
11739       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11740     }
11741   std::map<int,int> m;
11742   for(int *workPt=work;workPt!=work+sz;workPt++)
11743     m[*workPt]=(int)std::distance(work,workPt);
11744   int *iter2=ret;
11745   for(const int *iter=start;iter!=end;iter++,iter2++)
11746     *iter2=m[*iter];
11747   delete [] work;
11748   return ret;
11749 }
11750
11751 /*!
11752  * Returns a new DataArrayInt containing an arithmetic progression
11753  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11754  * function.
11755  *  \param [in] begin - the start value of the result sequence.
11756  *  \param [in] end - limiting value, so that every value of the result array is less than
11757  *              \a end.
11758  *  \param [in] step - specifies the increment or decrement.
11759  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11760  *          array using decrRef() as it is no more needed.
11761  *  \throw If \a step == 0.
11762  *  \throw If \a end < \a begin && \a step > 0.
11763  *  \throw If \a end > \a begin && \a step < 0.
11764  */
11765 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11766 {
11767   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11768   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11769   ret->alloc(nbOfTuples,1);
11770   int *ptr=ret->getPointer();
11771   if(step>0)
11772     {
11773       for(int i=begin;i<end;i+=step,ptr++)
11774         *ptr=i;
11775     }
11776   else
11777     {
11778       for(int i=begin;i>end;i+=step,ptr++)
11779         *ptr=i;
11780     }
11781   return ret.retn();
11782 }
11783
11784 /*!
11785  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11786  * Server side.
11787  */
11788 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11789 {
11790   tinyInfo.resize(2);
11791   if(isAllocated())
11792     {
11793       tinyInfo[0]=getNumberOfTuples();
11794       tinyInfo[1]=getNumberOfComponents();
11795     }
11796   else
11797     {
11798       tinyInfo[0]=-1;
11799       tinyInfo[1]=-1;
11800     }
11801 }
11802
11803 /*!
11804  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11805  * Server side.
11806  */
11807 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11808 {
11809   if(isAllocated())
11810     {
11811       int nbOfCompo=getNumberOfComponents();
11812       tinyInfo.resize(nbOfCompo+1);
11813       tinyInfo[0]=getName();
11814       for(int i=0;i<nbOfCompo;i++)
11815         tinyInfo[i+1]=getInfoOnComponent(i);
11816     }
11817   else
11818     {
11819       tinyInfo.resize(1);
11820       tinyInfo[0]=getName();
11821     }
11822 }
11823
11824 /*!
11825  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11826  * This method returns if a feeding is needed.
11827  */
11828 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11829 {
11830   int nbOfTuple=tinyInfoI[0];
11831   int nbOfComp=tinyInfoI[1];
11832   if(nbOfTuple!=-1 || nbOfComp!=-1)
11833     {
11834       alloc(nbOfTuple,nbOfComp);
11835       return true;
11836     }
11837   return false;
11838 }
11839
11840 /*!
11841  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11842  * This method returns if a feeding is needed.
11843  */
11844 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11845 {
11846   setName(tinyInfoS[0]);
11847   if(isAllocated())
11848     {
11849       int nbOfCompo=tinyInfoI[1];
11850       for(int i=0;i<nbOfCompo;i++)
11851         setInfoOnComponent(i,tinyInfoS[i+1]);
11852     }
11853 }
11854
11855 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11856 {
11857   if(_da)
11858     {
11859       _da->incrRef();
11860       if(_da->isAllocated())
11861         {
11862           _nb_comp=da->getNumberOfComponents();
11863           _nb_tuple=da->getNumberOfTuples();
11864           _pt=da->getPointer();
11865         }
11866     }
11867 }
11868
11869 DataArrayIntIterator::~DataArrayIntIterator()
11870 {
11871   if(_da)
11872     _da->decrRef();
11873 }
11874
11875 DataArrayIntTuple *DataArrayIntIterator::nextt()
11876 {
11877   if(_tuple_id<_nb_tuple)
11878     {
11879       _tuple_id++;
11880       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11881       _pt+=_nb_comp;
11882       return ret;
11883     }
11884   else
11885     return 0;
11886 }
11887
11888 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11889 {
11890 }
11891
11892 std::string DataArrayIntTuple::repr() const
11893 {
11894   std::ostringstream oss; oss << "(";
11895   for(int i=0;i<_nb_of_compo-1;i++)
11896     oss << _pt[i] << ", ";
11897   oss << _pt[_nb_of_compo-1] << ")";
11898   return oss.str();
11899 }
11900
11901 int DataArrayIntTuple::intValue() const
11902 {
11903   if(_nb_of_compo==1)
11904     return *_pt;
11905   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11906 }
11907
11908 /*!
11909  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11910  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11911  * 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
11912  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11913  */
11914 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11915 {
11916   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11917     {
11918       DataArrayInt *ret=DataArrayInt::New();
11919       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11920       return ret;
11921     }
11922   else
11923     {
11924       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11925       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11926       throw INTERP_KERNEL::Exception(oss.str().c_str());
11927     }
11928 }