]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDCoupling/MEDCouplingMemArray.cxx
Salome HOME
Components are now available in VTK output of double arrays.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::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 /*!
438  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
439  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
440  * the number of component in the result array is same as that of each of given arrays.
441  * Info on components is copied from the first of the given arrays. Number of components
442  * in the given arrays must be  the same.
443  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
444  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
445  *          The caller is to delete this result array using decrRef() as it is no more
446  *          needed.
447  *  \throw If all arrays within \a arrs are NULL.
448  *  \throw If all not null arrays in \a arrs have not the same type.
449  *  \throw If getNumberOfComponents() of arrays within \a arrs.
450  */
451 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
452 {
453   std::vector<const DataArray *> arr2;
454   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
455     if(*it)
456       arr2.push_back(*it);
457   if(arr2.empty())
458     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
459   std::vector<const DataArrayDouble *> arrd;
460   std::vector<const DataArrayInt *> arri;
461   std::vector<const DataArrayChar *> arrc;
462   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
463     {
464       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
465       if(a)
466         { arrd.push_back(a); continue; }
467       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
468       if(b)
469         { arri.push_back(b); continue; }
470       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
471       if(c)
472         { arrc.push_back(c); continue; }
473       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
474     }
475   if(arr2.size()==arrd.size())
476     return DataArrayDouble::Aggregate(arrd);
477   if(arr2.size()==arri.size())
478     return DataArrayInt::Aggregate(arri);
479   if(arr2.size()==arrc.size())
480     return DataArrayChar::Aggregate(arrc);
481   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
482 }
483
484 /*!
485  * Sets information on a component specified by an index.
486  * To know more on format of this information
487  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
488  *  \warning Don't pass NULL as \a info!
489  *  \param [in] i - the index (zero based) of the component of interest.
490  *  \param [in] info - the string containing the information.
491  *  \throw If \a i is not a valid component index.
492  */
493 void DataArray::setInfoOnComponent(int i, const std::string& info)
494 {
495   if(i<(int)_info_on_compo.size() && i>=0)
496     _info_on_compo[i]=info;
497   else
498     {
499       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
500       throw INTERP_KERNEL::Exception(oss.str().c_str());
501     }
502 }
503
504 /*!
505  * Sets information on all components. This method can change number of components
506  * at certain conditions; if the conditions are not respected, an exception is thrown.
507  * The number of components can be changed in \a this only if \a this is not allocated.
508  * The condition of number of components must not be changed.
509  *
510  * To know more on format of the component information see
511  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
512  *  \param [in] info - a vector of component infos.
513  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
514  */
515 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
516 {
517   if(getNumberOfComponents()!=(int)info.size())
518     {
519       if(!isAllocated())
520         _info_on_compo=info;
521       else
522         {
523           std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
524           throw INTERP_KERNEL::Exception(oss.str().c_str());
525         }
526     }
527   else
528     _info_on_compo=info;
529 }
530
531 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
532 {
533   if(getNumberOfTuples()!=nbOfTuples)
534     {
535       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538 }
539
540 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
541 {
542   if(getNumberOfComponents()!=nbOfCompo)
543     {
544       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547 }
548
549 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
550 {
551   if(getNbOfElems()!=nbOfElems)
552     {
553       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
554       throw INTERP_KERNEL::Exception(oss.str().c_str());
555     }
556 }
557
558 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
559 {
560   if(getNumberOfTuples()!=other.getNumberOfTuples())
561     {
562       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
563       throw INTERP_KERNEL::Exception(oss.str().c_str());
564     }
565   if(getNumberOfComponents()!=other.getNumberOfComponents())
566     {
567       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570 }
571
572 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
573 {
574   checkNbOfTuples(nbOfTuples,msg);
575   checkNbOfComps(nbOfCompo,msg);
576 }
577
578 /*!
579  * Simply this method checks that \b value is in [0,\b ref).
580  */
581 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
582 {
583   if(value<0 || value>=ref)
584     {
585       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588 }
589
590 /*!
591  * This method checks that [\b start, \b end) is compliant with ref length \b value.
592  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
593  */
594 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
595 {
596   if(start<0 || start>=value)
597     {
598       if(value!=start || end!=start)
599         {
600           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
601           throw INTERP_KERNEL::Exception(oss.str().c_str());
602         }
603     }
604   if(end<0 || end>value)
605     {
606       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
607       throw INTERP_KERNEL::Exception(oss.str().c_str());
608     }
609 }
610
611 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
612 {
613   if(value<0 || value>ref)
614     {
615       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
616       throw INTERP_KERNEL::Exception(oss.str().c_str());
617     }
618 }
619
620 /*!
621  * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, 
622  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
623  *
624  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
625  *
626  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
627  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
628  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
629  * \param [in] sliceId - the slice id considered
630  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
631  * \param [out] startSlice - the start of the slice considered
632  * \param [out] stopSlice - the stop of the slice consided
633  * 
634  * \throw If \a step == 0
635  * \throw If \a nbOfSlices not > 0
636  * \throw If \a sliceId not in [0,nbOfSlices)
637  */
638 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
639 {
640   if(nbOfSlices<=0)
641     {
642       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
643       throw INTERP_KERNEL::Exception(oss.str().c_str());
644     }
645   if(sliceId<0 || sliceId>=nbOfSlices)
646     {
647       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
648       throw INTERP_KERNEL::Exception(oss.str().c_str());
649     }
650   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
651   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
652   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
653   if(sliceId<nbOfSlices-1)
654     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
655   else
656     stopSlice=stop;
657 }
658
659 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
660 {
661   if(end<begin)
662     {
663       std::ostringstream oss; oss << msg << " : end before begin !";
664       throw INTERP_KERNEL::Exception(oss.str().c_str());
665     }
666   if(end==begin)
667     return 0;
668   if(step<=0)
669     {
670       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   return (end-1-begin)/step+1;
674 }
675
676 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
677 {
678   if(step==0)
679     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
680   if(end<begin && step>0)
681     {
682       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   if(begin<end && step<0)
686     {
687       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   if(begin!=end)
691     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
692   else
693     return 0;
694 }
695
696 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
697 {
698   if(step!=0)
699     {
700       if(step>0)
701         {
702           if(begin<=value && value<end)
703             {
704               if((value-begin)%step==0)
705                 return (value-begin)/step;
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712       else
713         {
714           if(begin>=value && value>end)
715             {
716               if((begin-value)%(-step)==0)
717                 return (begin-value)/(-step);
718               else
719                 return -1;
720             }
721           else
722             return -1;
723         }
724     }
725   else
726     return -1;
727 }
728
729 /*!
730  * Returns a new instance of DataArrayDouble. The caller is to delete this array
731  * using decrRef() as it is no more needed. 
732  */
733 DataArrayDouble *DataArrayDouble::New()
734 {
735   return new DataArrayDouble;
736 }
737
738 /*!
739  * Checks if raw data is allocated. Read more on the raw data
740  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
741  *  \return bool - \a true if the raw data is allocated, \a false else.
742  */
743 bool DataArrayDouble::isAllocated() const
744 {
745   return getConstPointer()!=0;
746 }
747
748 /*!
749  * Checks if raw data is allocated and throws an exception if it is not the case.
750  *  \throw If the raw data is not allocated.
751  */
752 void DataArrayDouble::checkAllocated() const
753 {
754   if(!isAllocated())
755     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
756 }
757
758 /*!
759  * This method desallocated \a this without modification of informations relative to the components.
760  * After call of this method, DataArrayDouble::isAllocated will return false.
761  * If \a this is already not allocated, \a this is let unchanged.
762  */
763 void DataArrayDouble::desallocate()
764 {
765   _mem.destroy();
766 }
767
768 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
769 {
770   std::size_t sz(_mem.getNbOfElemAllocated());
771   sz*=sizeof(double);
772   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
773 }
774
775 /*!
776  * Returns the only one value in \a this, if and only if number of elements
777  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
778  *  \return double - the sole value stored in \a this array.
779  *  \throw If at least one of conditions stated above is not fulfilled.
780  */
781 double DataArrayDouble::doubleValue() const
782 {
783   if(isAllocated())
784     {
785       if(getNbOfElems()==1)
786         {
787           return *getConstPointer();
788         }
789       else
790         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
791     }
792   else
793     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
794 }
795
796 /*!
797  * Checks the number of tuples.
798  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
799  *  \throw If \a this is not allocated.
800  */
801 bool DataArrayDouble::empty() const
802 {
803   checkAllocated();
804   return getNumberOfTuples()==0;
805 }
806
807 /*!
808  * Returns a full copy of \a this. For more info on copying data arrays see
809  * \ref MEDCouplingArrayBasicsCopyDeep.
810  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
811  *          delete this array using decrRef() as it is no more needed. 
812  */
813 DataArrayDouble *DataArrayDouble::deepCpy() const
814 {
815   return new DataArrayDouble(*this);
816 }
817
818 /*!
819  * Returns either a \a deep or \a shallow copy of this array. For more info see
820  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
821  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
822  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
823  *          == \a true) or \a this instance (if \a dCpy == \a false).
824  */
825 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
826 {
827   if(dCpy)
828     return deepCpy();
829   else
830     {
831       incrRef();
832       return const_cast<DataArrayDouble *>(this);
833     }
834 }
835
836 /*!
837  * Copies all the data from another DataArrayDouble. For more info see
838  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
839  *  \param [in] other - another instance of DataArrayDouble to copy data from.
840  *  \throw If the \a other is not allocated.
841  */
842 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
843 {
844   other.checkAllocated();
845   int nbOfTuples=other.getNumberOfTuples();
846   int nbOfComp=other.getNumberOfComponents();
847   allocIfNecessary(nbOfTuples,nbOfComp);
848   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
849   double *pt=getPointer();
850   const double *ptI=other.getConstPointer();
851   for(std::size_t i=0;i<nbOfElems;i++)
852     pt[i]=ptI[i];
853   copyStringInfoFrom(other);
854 }
855
856 /*!
857  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
858  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
859  * If \a this has not already been allocated, number of components is set to one.
860  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
861  * 
862  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
863  */
864 void DataArrayDouble::reserve(std::size_t nbOfElems)
865 {
866   int nbCompo=getNumberOfComponents();
867   if(nbCompo==1)
868     {
869       _mem.reserve(nbOfElems);
870     }
871   else if(nbCompo==0)
872     {
873       _mem.reserve(nbOfElems);
874       _info_on_compo.resize(1);
875     }
876   else
877     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
878 }
879
880 /*!
881  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
882  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
883  *
884  * \param [in] val the value to be added in \a this
885  * \throw If \a this has already been allocated with number of components different from one.
886  * \sa DataArrayDouble::pushBackValsSilent
887  */
888 void DataArrayDouble::pushBackSilent(double val)
889 {
890   int nbCompo=getNumberOfComponents();
891   if(nbCompo==1)
892     _mem.pushBack(val);
893   else if(nbCompo==0)
894     {
895       _info_on_compo.resize(1);
896       _mem.pushBack(val);
897     }
898   else
899     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
900 }
901
902 /*!
903  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
904  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
905  *
906  *  \param [in] valsBg - an array of values to push at the end of \this.
907  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
908  *              the last value of \a valsBg is \a valsEnd[ -1 ].
909  * \throw If \a this has already been allocated with number of components different from one.
910  * \sa DataArrayDouble::pushBackSilent
911  */
912 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
913 {
914   int nbCompo=getNumberOfComponents();
915   if(nbCompo==1)
916     _mem.insertAtTheEnd(valsBg,valsEnd);
917   else if(nbCompo==0)
918     {
919       _info_on_compo.resize(1);
920       _mem.insertAtTheEnd(valsBg,valsEnd);
921     }
922   else
923     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
924 }
925
926 /*!
927  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
928  * \throw If \a this is already empty.
929  * \throw If \a this has number of components different from one.
930  */
931 double DataArrayDouble::popBackSilent()
932 {
933   if(getNumberOfComponents()==1)
934     return _mem.popBack();
935   else
936     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
937 }
938
939 /*!
940  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
941  *
942  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
943  */
944 void DataArrayDouble::pack() const
945 {
946   _mem.pack();
947 }
948
949 /*!
950  * Allocates the raw data in memory. If exactly same memory as needed already
951  * allocated, it is not re-allocated.
952  *  \param [in] nbOfTuple - number of tuples of data to allocate.
953  *  \param [in] nbOfCompo - number of components of data to allocate.
954  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
955  */
956 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
957 {
958   if(isAllocated())
959     {
960       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
961         alloc(nbOfTuple,nbOfCompo);
962     }
963   else
964     alloc(nbOfTuple,nbOfCompo);
965 }
966
967 /*!
968  * Allocates the raw data in memory. If the memory was already allocated, then it is
969  * freed and re-allocated. See an example of this method use
970  * \ref MEDCouplingArraySteps1WC "here".
971  *  \param [in] nbOfTuple - number of tuples of data to allocate.
972  *  \param [in] nbOfCompo - number of components of data to allocate.
973  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
974  */
975 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
976 {
977   if(nbOfTuple<0 || nbOfCompo<0)
978     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
979   _info_on_compo.resize(nbOfCompo);
980   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign zero to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  * \throw If \a this is not allocated.
988  */
989 void DataArrayDouble::fillWithZero()
990 {
991   checkAllocated();
992   _mem.fillWithValue(0.);
993   declareAsNew();
994 }
995
996 /*!
997  * Assign \a val to all values in \a this array. To know more on filling arrays see
998  * \ref MEDCouplingArrayFill.
999  *  \param [in] val - the value to fill with.
1000  *  \throw If \a this is not allocated.
1001  */
1002 void DataArrayDouble::fillWithValue(double val)
1003 {
1004   checkAllocated();
1005   _mem.fillWithValue(val);
1006   declareAsNew();
1007 }
1008
1009 /*!
1010  * Set all values in \a this array so that the i-th element equals to \a init + i
1011  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1012  *  \param [in] init - value to assign to the first element of array.
1013  *  \throw If \a this->getNumberOfComponents() != 1
1014  *  \throw If \a this is not allocated.
1015  */
1016 void DataArrayDouble::iota(double init)
1017 {
1018   checkAllocated();
1019   if(getNumberOfComponents()!=1)
1020     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1021   double *ptr=getPointer();
1022   int ntuples=getNumberOfTuples();
1023   for(int i=0;i<ntuples;i++)
1024     ptr[i]=init+double(i);
1025   declareAsNew();
1026 }
1027
1028 /*!
1029  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1030  *  \param [in] val - value to check equality of array values to.
1031  *  \param [in] eps - precision to check the equality.
1032  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1033  *                 \a false else.
1034  *  \throw If \a this->getNumberOfComponents() != 1
1035  *  \throw If \a this is not allocated.
1036  */
1037 bool DataArrayDouble::isUniform(double val, double eps) const
1038 {
1039   checkAllocated();
1040   if(getNumberOfComponents()!=1)
1041     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1042   int nbOfTuples=getNumberOfTuples();
1043   const double *w=getConstPointer();
1044   const double *end2=w+nbOfTuples;
1045   const double vmin=val-eps;
1046   const double vmax=val+eps;
1047   for(;w!=end2;w++)
1048     if(*w<vmin || *w>vmax)
1049       return false;
1050   return true;
1051 }
1052
1053 /*!
1054  * Sorts values of the array.
1055  *  \param [in] asc - \a true means ascending order, \a false, descending.
1056  *  \throw If \a this is not allocated.
1057  *  \throw If \a this->getNumberOfComponents() != 1.
1058  */
1059 void DataArrayDouble::sort(bool asc)
1060 {
1061   checkAllocated();
1062   if(getNumberOfComponents()!=1)
1063     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1064   _mem.sort(asc);
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Reverse the array values.
1070  *  \throw If \a this->getNumberOfComponents() < 1.
1071  *  \throw If \a this is not allocated.
1072  */
1073 void DataArrayDouble::reverse()
1074 {
1075   checkAllocated();
1076   _mem.reverse(getNumberOfComponents());
1077   declareAsNew();
1078 }
1079
1080 /*!
1081  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1082  * with at least absolute difference value of |\a eps| at each step.
1083  * If not an exception is thrown.
1084  *  \param [in] increasing - if \a true, the array values should be increasing.
1085  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1086  *                    the values are considered different.
1087  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1088  *         increasing arg.
1089  *  \throw If \a this->getNumberOfComponents() != 1.
1090  *  \throw If \a this is not allocated.
1091  */
1092 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1093 {
1094   if(!isMonotonic(increasing,eps))
1095     {
1096       if (increasing)
1097         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1098       else
1099         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1100     }
1101 }
1102
1103 /*!
1104  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1105  * with at least absolute difference value of |\a eps| at each step.
1106  *  \param [in] increasing - if \a true, array values should be increasing.
1107  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1108  *                    the values are considered different.
1109  *  \return bool - \a true if values change in accordance with \a increasing arg.
1110  *  \throw If \a this->getNumberOfComponents() != 1.
1111  *  \throw If \a this is not allocated.
1112  */
1113 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1114 {
1115   checkAllocated();
1116   if(getNumberOfComponents()!=1)
1117     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1118   int nbOfElements=getNumberOfTuples();
1119   const double *ptr=getConstPointer();
1120   if(nbOfElements==0)
1121     return true;
1122   double ref=ptr[0];
1123   double absEps=fabs(eps);
1124   if(increasing)
1125     {
1126       for(int i=1;i<nbOfElements;i++)
1127         {
1128           if(ptr[i]<(ref+absEps))
1129             return false;
1130           ref=ptr[i];
1131         }
1132       return true;
1133     }
1134   else
1135     {
1136       for(int i=1;i<nbOfElements;i++)
1137         {
1138           if(ptr[i]>(ref-absEps))
1139             return false;
1140           ref=ptr[i];
1141         }
1142       return true;
1143     }
1144 }
1145
1146 /*!
1147  * Returns a textual and human readable representation of \a this instance of
1148  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1149  *  \return std::string - text describing \a this DataArrayDouble.
1150  */
1151 std::string DataArrayDouble::repr() const
1152 {
1153   std::ostringstream ret;
1154   reprStream(ret);
1155   return ret.str();
1156 }
1157
1158 std::string DataArrayDouble::reprZip() const
1159 {
1160   std::ostringstream ret;
1161   reprZipStream(ret);
1162   return ret.str();
1163 }
1164
1165 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1166 {
1167   static const char SPACE[4]={' ',' ',' ',' '};
1168   checkAllocated();
1169   std::string idt(indent,' ');
1170   ofs.precision(17);
1171   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1172   //
1173   bool areAllEmpty(true);
1174   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
1175     if(!(*it).empty())
1176       areAllEmpty=false;
1177   if(!areAllEmpty)
1178     for(std::size_t i=0;i<_info_on_compo.size();i++)
1179       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
1180   //
1181   if(byteArr)
1182     {
1183       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1184       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1185       float *pt(tmp);
1186       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1187       for(const double *src=begin();src!=end();src++,pt++)
1188         *pt=float(*src);
1189       const char *data(reinterpret_cast<const char *>((float *)tmp));
1190       std::size_t sz(getNbOfElems()*sizeof(float));
1191       byteArr->insertAtTheEnd(data,data+sz);
1192       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1193     }
1194   else
1195     {
1196       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1197       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1198     }
1199   ofs << std::endl << idt << "</DataArray>\n";
1200 }
1201
1202 void DataArrayDouble::reprStream(std::ostream& stream) const
1203 {
1204   stream << "Name of double array : \"" << _name << "\"\n";
1205   reprWithoutNameStream(stream);
1206 }
1207
1208 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1209 {
1210   stream << "Name of double array : \"" << _name << "\"\n";
1211   reprZipWithoutNameStream(stream);
1212 }
1213
1214 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1215 {
1216   DataArray::reprWithoutNameStream(stream);
1217   stream.precision(17);
1218   _mem.repr(getNumberOfComponents(),stream);
1219 }
1220
1221 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1222 {
1223   DataArray::reprWithoutNameStream(stream);
1224   stream.precision(17);
1225   _mem.reprZip(getNumberOfComponents(),stream);
1226 }
1227
1228 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1229 {
1230   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1231   const double *data=getConstPointer();
1232   stream.precision(17);
1233   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1234   if(nbTuples*nbComp>=1)
1235     {
1236       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1237       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1238       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1239       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1240     }
1241   else
1242     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1243   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1244 }
1245
1246 /*!
1247  * Method that gives a quick overvien of \a this for python.
1248  */
1249 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1250 {
1251   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1252   stream << "DataArrayDouble C++ instance at " << this << ". ";
1253   if(isAllocated())
1254     {
1255       int nbOfCompo=(int)_info_on_compo.size();
1256       if(nbOfCompo>=1)
1257         {
1258           int nbOfTuples=getNumberOfTuples();
1259           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1260           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1261         }
1262       else
1263         stream << "Number of components : 0.";
1264     }
1265   else
1266     stream << "*** No data allocated ****";
1267 }
1268
1269 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1270 {
1271   const double *data=begin();
1272   int nbOfTuples=getNumberOfTuples();
1273   int nbOfCompo=(int)_info_on_compo.size();
1274   std::ostringstream oss2; oss2 << "[";
1275   oss2.precision(17);
1276   std::string oss2Str(oss2.str());
1277   bool isFinished=true;
1278   for(int i=0;i<nbOfTuples && isFinished;i++)
1279     {
1280       if(nbOfCompo>1)
1281         {
1282           oss2 << "(";
1283           for(int j=0;j<nbOfCompo;j++,data++)
1284             {
1285               oss2 << *data;
1286               if(j!=nbOfCompo-1) oss2 << ", ";
1287             }
1288           oss2 << ")";
1289         }
1290       else
1291         oss2 << *data++;
1292       if(i!=nbOfTuples-1) oss2 << ", ";
1293       std::string oss3Str(oss2.str());
1294       if(oss3Str.length()<maxNbOfByteInRepr)
1295         oss2Str=oss3Str;
1296       else
1297         isFinished=false;
1298     }
1299   stream << oss2Str;
1300   if(!isFinished)
1301     stream << "... ";
1302   stream << "]";
1303 }
1304
1305 /*!
1306  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1307  * mismatch is given.
1308  * 
1309  * \param [in] other the instance to be compared with \a this
1310  * \param [in] prec the precision to compare numeric data of the arrays.
1311  * \param [out] reason In case of inequality returns the reason.
1312  * \sa DataArrayDouble::isEqual
1313  */
1314 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1315 {
1316   if(!areInfoEqualsIfNotWhy(other,reason))
1317     return false;
1318   return _mem.isEqual(other._mem,prec,reason);
1319 }
1320
1321 /*!
1322  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1323  * \ref MEDCouplingArrayBasicsCompare.
1324  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1325  *  \param [in] prec - precision value to compare numeric data of the arrays.
1326  *  \return bool - \a true if the two arrays are equal, \a false else.
1327  */
1328 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1329 {
1330   std::string tmp;
1331   return isEqualIfNotWhy(other,prec,tmp);
1332 }
1333
1334 /*!
1335  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1336  * \ref MEDCouplingArrayBasicsCompare.
1337  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1338  *  \param [in] prec - precision value to compare numeric data of the arrays.
1339  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1340  */
1341 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1342 {
1343   std::string tmp;
1344   return _mem.isEqual(other._mem,prec,tmp);
1345 }
1346
1347 /*!
1348  * Changes number of tuples in the array. If the new number of tuples is smaller
1349  * than the current number the array is truncated, otherwise the array is extended.
1350  *  \param [in] nbOfTuples - new number of tuples. 
1351  *  \throw If \a this is not allocated.
1352  *  \throw If \a nbOfTuples is negative.
1353  */
1354 void DataArrayDouble::reAlloc(int nbOfTuples)
1355 {
1356   if(nbOfTuples<0)
1357     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1358   checkAllocated();
1359   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1360   declareAsNew();
1361 }
1362
1363 /*!
1364  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1365  * array to the new one.
1366  *  \return DataArrayInt * - the new instance of DataArrayInt.
1367  */
1368 DataArrayInt *DataArrayDouble::convertToIntArr() const
1369 {
1370   DataArrayInt *ret=DataArrayInt::New();
1371   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1372   int *dest=ret->getPointer();
1373   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1374   for(const double *src=begin();src!=end();src++,dest++)
1375     *dest=(int)*src;
1376   ret->copyStringInfoFrom(*this);
1377   return ret;
1378 }
1379
1380 /*!
1381  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1382  * arranged in memory. If \a this array holds 2 components of 3 values:
1383  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1384  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1385  *  \warning Do not confuse this method with transpose()!
1386  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1387  *          is to delete using decrRef() as it is no more needed.
1388  *  \throw If \a this is not allocated.
1389  */
1390 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1391 {
1392   if(_mem.isNull())
1393     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1394   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1395   DataArrayDouble *ret=DataArrayDouble::New();
1396   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1397   return ret;
1398 }
1399
1400 /*!
1401  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1402  * arranged in memory. If \a this array holds 2 components of 3 values:
1403  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1404  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1405  *  \warning Do not confuse this method with transpose()!
1406  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1407  *          is to delete using decrRef() as it is no more needed.
1408  *  \throw If \a this is not allocated.
1409  */
1410 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1411 {
1412   if(_mem.isNull())
1413     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1414   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1415   DataArrayDouble *ret=DataArrayDouble::New();
1416   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1417   return ret;
1418 }
1419
1420 /*!
1421  * Permutes values of \a this array as required by \a old2New array. The values are
1422  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1423  * the same as in \this one.
1424  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1425  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1426  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1427  *     giving a new position for i-th old value.
1428  */
1429 void DataArrayDouble::renumberInPlace(const int *old2New)
1430 {
1431   checkAllocated();
1432   int nbTuples=getNumberOfTuples();
1433   int nbOfCompo=getNumberOfComponents();
1434   double *tmp=new double[nbTuples*nbOfCompo];
1435   const double *iptr=getConstPointer();
1436   for(int i=0;i<nbTuples;i++)
1437     {
1438       int v=old2New[i];
1439       if(v>=0 && v<nbTuples)
1440         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1441       else
1442         {
1443           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1444           throw INTERP_KERNEL::Exception(oss.str().c_str());
1445         }
1446     }
1447   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1448   delete [] tmp;
1449   declareAsNew();
1450 }
1451
1452 /*!
1453  * Permutes values of \a this array as required by \a new2Old array. The values are
1454  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1455  * the same as in \this one.
1456  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1457  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1458  *     giving a previous position of i-th new value.
1459  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1460  *          is to delete using decrRef() as it is no more needed.
1461  */
1462 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1463 {
1464   checkAllocated();
1465   int nbTuples=getNumberOfTuples();
1466   int nbOfCompo=getNumberOfComponents();
1467   double *tmp=new double[nbTuples*nbOfCompo];
1468   const double *iptr=getConstPointer();
1469   for(int i=0;i<nbTuples;i++)
1470     {
1471       int v=new2Old[i];
1472       if(v>=0 && v<nbTuples)
1473         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1474       else
1475         {
1476           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1477           throw INTERP_KERNEL::Exception(oss.str().c_str());
1478         }
1479     }
1480   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1481   delete [] tmp;
1482   declareAsNew();
1483 }
1484
1485 /*!
1486  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1487  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1488  * Number of tuples in the result array remains the same as in \this one.
1489  * If a permutation reduction is needed, renumberAndReduce() should be used.
1490  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1491  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1492  *          giving a new position for i-th old value.
1493  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1494  *          is to delete using decrRef() as it is no more needed.
1495  *  \throw If \a this is not allocated.
1496  */
1497 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1498 {
1499   checkAllocated();
1500   int nbTuples=getNumberOfTuples();
1501   int nbOfCompo=getNumberOfComponents();
1502   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1503   ret->alloc(nbTuples,nbOfCompo);
1504   ret->copyStringInfoFrom(*this);
1505   const double *iptr=getConstPointer();
1506   double *optr=ret->getPointer();
1507   for(int i=0;i<nbTuples;i++)
1508     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1509   ret->copyStringInfoFrom(*this);
1510   return ret.retn();
1511 }
1512
1513 /*!
1514  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1515  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1516  * tuples in the result array remains the same as in \this one.
1517  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1518  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1519  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1520  *     giving a previous position of i-th new value.
1521  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1522  *          is to delete using decrRef() as it is no more needed.
1523  */
1524 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1525 {
1526   checkAllocated();
1527   int nbTuples=getNumberOfTuples();
1528   int nbOfCompo=getNumberOfComponents();
1529   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1530   ret->alloc(nbTuples,nbOfCompo);
1531   ret->copyStringInfoFrom(*this);
1532   const double *iptr=getConstPointer();
1533   double *optr=ret->getPointer();
1534   for(int i=0;i<nbTuples;i++)
1535     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1536   ret->copyStringInfoFrom(*this);
1537   return ret.retn();
1538 }
1539
1540 /*!
1541  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1542  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1543  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1544  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1545  * \a old2New[ i ] is negative, is missing from the result array.
1546  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1547  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1548  *     giving a new position for i-th old tuple and giving negative position for
1549  *     for i-th old tuple that should be omitted.
1550  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1551  *          is to delete using decrRef() as it is no more needed.
1552  */
1553 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1554 {
1555   checkAllocated();
1556   int nbTuples=getNumberOfTuples();
1557   int nbOfCompo=getNumberOfComponents();
1558   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1559   ret->alloc(newNbOfTuple,nbOfCompo);
1560   const double *iptr=getConstPointer();
1561   double *optr=ret->getPointer();
1562   for(int i=0;i<nbTuples;i++)
1563     {
1564       int w=old2New[i];
1565       if(w>=0)
1566         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1567     }
1568   ret->copyStringInfoFrom(*this);
1569   return ret.retn();
1570 }
1571
1572 /*!
1573  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1574  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1575  * \a new2OldBg array.
1576  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1577  * This method is equivalent to renumberAndReduce() except that convention in input is
1578  * \c new2old and \b not \c old2new.
1579  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1580  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1581  *              tuple index in \a this array to fill the i-th tuple in the new array.
1582  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1583  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1584  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1585  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1586  *          is to delete using decrRef() as it is no more needed.
1587  */
1588 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1589 {
1590   checkAllocated();
1591   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1592   int nbComp=getNumberOfComponents();
1593   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1594   ret->copyStringInfoFrom(*this);
1595   double *pt=ret->getPointer();
1596   const double *srcPt=getConstPointer();
1597   int i=0;
1598   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1599     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1600   ret->copyStringInfoFrom(*this);
1601   return ret.retn();
1602 }
1603
1604 /*!
1605  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1606  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1607  * \a new2OldBg array.
1608  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1609  * This method is equivalent to renumberAndReduce() except that convention in input is
1610  * \c new2old and \b not \c old2new.
1611  * This method is equivalent to selectByTupleId() except that it prevents coping data
1612  * from behind the end of \a this array.
1613  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1614  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1615  *              tuple index in \a this array to fill the i-th tuple in the new array.
1616  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1617  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1618  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1619  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1620  *          is to delete using decrRef() as it is no more needed.
1621  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1622  */
1623 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1624 {
1625   checkAllocated();
1626   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1627   int nbComp=getNumberOfComponents();
1628   int oldNbOfTuples=getNumberOfTuples();
1629   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1630   ret->copyStringInfoFrom(*this);
1631   double *pt=ret->getPointer();
1632   const double *srcPt=getConstPointer();
1633   int i=0;
1634   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1635     if(*w>=0 && *w<oldNbOfTuples)
1636       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1637     else
1638       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1639   ret->copyStringInfoFrom(*this);
1640   return ret.retn();
1641 }
1642
1643 /*!
1644  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1645  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1646  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1647  * command \c range( \a bg, \a end2, \a step ).
1648  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1649  * not constructed explicitly.
1650  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1651  *  \param [in] bg - index of the first tuple to copy from \a this array.
1652  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1653  *  \param [in] step - index increment to get index of the next tuple to copy.
1654  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1655  *          is to delete using decrRef() as it is no more needed.
1656  *  \sa DataArrayDouble::substr.
1657  */
1658 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1659 {
1660   checkAllocated();
1661   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1662   int nbComp=getNumberOfComponents();
1663   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1664   ret->alloc(newNbOfTuples,nbComp);
1665   double *pt=ret->getPointer();
1666   const double *srcPt=getConstPointer()+bg*nbComp;
1667   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1668     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1669   ret->copyStringInfoFrom(*this);
1670   return ret.retn();
1671 }
1672
1673 /*!
1674  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1675  * of tuples specified by \a ranges parameter.
1676  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1677  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1678  *              of tuples in [\c begin,\c end) format.
1679  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1680  *          is to delete using decrRef() as it is no more needed.
1681  *  \throw If \a end < \a begin.
1682  *  \throw If \a end > \a this->getNumberOfTuples().
1683  *  \throw If \a this is not allocated.
1684  */
1685 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1686 {
1687   checkAllocated();
1688   int nbOfComp=getNumberOfComponents();
1689   int nbOfTuplesThis=getNumberOfTuples();
1690   if(ranges.empty())
1691     {
1692       DataArrayDouble *ret=DataArrayDouble::New();
1693       ret->alloc(0,nbOfComp);
1694       ret->copyStringInfoFrom(*this);
1695       return ret;
1696     }
1697   int ref=ranges.front().first;
1698   int nbOfTuples=0;
1699   bool isIncreasing=true;
1700   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1701     {
1702       if((*it).first<=(*it).second)
1703         {
1704           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1705             {
1706               nbOfTuples+=(*it).second-(*it).first;
1707               if(isIncreasing)
1708                 isIncreasing=ref<=(*it).first;
1709               ref=(*it).second;
1710             }
1711           else
1712             {
1713               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1714               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1715               throw INTERP_KERNEL::Exception(oss.str().c_str());
1716             }
1717         }
1718       else
1719         {
1720           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1721           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1722           throw INTERP_KERNEL::Exception(oss.str().c_str());
1723         }
1724     }
1725   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1726     return deepCpy();
1727   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1728   ret->alloc(nbOfTuples,nbOfComp);
1729   ret->copyStringInfoFrom(*this);
1730   const double *src=getConstPointer();
1731   double *work=ret->getPointer();
1732   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1733     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1734   return ret.retn();
1735 }
1736
1737 /*!
1738  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1739  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1740  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1741  * This method is a specialization of selectByTupleId2().
1742  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1743  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1744  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1745  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1746  *          is to delete using decrRef() as it is no more needed.
1747  *  \throw If \a tupleIdBg < 0.
1748  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1749     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1750  *  \sa DataArrayDouble::selectByTupleId2
1751  */
1752 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1753 {
1754   checkAllocated();
1755   int nbt=getNumberOfTuples();
1756   if(tupleIdBg<0)
1757     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1758   if(tupleIdBg>nbt)
1759     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1760   int trueEnd=tupleIdEnd;
1761   if(tupleIdEnd!=-1)
1762     {
1763       if(tupleIdEnd>nbt)
1764         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1765     }
1766   else
1767     trueEnd=nbt;
1768   int nbComp=getNumberOfComponents();
1769   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1770   ret->alloc(trueEnd-tupleIdBg,nbComp);
1771   ret->copyStringInfoFrom(*this);
1772   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1773   return ret.retn();
1774 }
1775
1776 /*!
1777  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1778  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1779  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1780  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1781  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1782  * components.  
1783  *  \param [in] newNbOfComp - number of components for the new array to have.
1784  *  \param [in] dftValue - value assigned to new values added to the new array.
1785  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1786  *          is to delete using decrRef() as it is no more needed.
1787  *  \throw If \a this is not allocated.
1788  */
1789 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1790 {
1791   checkAllocated();
1792   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1793   ret->alloc(getNumberOfTuples(),newNbOfComp);
1794   const double *oldc=getConstPointer();
1795   double *nc=ret->getPointer();
1796   int nbOfTuples=getNumberOfTuples();
1797   int oldNbOfComp=getNumberOfComponents();
1798   int dim=std::min(oldNbOfComp,newNbOfComp);
1799   for(int i=0;i<nbOfTuples;i++)
1800     {
1801       int j=0;
1802       for(;j<dim;j++)
1803         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1804       for(;j<newNbOfComp;j++)
1805         nc[newNbOfComp*i+j]=dftValue;
1806     }
1807   ret->setName(getName());
1808   for(int i=0;i<dim;i++)
1809     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1810   ret->setName(getName());
1811   return ret.retn();
1812 }
1813
1814 /*!
1815  * Changes the number of components within \a this array so that its raw data **does
1816  * not** change, instead splitting this data into tuples changes.
1817  *  \warning This method erases all (name and unit) component info set before!
1818  *  \param [in] newNbOfComp - number of components for \a this array to have.
1819  *  \throw If \a this is not allocated
1820  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1821  *  \throw If \a newNbOfCompo is lower than 1.
1822  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1823  *  \warning This method erases all (name and unit) component info set before!
1824  */
1825 void DataArrayDouble::rearrange(int newNbOfCompo)
1826 {
1827   checkAllocated();
1828   if(newNbOfCompo<1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1830   std::size_t nbOfElems=getNbOfElems();
1831   if(nbOfElems%newNbOfCompo!=0)
1832     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1833   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1834     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1835   _info_on_compo.clear();
1836   _info_on_compo.resize(newNbOfCompo);
1837   declareAsNew();
1838 }
1839
1840 /*!
1841  * Changes the number of components within \a this array to be equal to its number
1842  * of tuples, and inversely its number of tuples to become equal to its number of 
1843  * components. So that its raw data **does not** change, instead splitting this
1844  * data into tuples changes.
1845  *  \warning This method erases all (name and unit) component info set before!
1846  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1847  *  \throw If \a this is not allocated.
1848  *  \sa rearrange()
1849  */
1850 void DataArrayDouble::transpose()
1851 {
1852   checkAllocated();
1853   int nbOfTuples=getNumberOfTuples();
1854   rearrange(nbOfTuples);
1855 }
1856
1857 /*!
1858  * Returns a copy of \a this array composed of selected components.
1859  * The new DataArrayDouble has the same number of tuples but includes components
1860  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1861  * can be either less, same or more than \a this->getNbOfElems().
1862  *  \param [in] compoIds - sequence of zero based indices of components to include
1863  *              into the new array.
1864  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1865  *          is to delete using decrRef() as it is no more needed.
1866  *  \throw If \a this is not allocated.
1867  *  \throw If a component index (\a i) is not valid: 
1868  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1869  *
1870  *  \if ENABLE_EXAMPLES
1871  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1872  *  \endif
1873  */
1874 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1875 {
1876   checkAllocated();
1877   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1878   std::size_t newNbOfCompo=compoIds.size();
1879   int oldNbOfCompo=getNumberOfComponents();
1880   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1881     if((*it)<0 || (*it)>=oldNbOfCompo)
1882       {
1883         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1884         throw INTERP_KERNEL::Exception(oss.str().c_str());
1885       }
1886   int nbOfTuples=getNumberOfTuples();
1887   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1888   ret->copyPartOfStringInfoFrom(*this,compoIds);
1889   const double *oldc=getConstPointer();
1890   double *nc=ret->getPointer();
1891   for(int i=0;i<nbOfTuples;i++)
1892     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1893       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1894   return ret.retn();
1895 }
1896
1897 /*!
1898  * Appends components of another array to components of \a this one, tuple by tuple.
1899  * So that the number of tuples of \a this array remains the same and the number of 
1900  * components increases.
1901  *  \param [in] other - the DataArrayDouble to append to \a this one.
1902  *  \throw If \a this is not allocated.
1903  *  \throw If \a this and \a other arrays have different number of tuples.
1904  *
1905  *  \if ENABLE_EXAMPLES
1906  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1907  *
1908  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1909  *  \endif
1910  */
1911 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1912 {
1913   checkAllocated();
1914   other->checkAllocated();
1915   int nbOfTuples=getNumberOfTuples();
1916   if(nbOfTuples!=other->getNumberOfTuples())
1917     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1918   int nbOfComp1=getNumberOfComponents();
1919   int nbOfComp2=other->getNumberOfComponents();
1920   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1921   double *w=newArr;
1922   const double *inp1=getConstPointer();
1923   const double *inp2=other->getConstPointer();
1924   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1925     {
1926       w=std::copy(inp1,inp1+nbOfComp1,w);
1927       w=std::copy(inp2,inp2+nbOfComp2,w);
1928     }
1929   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1930   std::vector<int> compIds(nbOfComp2);
1931   for(int i=0;i<nbOfComp2;i++)
1932     compIds[i]=nbOfComp1+i;
1933   copyPartOfStringInfoFrom2(compIds,*other);
1934 }
1935
1936 /*!
1937  * This method checks that all tuples in \a other are in \a this.
1938  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1939  * 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.
1940  *
1941  * \param [in] other - the array having the same number of components than \a this.
1942  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1943  * \sa DataArrayDouble::findCommonTuples
1944  */
1945 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1946 {
1947   if(!other)
1948     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1949   checkAllocated(); other->checkAllocated();
1950   if(getNumberOfComponents()!=other->getNumberOfComponents())
1951     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1952   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1953   DataArrayInt *c=0,*ci=0;
1954   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1955   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1956   int newNbOfTuples=-1;
1957   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1958   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1959   tupleIds=ret1.retn();
1960   return newNbOfTuples==getNumberOfTuples();
1961 }
1962
1963 /*!
1964  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1965  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1966  * distance separating two points is computed with the infinite norm.
1967  *
1968  * Indices of coincident tuples are stored in output arrays.
1969  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1970  *
1971  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1972  * MEDCouplingUMesh::mergeNodes().
1973  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1974  *              considered not coincident.
1975  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1976  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1977  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1978  *               \a comm->getNumberOfComponents() == 1. 
1979  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1980  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1981  *               groups of (indices of) coincident tuples. Its every value is a tuple
1982  *               index where a next group of tuples begins. For example the second
1983  *               group of tuples in \a comm is described by following range of indices:
1984  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1985  *               gives the number of groups of coincident tuples.
1986  *  \throw If \a this is not allocated.
1987  *  \throw If the number of components is not in [1,2,3,4].
1988  *
1989  *  \if ENABLE_EXAMPLES
1990  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1991  *
1992  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1993  *  \endif
1994  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1995  */
1996 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1997 {
1998   checkAllocated();
1999   int nbOfCompo=getNumberOfComponents();
2000   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
2001     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
2002
2003   int nbOfTuples=getNumberOfTuples();
2004   //
2005   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
2006   switch(nbOfCompo)
2007   {
2008     case 4:
2009       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2010       break;
2011     case 3:
2012       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2013       break;
2014     case 2:
2015       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2016       break;
2017     case 1:
2018       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2019       break;
2020     default:
2021       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2022   }
2023   comm=c.retn();
2024   commIndex=cI.retn();
2025 }
2026
2027 /*!
2028  * 
2029  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2030  *             \a nbTimes  should be at least equal to 1.
2031  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2032  * \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.
2033  */
2034 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2035 {
2036   checkAllocated();
2037   if(getNumberOfComponents()!=1)
2038     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2039   if(nbTimes<1)
2040     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2041   int nbTuples=getNumberOfTuples();
2042   const double *inPtr=getConstPointer();
2043   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2044   double *retPtr=ret->getPointer();
2045   for(int i=0;i<nbTuples;i++,inPtr++)
2046     {
2047       double val=*inPtr;
2048       for(int j=0;j<nbTimes;j++,retPtr++)
2049         *retPtr=val;
2050     }
2051   ret->copyStringInfoFrom(*this);
2052   return ret.retn();
2053 }
2054
2055 /*!
2056  * This methods returns the minimal distance between the two set of points \a this and \a other.
2057  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2058  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2059  *
2060  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2061  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2062  * \return the minimal distance between the two set of points \a this and \a other.
2063  * \sa DataArrayDouble::findClosestTupleId
2064  */
2065 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2066 {
2067   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2068   int nbOfCompo(getNumberOfComponents());
2069   int otherNbTuples(other->getNumberOfTuples());
2070   const double *thisPt(begin()),*otherPt(other->begin());
2071   const int *part1Pt(part1->begin());
2072   double ret=std::numeric_limits<double>::max();
2073   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2074     {
2075       double tmp(0.);
2076       for(int j=0;j<nbOfCompo;j++)
2077         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2078       if(tmp<ret)
2079         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2080     }
2081   return sqrt(ret);
2082 }
2083
2084 /*!
2085  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2086  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2087  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2088  *
2089  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2090  * \sa DataArrayDouble::minimalDistanceTo
2091  */
2092 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2093 {
2094   if(!other)
2095     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2096   checkAllocated(); other->checkAllocated();
2097   int nbOfCompo=getNumberOfComponents();
2098   if(nbOfCompo!=other->getNumberOfComponents())
2099     {
2100       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2101       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2102       throw INTERP_KERNEL::Exception(oss.str().c_str());
2103     }
2104   int nbOfTuples=other->getNumberOfTuples();
2105   int thisNbOfTuples=getNumberOfTuples();
2106   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2107   double bounds[6];
2108   getMinMaxPerComponent(bounds);
2109   switch(nbOfCompo)
2110   {
2111     case 3:
2112       {
2113         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2114         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2115         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2116         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2117         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2118         break;
2119       }
2120     case 2:
2121       {
2122         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2123         double delta=std::max(xDelta,yDelta);
2124         double characSize=sqrt(delta/(double)thisNbOfTuples);
2125         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2126         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2127         break;
2128       }
2129     case 1:
2130       {
2131         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2132         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2133         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2134         break;
2135       }
2136     default:
2137       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2138   }
2139   return ret.retn();
2140 }
2141
2142 /*!
2143  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2144  * 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
2145  * how many bounding boxes in \a otherBBoxFrmt.
2146  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2147  *
2148  * \param [in] otherBBoxFrmt - It is an array .
2149  * \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.
2150  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2151  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2152  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2153  */
2154 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2155 {
2156   if(!otherBBoxFrmt)
2157     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2158   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2159     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2160   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2161   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2162     {
2163       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2164       throw INTERP_KERNEL::Exception(oss.str().c_str());
2165     }
2166   if(nbOfComp%2!=0)
2167     {
2168       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2169       throw INTERP_KERNEL::Exception(oss.str().c_str());
2170     }
2171   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2172   const double *thisBBPtr(begin());
2173   int *retPtr(ret->getPointer());
2174   switch(nbOfComp/2)
2175   {
2176     case 3:
2177       {
2178         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2179         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2180           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2181         break;
2182       }
2183     case 2:
2184       {
2185         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2186         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2187           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2188         break;
2189       }
2190     case 1:
2191       {
2192         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2193         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2194           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2195         break;
2196       }
2197     default:
2198       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2199   }
2200
2201   return ret.retn();
2202 }
2203
2204 /*!
2205  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2206  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2207  * space. The distance between tuples is computed using norm2. If several tuples are
2208  * not far each from other than \a prec, only one of them remains in the result
2209  * array. The order of tuples in the result array is same as in \a this one except
2210  * that coincident tuples are excluded.
2211  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2212  *              considered not coincident.
2213  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2214  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2215  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2216  *          is to delete using decrRef() as it is no more needed.
2217  *  \throw If \a this is not allocated.
2218  *  \throw If the number of components is not in [1,2,3,4].
2219  *
2220  *  \if ENABLE_EXAMPLES
2221  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2222  *  \endif
2223  */
2224 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2225 {
2226   checkAllocated();
2227   DataArrayInt *c0=0,*cI0=0;
2228   findCommonTuples(prec,limitTupleId,c0,cI0);
2229   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2230   int newNbOfTuples=-1;
2231   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2232   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2233 }
2234
2235 /*!
2236  * Copy all components in a specified order from another DataArrayDouble.
2237  * Both numerical and textual data is copied. The number of tuples in \a this and
2238  * the other array can be different.
2239  *  \param [in] a - the array to copy data from.
2240  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2241  *              to be copied.
2242  *  \throw If \a a is NULL.
2243  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2244  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2245  *
2246  *  \if ENABLE_EXAMPLES
2247  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2248  *  \endif
2249  */
2250 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2251 {
2252   if(!a)
2253     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2254   checkAllocated();
2255   copyPartOfStringInfoFrom2(compoIds,*a);
2256   std::size_t partOfCompoSz=compoIds.size();
2257   int nbOfCompo=getNumberOfComponents();
2258   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2259   const double *ac=a->getConstPointer();
2260   double *nc=getPointer();
2261   for(int i=0;i<nbOfTuples;i++)
2262     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2263       nc[nbOfCompo*i+compoIds[j]]=*ac;
2264 }
2265
2266 /*!
2267  * Copy all values from another DataArrayDouble into specified tuples and components
2268  * of \a this array. Textual data is not copied.
2269  * The tree parameters defining set of indices of tuples and components are similar to
2270  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2271  *  \param [in] a - the array to copy values from.
2272  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2273  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2274  *              are located.
2275  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2276  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2277  *  \param [in] endComp - index of the component before which the components to assign
2278  *              to are located.
2279  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2280  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2281  *              must be equal to the number of columns to assign to, else an
2282  *              exception is thrown; if \a false, then it is only required that \a
2283  *              a->getNbOfElems() equals to number of values to assign to (this condition
2284  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2285  *              values to assign to is given by following Python expression:
2286  *              \a nbTargetValues = 
2287  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2288  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2289  *  \throw If \a a is NULL.
2290  *  \throw If \a a is not allocated.
2291  *  \throw If \a this is not allocated.
2292  *  \throw If parameters specifying tuples and components to assign to do not give a
2293  *            non-empty range of increasing indices.
2294  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2295  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2296  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2297  *
2298  *  \if ENABLE_EXAMPLES
2299  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2300  *  \endif
2301  */
2302 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2303 {
2304   if(!a)
2305     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2306   const char msg[]="DataArrayDouble::setPartOfValues1";
2307   checkAllocated();
2308   a->checkAllocated();
2309   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2310   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2311   int nbComp=getNumberOfComponents();
2312   int nbOfTuples=getNumberOfTuples();
2313   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2314   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2315   bool assignTech=true;
2316   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2317     {
2318       if(strictCompoCompare)
2319         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2320     }
2321   else
2322     {
2323       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2324       assignTech=false;
2325     }
2326   const double *srcPt=a->getConstPointer();
2327   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2328   if(assignTech)
2329     {
2330       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2331         for(int j=0;j<newNbOfComp;j++,srcPt++)
2332           pt[j*stepComp]=*srcPt;
2333     }
2334   else
2335     {
2336       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2337         {
2338           const double *srcPt2=srcPt;
2339           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2340             pt[j*stepComp]=*srcPt2;
2341         }
2342     }
2343 }
2344
2345 /*!
2346  * Assign a given value to values at specified tuples and components of \a this array.
2347  * The tree parameters defining set of indices of tuples and components are similar to
2348  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2349  *  \param [in] a - the value to assign.
2350  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2351  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2352  *              are located.
2353  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2354  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2355  *  \param [in] endComp - index of the component before which the components to assign
2356  *              to are located.
2357  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2358  *  \throw If \a this is not allocated.
2359  *  \throw If parameters specifying tuples and components to assign to, do not give a
2360  *            non-empty range of increasing indices or indices are out of a valid range
2361  *            for \this array.
2362  *
2363  *  \if ENABLE_EXAMPLES
2364  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2365  *  \endif
2366  */
2367 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2368 {
2369   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2370   checkAllocated();
2371   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2372   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2373   int nbComp=getNumberOfComponents();
2374   int nbOfTuples=getNumberOfTuples();
2375   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2376   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2377   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2378   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2379     for(int j=0;j<newNbOfComp;j++)
2380       pt[j*stepComp]=a;
2381 }
2382
2383 /*!
2384  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2385  * components of \a this array. Textual data is not copied.
2386  * The tuples and components to assign to are defined by C arrays of indices.
2387  * There are two *modes of usage*:
2388  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2389  *   of \a a is assigned to its own location within \a this array. 
2390  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2391  *   components of every specified tuple of \a this array. In this mode it is required
2392  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2393  *
2394  *  \param [in] a - the array to copy values from.
2395  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2396  *              assign values of \a a to.
2397  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2398  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2399  *              \a bgTuples <= \a pi < \a endTuples.
2400  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2401  *              assign values of \a a to.
2402  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2403  *              pointer to a component index <em>(pi)</em> varies as this: 
2404  *              \a bgComp <= \a pi < \a endComp.
2405  *  \param [in] strictCompoCompare - this parameter is checked only if the
2406  *               *mode of usage* is the first; if it is \a true (default), 
2407  *               then \a a->getNumberOfComponents() must be equal 
2408  *               to the number of specified columns, else this is not required.
2409  *  \throw If \a a is NULL.
2410  *  \throw If \a a is not allocated.
2411  *  \throw If \a this is not allocated.
2412  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2413  *         out of a valid range for \a this array.
2414  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2415  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2416  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2417  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2418  *
2419  *  \if ENABLE_EXAMPLES
2420  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2421  *  \endif
2422  */
2423 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2424 {
2425   if(!a)
2426     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2427   const char msg[]="DataArrayDouble::setPartOfValues2";
2428   checkAllocated();
2429   a->checkAllocated();
2430   int nbComp=getNumberOfComponents();
2431   int nbOfTuples=getNumberOfTuples();
2432   for(const int *z=bgComp;z!=endComp;z++)
2433     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2434   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2435   int newNbOfComp=(int)std::distance(bgComp,endComp);
2436   bool assignTech=true;
2437   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2438     {
2439       if(strictCompoCompare)
2440         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2441     }
2442   else
2443     {
2444       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2445       assignTech=false;
2446     }
2447   double *pt=getPointer();
2448   const double *srcPt=a->getConstPointer();
2449   if(assignTech)
2450     {    
2451       for(const int *w=bgTuples;w!=endTuples;w++)
2452         {
2453           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2454           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2455             {    
2456               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2457             }
2458         }
2459     }
2460   else
2461     {
2462       for(const int *w=bgTuples;w!=endTuples;w++)
2463         {
2464           const double *srcPt2=srcPt;
2465           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2466           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2467             {    
2468               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2469             }
2470         }
2471     }
2472 }
2473
2474 /*!
2475  * Assign a given value to values at specified tuples and components of \a this array.
2476  * The tuples and components to assign to are defined by C arrays of indices.
2477  *  \param [in] a - the value to assign.
2478  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2479  *              assign \a a to.
2480  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2481  *              pointer to a tuple index (\a pi) varies as this: 
2482  *              \a bgTuples <= \a pi < \a endTuples.
2483  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2484  *              assign \a a to.
2485  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2486  *              pointer to a component index (\a pi) varies as this: 
2487  *              \a bgComp <= \a pi < \a endComp.
2488  *  \throw If \a this is not allocated.
2489  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2490  *         out of a valid range for \a this array.
2491  *
2492  *  \if ENABLE_EXAMPLES
2493  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2494  *  \endif
2495  */
2496 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2497 {
2498   checkAllocated();
2499   int nbComp=getNumberOfComponents();
2500   int nbOfTuples=getNumberOfTuples();
2501   for(const int *z=bgComp;z!=endComp;z++)
2502     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2503   double *pt=getPointer();
2504   for(const int *w=bgTuples;w!=endTuples;w++)
2505     for(const int *z=bgComp;z!=endComp;z++)
2506       {
2507         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2508         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2509       }
2510 }
2511
2512 /*!
2513  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2514  * components of \a this array. Textual data is not copied.
2515  * The tuples to assign to are defined by a C array of indices.
2516  * The components to assign to are defined by three values similar to parameters of
2517  * the Python function \c range(\c start,\c stop,\c step).
2518  * There are two *modes of usage*:
2519  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2520  *   of \a a is assigned to its own location within \a this array. 
2521  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2522  *   components of every specified tuple of \a this array. In this mode it is required
2523  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2524  *
2525  *  \param [in] a - the array to copy values from.
2526  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2527  *              assign values of \a a to.
2528  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2529  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2530  *              \a bgTuples <= \a pi < \a endTuples.
2531  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2532  *  \param [in] endComp - index of the component before which the components to assign
2533  *              to are located.
2534  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2535  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2536  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2537  *               then \a a->getNumberOfComponents() must be equal 
2538  *               to the number of specified columns, else this is not required.
2539  *  \throw If \a a is NULL.
2540  *  \throw If \a a is not allocated.
2541  *  \throw If \a this is not allocated.
2542  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2543  *         \a this array.
2544  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2545  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2546  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2547  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2548  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2549  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2550  *  \throw If parameters specifying components to assign to, do not give a
2551  *            non-empty range of increasing indices or indices are out of a valid range
2552  *            for \this array.
2553  *
2554  *  \if ENABLE_EXAMPLES
2555  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2556  *  \endif
2557  */
2558 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2559 {
2560   if(!a)
2561     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2562   const char msg[]="DataArrayDouble::setPartOfValues3";
2563   checkAllocated();
2564   a->checkAllocated();
2565   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2566   int nbComp=getNumberOfComponents();
2567   int nbOfTuples=getNumberOfTuples();
2568   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2569   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2570   bool assignTech=true;
2571   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2572     {
2573       if(strictCompoCompare)
2574         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2575     }
2576   else
2577     {
2578       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2579       assignTech=false;
2580     }
2581   double *pt=getPointer()+bgComp;
2582   const double *srcPt=a->getConstPointer();
2583   if(assignTech)
2584     {
2585       for(const int *w=bgTuples;w!=endTuples;w++)
2586         for(int j=0;j<newNbOfComp;j++,srcPt++)
2587           {
2588             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2589             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2590           }
2591     }
2592   else
2593     {
2594       for(const int *w=bgTuples;w!=endTuples;w++)
2595         {
2596           const double *srcPt2=srcPt;
2597           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2598             {
2599               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2600               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2601             }
2602         }
2603     }
2604 }
2605
2606 /*!
2607  * Assign a given value to values at specified tuples and components of \a this array.
2608  * The tuples to assign to are defined by a C array of indices.
2609  * The components to assign to are defined by three values similar to parameters of
2610  * the Python function \c range(\c start,\c stop,\c step).
2611  *  \param [in] a - the value to assign.
2612  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2613  *              assign \a a to.
2614  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2615  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2616  *              \a bgTuples <= \a pi < \a endTuples.
2617  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2618  *  \param [in] endComp - index of the component before which the components to assign
2619  *              to are located.
2620  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2621  *  \throw If \a this is not allocated.
2622  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2623  *         \a this array.
2624  *  \throw If parameters specifying components to assign to, do not give a
2625  *            non-empty range of increasing indices or indices are out of a valid range
2626  *            for \this array.
2627  *
2628  *  \if ENABLE_EXAMPLES
2629  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2630  *  \endif
2631  */
2632 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2633 {
2634   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2635   checkAllocated();
2636   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2637   int nbComp=getNumberOfComponents();
2638   int nbOfTuples=getNumberOfTuples();
2639   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2640   double *pt=getPointer()+bgComp;
2641   for(const int *w=bgTuples;w!=endTuples;w++)
2642     for(int j=0;j<newNbOfComp;j++)
2643       {
2644         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2645         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2646       }
2647 }
2648
2649 /*!
2650  * Copy all values from another DataArrayDouble into specified tuples and components
2651  * of \a this array. Textual data is not copied.
2652  * The tree parameters defining set of indices of tuples and components are similar to
2653  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2654  *  \param [in] a - the array to copy values from.
2655  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2656  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2657  *              are located.
2658  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2659  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2660  *              assign \a a to.
2661  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2662  *              pointer to a component index (\a pi) varies as this: 
2663  *              \a bgComp <= \a pi < \a endComp.
2664  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2665  *              must be equal to the number of columns to assign to, else an
2666  *              exception is thrown; if \a false, then it is only required that \a
2667  *              a->getNbOfElems() equals to number of values to assign to (this condition
2668  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2669  *              values to assign to is given by following Python expression:
2670  *              \a nbTargetValues = 
2671  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2672  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2673  *  \throw If \a a is NULL.
2674  *  \throw If \a a is not allocated.
2675  *  \throw If \a this is not allocated.
2676  *  \throw If parameters specifying tuples and components to assign to do not give a
2677  *            non-empty range of increasing indices.
2678  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2679  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2680  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2681  *
2682  */
2683 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2684 {
2685   if(!a)
2686     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2687   const char msg[]="DataArrayDouble::setPartOfValues4";
2688   checkAllocated();
2689   a->checkAllocated();
2690   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2691   int newNbOfComp=(int)std::distance(bgComp,endComp);
2692   int nbComp=getNumberOfComponents();
2693   for(const int *z=bgComp;z!=endComp;z++)
2694     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2695   int nbOfTuples=getNumberOfTuples();
2696   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2697   bool assignTech=true;
2698   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2699     {
2700       if(strictCompoCompare)
2701         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2702     }
2703   else
2704     {
2705       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2706       assignTech=false;
2707     }
2708   const double *srcPt=a->getConstPointer();
2709   double *pt=getPointer()+bgTuples*nbComp;
2710   if(assignTech)
2711     {
2712       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2713         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2714           pt[*z]=*srcPt;
2715     }
2716   else
2717     {
2718       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2719         {
2720           const double *srcPt2=srcPt;
2721           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2722             pt[*z]=*srcPt2;
2723         }
2724     }
2725 }
2726
2727 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2728 {
2729   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2730   checkAllocated();
2731   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2732   int nbComp=getNumberOfComponents();
2733   for(const int *z=bgComp;z!=endComp;z++)
2734     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2735   int nbOfTuples=getNumberOfTuples();
2736   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2737   double *pt=getPointer()+bgTuples*nbComp;
2738   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2739     for(const int *z=bgComp;z!=endComp;z++)
2740       pt[*z]=a;
2741 }
2742
2743 /*!
2744  * Copy some tuples from another DataArrayDouble into specified tuples
2745  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2746  * components.
2747  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2748  * All components of selected tuples are copied.
2749  *  \param [in] a - the array to copy values from.
2750  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2751  *              target tuples of \a this. \a tuplesSelec has two components, and the
2752  *              first component specifies index of the source tuple and the second
2753  *              one specifies index of the target tuple.
2754  *  \throw If \a this is not allocated.
2755  *  \throw If \a a is NULL.
2756  *  \throw If \a a is not allocated.
2757  *  \throw If \a tuplesSelec is NULL.
2758  *  \throw If \a tuplesSelec is not allocated.
2759  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2760  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2761  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2762  *         the corresponding (\a this or \a a) array.
2763  */
2764 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2765 {
2766   if(!a || !tuplesSelec)
2767     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2768   checkAllocated();
2769   a->checkAllocated();
2770   tuplesSelec->checkAllocated();
2771   int nbOfComp=getNumberOfComponents();
2772   if(nbOfComp!=a->getNumberOfComponents())
2773     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2774   if(tuplesSelec->getNumberOfComponents()!=2)
2775     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2776   int thisNt=getNumberOfTuples();
2777   int aNt=a->getNumberOfTuples();
2778   double *valsToSet=getPointer();
2779   const double *valsSrc=a->getConstPointer();
2780   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2781     {
2782       if(tuple[1]>=0 && tuple[1]<aNt)
2783         {
2784           if(tuple[0]>=0 && tuple[0]<thisNt)
2785             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2786           else
2787             {
2788               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2789               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2790               throw INTERP_KERNEL::Exception(oss.str().c_str());
2791             }
2792         }
2793       else
2794         {
2795           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2796           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2797           throw INTERP_KERNEL::Exception(oss.str().c_str());
2798         }
2799     }
2800 }
2801
2802 /*!
2803  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2804  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2805  * components.
2806  * The tuples to assign to are defined by index of the first tuple, and
2807  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2808  * The tuples to copy are defined by values of a DataArrayInt.
2809  * All components of selected tuples are copied.
2810  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2811  *              values to.
2812  *  \param [in] aBase - the array to copy values from.
2813  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2814  *  \throw If \a this is not allocated.
2815  *  \throw If \a aBase is NULL.
2816  *  \throw If \a aBase is not allocated.
2817  *  \throw If \a tuplesSelec is NULL.
2818  *  \throw If \a tuplesSelec is not allocated.
2819  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2820  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2821  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2822  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2823  *         \a aBase array.
2824  */
2825 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2826 {
2827   if(!aBase || !tuplesSelec)
2828     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2829   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2830   if(!a)
2831     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2832   checkAllocated();
2833   a->checkAllocated();
2834   tuplesSelec->checkAllocated();
2835   int nbOfComp=getNumberOfComponents();
2836   if(nbOfComp!=a->getNumberOfComponents())
2837     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2838   if(tuplesSelec->getNumberOfComponents()!=1)
2839     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2840   int thisNt=getNumberOfTuples();
2841   int aNt=a->getNumberOfTuples();
2842   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2843   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2844   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2845     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2846   const double *valsSrc=a->getConstPointer();
2847   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2848     {
2849       if(*tuple>=0 && *tuple<aNt)
2850         {
2851           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2852         }
2853       else
2854         {
2855           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2856           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2857           throw INTERP_KERNEL::Exception(oss.str().c_str());
2858         }
2859     }
2860 }
2861
2862 /*!
2863  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2864  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2865  * components.
2866  * The tuples to copy are defined by three values similar to parameters of
2867  * the Python function \c range(\c start,\c stop,\c step).
2868  * The tuples to assign to are defined by index of the first tuple, and
2869  * their number is defined by number of tuples to copy.
2870  * All components of selected tuples are copied.
2871  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2872  *              values to.
2873  *  \param [in] aBase - the array to copy values from.
2874  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2875  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2876  *              are located.
2877  *  \param [in] step - index increment to get index of the next tuple to copy.
2878  *  \throw If \a this is not allocated.
2879  *  \throw If \a aBase is NULL.
2880  *  \throw If \a aBase is not allocated.
2881  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2882  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2883  *  \throw If parameters specifying tuples to copy, do not give a
2884  *            non-empty range of increasing indices or indices are out of a valid range
2885  *            for the array \a aBase.
2886  */
2887 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2888 {
2889   if(!aBase)
2890     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2891   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2892   if(!a)
2893     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2894   checkAllocated();
2895   a->checkAllocated();
2896   int nbOfComp=getNumberOfComponents();
2897   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2898   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2899   if(nbOfComp!=a->getNumberOfComponents())
2900     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2901   int thisNt=getNumberOfTuples();
2902   int aNt=a->getNumberOfTuples();
2903   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2904   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2905     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2906   if(end2>aNt)
2907     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2908   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2909   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2910     {
2911       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2912     }
2913 }
2914
2915 /*!
2916  * Returns a value located at specified tuple and component.
2917  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2918  * parameters is checked. So this method is safe but expensive if used to go through
2919  * all values of \a this.
2920  *  \param [in] tupleId - index of tuple of interest.
2921  *  \param [in] compoId - index of component of interest.
2922  *  \return double - value located by \a tupleId and \a compoId.
2923  *  \throw If \a this is not allocated.
2924  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2925  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2926  */
2927 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2928 {
2929   checkAllocated();
2930   if(tupleId<0 || tupleId>=getNumberOfTuples())
2931     {
2932       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2933       throw INTERP_KERNEL::Exception(oss.str().c_str());
2934     }
2935   if(compoId<0 || compoId>=getNumberOfComponents())
2936     {
2937       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2938       throw INTERP_KERNEL::Exception(oss.str().c_str());
2939     }
2940   return _mem[tupleId*_info_on_compo.size()+compoId];
2941 }
2942
2943 /*!
2944  * Returns the first value of \a this. 
2945  *  \return double - the last value of \a this array.
2946  *  \throw If \a this is not allocated.
2947  *  \throw If \a this->getNumberOfComponents() != 1.
2948  *  \throw If \a this->getNumberOfTuples() < 1.
2949  */
2950 double DataArrayDouble::front() const
2951 {
2952   checkAllocated();
2953   if(getNumberOfComponents()!=1)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2955   int nbOfTuples=getNumberOfTuples();
2956   if(nbOfTuples<1)
2957     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2958   return *(getConstPointer());
2959 }
2960
2961 /*!
2962  * Returns the last value of \a this. 
2963  *  \return double - the last value of \a this array.
2964  *  \throw If \a this is not allocated.
2965  *  \throw If \a this->getNumberOfComponents() != 1.
2966  *  \throw If \a this->getNumberOfTuples() < 1.
2967  */
2968 double DataArrayDouble::back() const
2969 {
2970   checkAllocated();
2971   if(getNumberOfComponents()!=1)
2972     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2973   int nbOfTuples=getNumberOfTuples();
2974   if(nbOfTuples<1)
2975     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2976   return *(getConstPointer()+nbOfTuples-1);
2977 }
2978
2979 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2980 {
2981   if(newArray!=arrayToSet)
2982     {
2983       if(arrayToSet)
2984         arrayToSet->decrRef();
2985       arrayToSet=newArray;
2986       if(arrayToSet)
2987         arrayToSet->incrRef();
2988     }
2989 }
2990
2991 /*!
2992  * Sets a C array to be used as raw data of \a this. The previously set info
2993  *  of components is retained and re-sized. 
2994  * For more info see \ref MEDCouplingArraySteps1.
2995  *  \param [in] array - the C array to be used as raw data of \a this.
2996  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2997  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2998  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2999  *                     \c free(\c array ) will be called.
3000  *  \param [in] nbOfTuple - new number of tuples in \a this.
3001  *  \param [in] nbOfCompo - new number of components in \a this.
3002  */
3003 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
3004 {
3005   _info_on_compo.resize(nbOfCompo);
3006   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
3007   declareAsNew();
3008 }
3009
3010 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3011 {
3012   _info_on_compo.resize(nbOfCompo);
3013   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3014   declareAsNew();
3015 }
3016
3017 /*!
3018  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3019  * is thrown.
3020  * \throw If zero is found in \a this array.
3021  */
3022 void DataArrayDouble::checkNoNullValues() const
3023 {
3024   const double *tmp=getConstPointer();
3025   std::size_t nbOfElems=getNbOfElems();
3026   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3027   if(where!=tmp+nbOfElems)
3028     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3029 }
3030
3031 /*!
3032  * Computes minimal and maximal value in each component. An output array is filled
3033  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3034  * enough memory before calling this method.
3035  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3036  *               It is filled as follows:<br>
3037  *               \a bounds[0] = \c min_of_component_0 <br>
3038  *               \a bounds[1] = \c max_of_component_0 <br>
3039  *               \a bounds[2] = \c min_of_component_1 <br>
3040  *               \a bounds[3] = \c max_of_component_1 <br>
3041  *               ...
3042  */
3043 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3044 {
3045   checkAllocated();
3046   int dim=getNumberOfComponents();
3047   for (int idim=0; idim<dim; idim++)
3048     {
3049       bounds[idim*2]=std::numeric_limits<double>::max();
3050       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3051     } 
3052   const double *ptr=getConstPointer();
3053   int nbOfTuples=getNumberOfTuples();
3054   for(int i=0;i<nbOfTuples;i++)
3055     {
3056       for(int idim=0;idim<dim;idim++)
3057         {
3058           if(bounds[idim*2]>ptr[i*dim+idim])
3059             {
3060               bounds[idim*2]=ptr[i*dim+idim];
3061             }
3062           if(bounds[idim*2+1]<ptr[i*dim+idim])
3063             {
3064               bounds[idim*2+1]=ptr[i*dim+idim];
3065             }
3066         }
3067     }
3068 }
3069
3070 /*!
3071  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3072  * to store both the min and max per component of each tuples. 
3073  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3074  *
3075  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3076  *
3077  * \throw If \a this is not allocated yet.
3078  */
3079 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3080 {
3081   checkAllocated();
3082   const double *dataPtr=getConstPointer();
3083   int nbOfCompo=getNumberOfComponents();
3084   int nbTuples=getNumberOfTuples();
3085   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3086   bbox->alloc(nbTuples,2*nbOfCompo);
3087   double *bboxPtr=bbox->getPointer();
3088   for(int i=0;i<nbTuples;i++)
3089     {
3090       for(int j=0;j<nbOfCompo;j++)
3091         {
3092           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3093           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3094         }
3095     }
3096   return bbox.retn();
3097 }
3098
3099 /*!
3100  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3101  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3102  * 
3103  * \param [in] other a DataArrayDouble having same number of components than \a this.
3104  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3105  * \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.
3106  *             \a cI allows to extract information in \a c.
3107  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3108  *
3109  * \throw In case of:
3110  *  - \a this is not allocated
3111  *  - \a other is not allocated or null
3112  *  - \a this and \a other do not have the same number of components
3113  *  - if number of components of \a this is not in [1,2,3]
3114  *
3115  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3116  */
3117 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3118 {
3119   if(!other)
3120     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3121   checkAllocated();
3122   other->checkAllocated();
3123   int nbOfCompo=getNumberOfComponents();
3124   int otherNbOfCompo=other->getNumberOfComponents();
3125   if(nbOfCompo!=otherNbOfCompo)
3126     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3127   int nbOfTuplesOther=other->getNumberOfTuples();
3128   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3129   switch(nbOfCompo)
3130   {
3131     case 3:
3132       {
3133         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3134         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3135         break;
3136       }
3137     case 2:
3138       {
3139         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3140         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3141         break;
3142       }
3143     case 1:
3144       {
3145         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3146         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3147         break;
3148       }
3149     default:
3150       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3151   }
3152   c=cArr.retn(); cI=cIArr.retn();
3153 }
3154
3155 /*!
3156  * 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
3157  * around origin of 'radius' 1.
3158  * 
3159  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3160  */
3161 void DataArrayDouble::recenterForMaxPrecision(double eps)
3162 {
3163   checkAllocated();
3164   int dim=getNumberOfComponents();
3165   std::vector<double> bounds(2*dim);
3166   getMinMaxPerComponent(&bounds[0]);
3167   for(int i=0;i<dim;i++)
3168     {
3169       double delta=bounds[2*i+1]-bounds[2*i];
3170       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3171       if(delta>eps)
3172         applyLin(1./delta,-offset/delta,i);
3173       else
3174         applyLin(1.,-offset,i);
3175     }
3176 }
3177
3178 /*!
3179  * Returns the maximal value and its location within \a this one-dimensional array.
3180  *  \param [out] tupleId - index of the tuple holding the maximal value.
3181  *  \return double - the maximal value among all values of \a this array.
3182  *  \throw If \a this->getNumberOfComponents() != 1
3183  *  \throw If \a this->getNumberOfTuples() < 1
3184  */
3185 double DataArrayDouble::getMaxValue(int& tupleId) const
3186 {
3187   checkAllocated();
3188   if(getNumberOfComponents()!=1)
3189     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 !");
3190   int nbOfTuples=getNumberOfTuples();
3191   if(nbOfTuples<=0)
3192     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3193   const double *vals=getConstPointer();
3194   const double *loc=std::max_element(vals,vals+nbOfTuples);
3195   tupleId=(int)std::distance(vals,loc);
3196   return *loc;
3197 }
3198
3199 /*!
3200  * Returns the maximal value within \a this array that is allowed to have more than
3201  *  one component.
3202  *  \return double - the maximal value among all values of \a this array.
3203  *  \throw If \a this is not allocated.
3204  */
3205 double DataArrayDouble::getMaxValueInArray() const
3206 {
3207   checkAllocated();
3208   const double *loc=std::max_element(begin(),end());
3209   return *loc;
3210 }
3211
3212 /*!
3213  * Returns the maximal value and all its locations within \a this one-dimensional array.
3214  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3215  *               tuples holding the maximal value. The caller is to delete it using
3216  *               decrRef() as it is no more needed.
3217  *  \return double - the maximal value among all values of \a this array.
3218  *  \throw If \a this->getNumberOfComponents() != 1
3219  *  \throw If \a this->getNumberOfTuples() < 1
3220  */
3221 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3222 {
3223   int tmp;
3224   tupleIds=0;
3225   double ret=getMaxValue(tmp);
3226   tupleIds=getIdsInRange(ret,ret);
3227   return ret;
3228 }
3229
3230 /*!
3231  * Returns the minimal value and its location within \a this one-dimensional array.
3232  *  \param [out] tupleId - index of the tuple holding the minimal value.
3233  *  \return double - the minimal value among all values of \a this array.
3234  *  \throw If \a this->getNumberOfComponents() != 1
3235  *  \throw If \a this->getNumberOfTuples() < 1
3236  */
3237 double DataArrayDouble::getMinValue(int& tupleId) const
3238 {
3239   checkAllocated();
3240   if(getNumberOfComponents()!=1)
3241     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3242   int nbOfTuples=getNumberOfTuples();
3243   if(nbOfTuples<=0)
3244     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3245   const double *vals=getConstPointer();
3246   const double *loc=std::min_element(vals,vals+nbOfTuples);
3247   tupleId=(int)std::distance(vals,loc);
3248   return *loc;
3249 }
3250
3251 /*!
3252  * Returns the minimal value within \a this array that is allowed to have more than
3253  *  one component.
3254  *  \return double - the minimal value among all values of \a this array.
3255  *  \throw If \a this is not allocated.
3256  */
3257 double DataArrayDouble::getMinValueInArray() const
3258 {
3259   checkAllocated();
3260   const double *loc=std::min_element(begin(),end());
3261   return *loc;
3262 }
3263
3264 /*!
3265  * Returns the minimal value and all its locations within \a this one-dimensional array.
3266  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3267  *               tuples holding the minimal value. The caller is to delete it using
3268  *               decrRef() as it is no more needed.
3269  *  \return double - the minimal value among all values of \a this array.
3270  *  \throw If \a this->getNumberOfComponents() != 1
3271  *  \throw If \a this->getNumberOfTuples() < 1
3272  */
3273 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3274 {
3275   int tmp;
3276   tupleIds=0;
3277   double ret=getMinValue(tmp);
3278   tupleIds=getIdsInRange(ret,ret);
3279   return ret;
3280 }
3281
3282 /*!
3283  * 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.
3284  * This method only works for single component array.
3285  *
3286  * \return a value in [ 0, \c this->getNumberOfTuples() )
3287  *
3288  * \throw If \a this is not allocated
3289  *
3290  */
3291 int DataArrayDouble::count(double value, double eps) const
3292 {
3293   int ret=0;
3294   checkAllocated();
3295   if(getNumberOfComponents()!=1)
3296     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3297   const double *vals=begin();
3298   int nbOfTuples=getNumberOfTuples();
3299   for(int i=0;i<nbOfTuples;i++,vals++)
3300     if(fabs(*vals-value)<=eps)
3301       ret++;
3302   return ret;
3303 }
3304
3305 /*!
3306  * Returns the average value of \a this one-dimensional array.
3307  *  \return double - the average value over all values of \a this array.
3308  *  \throw If \a this->getNumberOfComponents() != 1
3309  *  \throw If \a this->getNumberOfTuples() < 1
3310  */
3311 double DataArrayDouble::getAverageValue() const
3312 {
3313   if(getNumberOfComponents()!=1)
3314     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3315   int nbOfTuples=getNumberOfTuples();
3316   if(nbOfTuples<=0)
3317     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3318   const double *vals=getConstPointer();
3319   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3320   return ret/nbOfTuples;
3321 }
3322
3323 /*!
3324  * Returns the Euclidean norm of the vector defined by \a this array.
3325  *  \return double - the value of the Euclidean norm, i.e.
3326  *          the square root of the inner product of vector.
3327  *  \throw If \a this is not allocated.
3328  */
3329 double DataArrayDouble::norm2() const
3330 {
3331   checkAllocated();
3332   double ret=0.;
3333   std::size_t nbOfElems=getNbOfElems();
3334   const double *pt=getConstPointer();
3335   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3336     ret+=(*pt)*(*pt);
3337   return sqrt(ret);
3338 }
3339
3340 /*!
3341  * Returns the maximum norm of the vector defined by \a this array.
3342  * This method works even if the number of components is diferent from one.
3343  * If the number of elements in \a this is 0, -1. is returned.
3344  *  \return double - the value of the maximum norm, i.e.
3345  *          the maximal absolute value among values of \a this array (whatever its number of components).
3346  *  \throw If \a this is not allocated.
3347  */
3348 double DataArrayDouble::normMax() const
3349 {
3350   checkAllocated();
3351   double ret(-1.);
3352   std::size_t nbOfElems(getNbOfElems());
3353   const double *pt(getConstPointer());
3354   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3355     {
3356       double val(std::abs(*pt));
3357       if(val>ret)
3358         ret=val;
3359     }
3360   return ret;
3361 }
3362
3363 /*!
3364  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3365  * This method works even if the number of components is diferent from one.
3366  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3367  *  \return double - the value of the minimum norm, i.e.
3368  *          the minimal absolute value among values of \a this array (whatever its number of components).
3369  *  \throw If \a this is not allocated.
3370  */
3371 double DataArrayDouble::normMin() const
3372 {
3373   checkAllocated();
3374   double ret(std::numeric_limits<double>::max());
3375   std::size_t nbOfElems(getNbOfElems());
3376   const double *pt(getConstPointer());
3377   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3378     {
3379       double val(std::abs(*pt));
3380       if(val<ret)
3381         ret=val;
3382     }
3383   return ret;
3384 }
3385
3386 /*!
3387  * Accumulates values of each component of \a this array.
3388  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3389  *         by the caller, that is filled by this method with sum value for each
3390  *         component.
3391  *  \throw If \a this is not allocated.
3392  */
3393 void DataArrayDouble::accumulate(double *res) const
3394 {
3395   checkAllocated();
3396   const double *ptr=getConstPointer();
3397   int nbTuple=getNumberOfTuples();
3398   int nbComps=getNumberOfComponents();
3399   std::fill(res,res+nbComps,0.);
3400   for(int i=0;i<nbTuple;i++)
3401     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3402 }
3403
3404 /*!
3405  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3406  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3407  *
3408  *
3409  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3410  * \a tupleEnd. If not an exception will be thrown.
3411  *
3412  * \param [in] tupleBg start pointer (included) of input external tuple
3413  * \param [in] tupleEnd end pointer (not included) of input external tuple
3414  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3415  * \return the min distance.
3416  * \sa MEDCouplingUMesh::distanceToPoint
3417  */
3418 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3419 {
3420   checkAllocated();
3421   int nbTuple=getNumberOfTuples();
3422   int nbComps=getNumberOfComponents();
3423   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3424     { 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()); }
3425   if(nbTuple==0)
3426     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3427   double ret0=std::numeric_limits<double>::max();
3428   tupleId=-1;
3429   const double *work=getConstPointer();
3430   for(int i=0;i<nbTuple;i++)
3431     {
3432       double val=0.;
3433       for(int j=0;j<nbComps;j++,work++) 
3434         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3435       if(val>=ret0)
3436         continue;
3437       else
3438         { ret0=val; tupleId=i; }
3439     }
3440   return sqrt(ret0);
3441 }
3442
3443 /*!
3444  * Accumulate values of the given component of \a this array.
3445  *  \param [in] compId - the index of the component of interest.
3446  *  \return double - a sum value of \a compId-th component.
3447  *  \throw If \a this is not allocated.
3448  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3449  *         not respected.
3450  */
3451 double DataArrayDouble::accumulate(int compId) const
3452 {
3453   checkAllocated();
3454   const double *ptr=getConstPointer();
3455   int nbTuple=getNumberOfTuples();
3456   int nbComps=getNumberOfComponents();
3457   if(compId<0 || compId>=nbComps)
3458     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3459   double ret=0.;
3460   for(int i=0;i<nbTuple;i++)
3461     ret+=ptr[i*nbComps+compId];
3462   return ret;
3463 }
3464
3465 /*!
3466  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3467  * The returned array will have same number of components than \a this and number of tuples equal to
3468  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3469  *
3470  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3471  * 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.
3472  *
3473  * \param [in] bgOfIndex - begin (included) of the input index array.
3474  * \param [in] endOfIndex - end (excluded) of the input index array.
3475  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3476  * 
3477  * \throw If bgOfIndex or end is NULL.
3478  * \throw If input index array is not ascendingly sorted.
3479  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3480  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3481  */
3482 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3483 {
3484   if(!bgOfIndex || !endOfIndex)
3485     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3486   checkAllocated();
3487   int nbCompo=getNumberOfComponents();
3488   int nbOfTuples=getNumberOfTuples();
3489   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3490   if(sz<1)
3491     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3492   sz--;
3493   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3494   const int *w=bgOfIndex;
3495   if(*w<0 || *w>=nbOfTuples)
3496     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3497   const double *srcPt=begin()+(*w)*nbCompo;
3498   double *tmp=ret->getPointer();
3499   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3500     {
3501       std::fill(tmp,tmp+nbCompo,0.);
3502       if(w[1]>=w[0])
3503         {
3504           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3505             {
3506               if(j>=0 && j<nbOfTuples)
3507                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3508               else
3509                 {
3510                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3511                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3512                 }
3513             }
3514         }
3515       else
3516         {
3517           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3518           throw INTERP_KERNEL::Exception(oss.str().c_str());
3519         }
3520     }
3521   ret->copyStringInfoFrom(*this);
3522   return ret.retn();
3523 }
3524
3525 /*!
3526  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3527  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3528  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3529  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3530  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3531  *          is to delete this array using decrRef() as it is no more needed. The array
3532  *          does not contain any textual info on components.
3533  *  \throw If \a this->getNumberOfComponents() != 2.
3534  */
3535 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3536 {
3537   checkAllocated();
3538   int nbOfComp=getNumberOfComponents();
3539   if(nbOfComp!=2)
3540     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3541   int nbOfTuple=getNumberOfTuples();
3542   DataArrayDouble *ret=DataArrayDouble::New();
3543   ret->alloc(nbOfTuple,2);
3544   double *w=ret->getPointer();
3545   const double *wIn=getConstPointer();
3546   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3547     {
3548       w[0]=wIn[0]*cos(wIn[1]);
3549       w[1]=wIn[0]*sin(wIn[1]);
3550     }
3551   return ret;
3552 }
3553
3554 /*!
3555  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3556  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3557  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3558  * the Cylindrical CS.
3559  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3560  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3561  *          on the third component is copied from \a this array. The caller
3562  *          is to delete this array using decrRef() as it is no more needed. 
3563  *  \throw If \a this->getNumberOfComponents() != 3.
3564  */
3565 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3566 {
3567   checkAllocated();
3568   int nbOfComp=getNumberOfComponents();
3569   if(nbOfComp!=3)
3570     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3571   int nbOfTuple=getNumberOfTuples();
3572   DataArrayDouble *ret=DataArrayDouble::New();
3573   ret->alloc(getNumberOfTuples(),3);
3574   double *w=ret->getPointer();
3575   const double *wIn=getConstPointer();
3576   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3577     {
3578       w[0]=wIn[0]*cos(wIn[1]);
3579       w[1]=wIn[0]*sin(wIn[1]);
3580       w[2]=wIn[2];
3581     }
3582   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3583   return ret;
3584 }
3585
3586 /*!
3587  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3588  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3589  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3590  * point in the Cylindrical CS.
3591  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3592  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3593  *          on the third component is copied from \a this array. The caller
3594  *          is to delete this array using decrRef() as it is no more needed.
3595  *  \throw If \a this->getNumberOfComponents() != 3.
3596  */
3597 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3598 {
3599   checkAllocated();
3600   int nbOfComp=getNumberOfComponents();
3601   if(nbOfComp!=3)
3602     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3603   int nbOfTuple=getNumberOfTuples();
3604   DataArrayDouble *ret=DataArrayDouble::New();
3605   ret->alloc(getNumberOfTuples(),3);
3606   double *w=ret->getPointer();
3607   const double *wIn=getConstPointer();
3608   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3609     {
3610       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3611       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3612       w[2]=wIn[0]*cos(wIn[1]);
3613     }
3614   return ret;
3615 }
3616
3617 /*!
3618  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3619  * array contating 6 components.
3620  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3621  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3622  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3623  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3624  *  \throw If \a this->getNumberOfComponents() != 6.
3625  */
3626 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3627 {
3628   checkAllocated();
3629   int nbOfComp=getNumberOfComponents();
3630   if(nbOfComp!=6)
3631     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3632   DataArrayDouble *ret=DataArrayDouble::New();
3633   int nbOfTuple=getNumberOfTuples();
3634   ret->alloc(nbOfTuple,1);
3635   const double *src=getConstPointer();
3636   double *dest=ret->getPointer();
3637   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3638     *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];
3639   return ret;
3640 }
3641
3642 /*!
3643  * Computes the determinant of every square matrix defined by the tuple of \a this
3644  * array, which contains either 4, 6 or 9 components. The case of 6 components
3645  * corresponds to that of the upper triangular matrix.
3646  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3647  *          is the determinant of matrix of the corresponding tuple of \a this array.
3648  *          The caller is to delete this result array using decrRef() as it is no more
3649  *          needed. 
3650  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3651  */
3652 DataArrayDouble *DataArrayDouble::determinant() const
3653 {
3654   checkAllocated();
3655   DataArrayDouble *ret=DataArrayDouble::New();
3656   int nbOfTuple=getNumberOfTuples();
3657   ret->alloc(nbOfTuple,1);
3658   const double *src=getConstPointer();
3659   double *dest=ret->getPointer();
3660   switch(getNumberOfComponents())
3661   {
3662     case 6:
3663       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3664         *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];
3665       return ret;
3666     case 4:
3667       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3668         *dest=src[0]*src[3]-src[1]*src[2];
3669       return ret;
3670     case 9:
3671       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3672         *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];
3673       return ret;
3674     default:
3675       ret->decrRef();
3676       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3677   }
3678 }
3679
3680 /*!
3681  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3682  * \a this array, which contains 6 components.
3683  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3684  *          components, whose each tuple contains the eigenvalues of the matrix of
3685  *          corresponding tuple of \a this array. 
3686  *          The caller is to delete this result array using decrRef() as it is no more
3687  *          needed. 
3688  *  \throw If \a this->getNumberOfComponents() != 6.
3689  */
3690 DataArrayDouble *DataArrayDouble::eigenValues() const
3691 {
3692   checkAllocated();
3693   int nbOfComp=getNumberOfComponents();
3694   if(nbOfComp!=6)
3695     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3696   DataArrayDouble *ret=DataArrayDouble::New();
3697   int nbOfTuple=getNumberOfTuples();
3698   ret->alloc(nbOfTuple,3);
3699   const double *src=getConstPointer();
3700   double *dest=ret->getPointer();
3701   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3702     INTERP_KERNEL::computeEigenValues6(src,dest);
3703   return ret;
3704 }
3705
3706 /*!
3707  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3708  * \a this array, which contains 6 components.
3709  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3710  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3711  *          corresponding tuple of \a this array.
3712  *          The caller is to delete this result array using decrRef() as it is no more
3713  *          needed.
3714  *  \throw If \a this->getNumberOfComponents() != 6.
3715  */
3716 DataArrayDouble *DataArrayDouble::eigenVectors() const
3717 {
3718   checkAllocated();
3719   int nbOfComp=getNumberOfComponents();
3720   if(nbOfComp!=6)
3721     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3722   DataArrayDouble *ret=DataArrayDouble::New();
3723   int nbOfTuple=getNumberOfTuples();
3724   ret->alloc(nbOfTuple,9);
3725   const double *src=getConstPointer();
3726   double *dest=ret->getPointer();
3727   for(int i=0;i<nbOfTuple;i++,src+=6)
3728     {
3729       double tmp[3];
3730       INTERP_KERNEL::computeEigenValues6(src,tmp);
3731       for(int j=0;j<3;j++,dest+=3)
3732         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3733     }
3734   return ret;
3735 }
3736
3737 /*!
3738  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3739  * array, which contains either 4, 6 or 9 components. The case of 6 components
3740  * corresponds to that of the upper triangular matrix.
3741  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3742  *          same number of components as \a this one, whose each tuple is the inverse
3743  *          matrix of the matrix of corresponding tuple of \a this array. 
3744  *          The caller is to delete this result array using decrRef() as it is no more
3745  *          needed. 
3746  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3747  */
3748 DataArrayDouble *DataArrayDouble::inverse() const
3749 {
3750   checkAllocated();
3751   int nbOfComp=getNumberOfComponents();
3752   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3753     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3754   DataArrayDouble *ret=DataArrayDouble::New();
3755   int nbOfTuple=getNumberOfTuples();
3756   ret->alloc(nbOfTuple,nbOfComp);
3757   const double *src=getConstPointer();
3758   double *dest=ret->getPointer();
3759   if(nbOfComp==6)
3760     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3761       {
3762         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];
3763         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3764         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3765         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3766         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3767         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3768         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3769       }
3770   else if(nbOfComp==4)
3771     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3772       {
3773         double det=src[0]*src[3]-src[1]*src[2];
3774         dest[0]=src[3]/det;
3775         dest[1]=-src[1]/det;
3776         dest[2]=-src[2]/det;
3777         dest[3]=src[0]/det;
3778       }
3779   else
3780     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3781       {
3782         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];
3783         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3784         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3785         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3786         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3787         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3788         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3789         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3790         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3791         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3792       }
3793   return ret;
3794 }
3795
3796 /*!
3797  * Computes the trace of every matrix defined by the tuple of \a this
3798  * array, which contains either 4, 6 or 9 components. The case of 6 components
3799  * corresponds to that of the upper triangular matrix.
3800  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3801  *          1 component, whose each tuple is the trace of
3802  *          the matrix of corresponding tuple of \a this array. 
3803  *          The caller is to delete this result array using decrRef() as it is no more
3804  *          needed. 
3805  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3806  */
3807 DataArrayDouble *DataArrayDouble::trace() const
3808 {
3809   checkAllocated();
3810   int nbOfComp=getNumberOfComponents();
3811   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3812     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3813   DataArrayDouble *ret=DataArrayDouble::New();
3814   int nbOfTuple=getNumberOfTuples();
3815   ret->alloc(nbOfTuple,1);
3816   const double *src=getConstPointer();
3817   double *dest=ret->getPointer();
3818   if(nbOfComp==6)
3819     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3820       *dest=src[0]+src[1]+src[2];
3821   else if(nbOfComp==4)
3822     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3823       *dest=src[0]+src[3];
3824   else
3825     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3826       *dest=src[0]+src[4]+src[8];
3827   return ret;
3828 }
3829
3830 /*!
3831  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3832  * \a this array, which contains 6 components.
3833  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3834  *          same number of components and tuples as \a this array.
3835  *          The caller is to delete this result array using decrRef() as it is no more
3836  *          needed.
3837  *  \throw If \a this->getNumberOfComponents() != 6.
3838  */
3839 DataArrayDouble *DataArrayDouble::deviator() const
3840 {
3841   checkAllocated();
3842   int nbOfComp=getNumberOfComponents();
3843   if(nbOfComp!=6)
3844     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3845   DataArrayDouble *ret=DataArrayDouble::New();
3846   int nbOfTuple=getNumberOfTuples();
3847   ret->alloc(nbOfTuple,6);
3848   const double *src=getConstPointer();
3849   double *dest=ret->getPointer();
3850   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3851     {
3852       double tr=(src[0]+src[1]+src[2])/3.;
3853       dest[0]=src[0]-tr;
3854       dest[1]=src[1]-tr;
3855       dest[2]=src[2]-tr;
3856       dest[3]=src[3];
3857       dest[4]=src[4];
3858       dest[5]=src[5];
3859     }
3860   return ret;
3861 }
3862
3863 /*!
3864  * Computes the magnitude of every vector defined by the tuple of
3865  * \a this array.
3866  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3867  *          same number of tuples as \a this array and one component.
3868  *          The caller is to delete this result array using decrRef() as it is no more
3869  *          needed.
3870  *  \throw If \a this is not allocated.
3871  */
3872 DataArrayDouble *DataArrayDouble::magnitude() const
3873 {
3874   checkAllocated();
3875   int nbOfComp=getNumberOfComponents();
3876   DataArrayDouble *ret=DataArrayDouble::New();
3877   int nbOfTuple=getNumberOfTuples();
3878   ret->alloc(nbOfTuple,1);
3879   const double *src=getConstPointer();
3880   double *dest=ret->getPointer();
3881   for(int i=0;i<nbOfTuple;i++,dest++)
3882     {
3883       double sum=0.;
3884       for(int j=0;j<nbOfComp;j++,src++)
3885         sum+=(*src)*(*src);
3886       *dest=sqrt(sum);
3887     }
3888   return ret;
3889 }
3890
3891 /*!
3892  * Computes for each tuple the sum of number of components values in the tuple and return it.
3893  * 
3894  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3895  *          same number of tuples as \a this array and one component.
3896  *          The caller is to delete this result array using decrRef() as it is no more
3897  *          needed.
3898  *  \throw If \a this is not allocated.
3899  */
3900 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3901 {
3902   checkAllocated();
3903   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3904   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3905   ret->alloc(nbOfTuple,1);
3906   const double *src(getConstPointer());
3907   double *dest(ret->getPointer());
3908   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3909     *dest=std::accumulate(src,src+nbOfComp,0.);
3910   return ret.retn();
3911 }
3912
3913 /*!
3914  * Computes the maximal value within every tuple of \a this array.
3915  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3916  *          same number of tuples as \a this array and one component.
3917  *          The caller is to delete this result array using decrRef() as it is no more
3918  *          needed.
3919  *  \throw If \a this is not allocated.
3920  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3921  */
3922 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3923 {
3924   checkAllocated();
3925   int nbOfComp=getNumberOfComponents();
3926   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3927   int nbOfTuple=getNumberOfTuples();
3928   ret->alloc(nbOfTuple,1);
3929   const double *src=getConstPointer();
3930   double *dest=ret->getPointer();
3931   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3932     *dest=*std::max_element(src,src+nbOfComp);
3933   return ret.retn();
3934 }
3935
3936 /*!
3937  * Computes the maximal value within every tuple of \a this array and it returns the first component
3938  * id for each tuple that corresponds to the maximal value within the tuple.
3939  * 
3940  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3941  *          same number of tuples and only one component.
3942  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3943  *          same number of tuples as \a this array and one component.
3944  *          The caller is to delete this result array using decrRef() as it is no more
3945  *          needed.
3946  *  \throw If \a this is not allocated.
3947  *  \sa DataArrayDouble::maxPerTuple
3948  */
3949 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3950 {
3951   checkAllocated();
3952   int nbOfComp=getNumberOfComponents();
3953   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3954   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3955   int nbOfTuple=getNumberOfTuples();
3956   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3957   const double *src=getConstPointer();
3958   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3959   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3960     {
3961       const double *loc=std::max_element(src,src+nbOfComp);
3962       *dest=*loc;
3963       *dest1=(int)std::distance(src,loc);
3964     }
3965   compoIdOfMaxPerTuple=ret1.retn();
3966   return ret0.retn();
3967 }
3968
3969 /*!
3970  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3971  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3972  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3973  * \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)
3974  *
3975  * \warning use this method with care because it can leads to big amount of consumed memory !
3976  * 
3977  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3978  *
3979  * \throw If \a this is not allocated.
3980  *
3981  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3982  */
3983 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3984 {
3985   checkAllocated();
3986   int nbOfComp=getNumberOfComponents();
3987   int nbOfTuples=getNumberOfTuples();
3988   const double *inData=getConstPointer();
3989   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3990   ret->alloc(nbOfTuples*nbOfTuples,1);
3991   double *outData=ret->getPointer();
3992   for(int i=0;i<nbOfTuples;i++)
3993     {
3994       outData[i*nbOfTuples+i]=0.;
3995       for(int j=i+1;j<nbOfTuples;j++)
3996         {
3997           double dist=0.;
3998           for(int k=0;k<nbOfComp;k++)
3999             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4000           dist=sqrt(dist);
4001           outData[i*nbOfTuples+j]=dist;
4002           outData[j*nbOfTuples+i]=dist;
4003         }
4004     }
4005   return ret.retn();
4006 }
4007
4008 /*!
4009  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4010  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4011  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4012  * \n Output rectangular matrix is sorted along rows.
4013  * \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)
4014  *
4015  * \warning use this method with care because it can leads to big amount of consumed memory !
4016  * 
4017  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4018  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4019  *
4020  * \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.
4021  *
4022  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4023  */
4024 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4025 {
4026   if(!other)
4027     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4028   checkAllocated();
4029   other->checkAllocated();
4030   int nbOfComp=getNumberOfComponents();
4031   int otherNbOfComp=other->getNumberOfComponents();
4032   if(nbOfComp!=otherNbOfComp)
4033     {
4034       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4035       throw INTERP_KERNEL::Exception(oss.str().c_str());
4036     }
4037   int nbOfTuples=getNumberOfTuples();
4038   int otherNbOfTuples=other->getNumberOfTuples();
4039   const double *inData=getConstPointer();
4040   const double *inDataOther=other->getConstPointer();
4041   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4042   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4043   double *outData=ret->getPointer();
4044   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4045     {
4046       for(int j=0;j<nbOfTuples;j++)
4047         {
4048           double dist=0.;
4049           for(int k=0;k<nbOfComp;k++)
4050             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4051           dist=sqrt(dist);
4052           outData[i*nbOfTuples+j]=dist;
4053         }
4054     }
4055   return ret.retn();
4056 }
4057
4058 /*!
4059  * Sorts value within every tuple of \a this array.
4060  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4061  *              in descending order.
4062  *  \throw If \a this is not allocated.
4063  */
4064 void DataArrayDouble::sortPerTuple(bool asc)
4065 {
4066   checkAllocated();
4067   double *pt=getPointer();
4068   int nbOfTuple=getNumberOfTuples();
4069   int nbOfComp=getNumberOfComponents();
4070   if(asc)
4071     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4072       std::sort(pt,pt+nbOfComp);
4073   else
4074     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4075       std::sort(pt,pt+nbOfComp,std::greater<double>());
4076   declareAsNew();
4077 }
4078
4079 /*!
4080  * Converts every value of \a this array to its absolute value.
4081  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4082  * should be called instead.
4083  *
4084  * \throw If \a this is not allocated.
4085  * \sa DataArrayDouble::computeAbs
4086  */
4087 void DataArrayDouble::abs()
4088 {
4089   checkAllocated();
4090   double *ptr(getPointer());
4091   std::size_t nbOfElems(getNbOfElems());
4092   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4093   declareAsNew();
4094 }
4095
4096 /*!
4097  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4098  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4099  *
4100  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4101  *         same number of tuples and component as \a this array.
4102  *         The caller is to delete this result array using decrRef() as it is no more
4103  *         needed.
4104  * \throw If \a this is not allocated.
4105  * \sa DataArrayDouble::abs
4106  */
4107 DataArrayDouble *DataArrayDouble::computeAbs() const
4108 {
4109   checkAllocated();
4110   DataArrayDouble *newArr(DataArrayDouble::New());
4111   int nbOfTuples(getNumberOfTuples());
4112   int nbOfComp(getNumberOfComponents());
4113   newArr->alloc(nbOfTuples,nbOfComp);
4114   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4115   newArr->copyStringInfoFrom(*this);
4116   return newArr;
4117 }
4118
4119 /*!
4120  * Apply a linear function to a given component of \a this array, so that
4121  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4122  *  \param [in] a - the first coefficient of the function.
4123  *  \param [in] b - the second coefficient of the function.
4124  *  \param [in] compoId - the index of component to modify.
4125  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4126  */
4127 void DataArrayDouble::applyLin(double a, double b, int compoId)
4128 {
4129   checkAllocated();
4130   double *ptr(getPointer()+compoId);
4131   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4132   if(compoId<0 || compoId>=nbOfComp)
4133     {
4134       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4135       throw INTERP_KERNEL::Exception(oss.str().c_str());
4136     }
4137   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4138     *ptr=a*(*ptr)+b;
4139   declareAsNew();
4140 }
4141
4142 /*!
4143  * Apply a linear function to all elements of \a this array, so that
4144  * an element _x_ becomes \f$ a * x + b \f$.
4145  *  \param [in] a - the first coefficient of the function.
4146  *  \param [in] b - the second coefficient of the function.
4147  *  \throw If \a this is not allocated.
4148  */
4149 void DataArrayDouble::applyLin(double a, double b)
4150 {
4151   checkAllocated();
4152   double *ptr=getPointer();
4153   std::size_t nbOfElems=getNbOfElems();
4154   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4155     *ptr=a*(*ptr)+b;
4156   declareAsNew();
4157 }
4158
4159 /*!
4160  * Modify all elements of \a this array, so that
4161  * an element _x_ becomes \f$ numerator / x \f$.
4162  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4163  *           array, all elements processed before detection of the zero element remain
4164  *           modified.
4165  *  \param [in] numerator - the numerator used to modify array elements.
4166  *  \throw If \a this is not allocated.
4167  *  \throw If there is an element equal to 0.0 in \a this array.
4168  */
4169 void DataArrayDouble::applyInv(double numerator)
4170 {
4171   checkAllocated();
4172   double *ptr=getPointer();
4173   std::size_t nbOfElems=getNbOfElems();
4174   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4175     {
4176       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4177         {
4178           *ptr=numerator/(*ptr);
4179         }
4180       else
4181         {
4182           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4183           oss << " !";
4184           throw INTERP_KERNEL::Exception(oss.str().c_str());
4185         }
4186     }
4187   declareAsNew();
4188 }
4189
4190 /*!
4191  * Returns a full copy of \a this array except that sign of all elements is reversed.
4192  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4193  *          same number of tuples and component as \a this array.
4194  *          The caller is to delete this result array using decrRef() as it is no more
4195  *          needed.
4196  *  \throw If \a this is not allocated.
4197  */
4198 DataArrayDouble *DataArrayDouble::negate() const
4199 {
4200   checkAllocated();
4201   DataArrayDouble *newArr=DataArrayDouble::New();
4202   int nbOfTuples=getNumberOfTuples();
4203   int nbOfComp=getNumberOfComponents();
4204   newArr->alloc(nbOfTuples,nbOfComp);
4205   const double *cptr=getConstPointer();
4206   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4207   newArr->copyStringInfoFrom(*this);
4208   return newArr;
4209 }
4210
4211 /*!
4212  * Modify all elements of \a this array, so that
4213  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4214  * all values in \a this have to be >= 0 if val is \b not integer.
4215  *  \param [in] val - the value used to apply pow on all array elements.
4216  *  \throw If \a this is not allocated.
4217  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4218  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4219  *           modified.
4220  */
4221 void DataArrayDouble::applyPow(double val)
4222 {
4223   checkAllocated();
4224   double *ptr=getPointer();
4225   std::size_t nbOfElems=getNbOfElems();
4226   int val2=(int)val;
4227   bool isInt=((double)val2)==val;
4228   if(!isInt)
4229     {
4230       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4231         {
4232           if(*ptr>=0)
4233             *ptr=pow(*ptr,val);
4234           else
4235             {
4236               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4237               throw INTERP_KERNEL::Exception(oss.str().c_str());
4238             }
4239         }
4240     }
4241   else
4242     {
4243       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4244         *ptr=pow(*ptr,val2);
4245     }
4246   declareAsNew();
4247 }
4248
4249 /*!
4250  * Modify all elements of \a this array, so that
4251  * an element _x_ becomes \f$ val ^ x \f$.
4252  *  \param [in] val - the value used to apply pow on all array elements.
4253  *  \throw If \a this is not allocated.
4254  *  \throw If \a val < 0.
4255  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4256  *           array, all elements processed before detection of the zero element remain
4257  *           modified.
4258  */
4259 void DataArrayDouble::applyRPow(double val)
4260 {
4261   checkAllocated();
4262   if(val<0.)
4263     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4264   double *ptr=getPointer();
4265   std::size_t nbOfElems=getNbOfElems();
4266   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4267     *ptr=pow(val,*ptr);
4268   declareAsNew();
4269 }
4270
4271 /*!
4272  * Returns a new DataArrayDouble created from \a this one by applying \a
4273  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4274  * For more info see \ref MEDCouplingArrayApplyFunc
4275  *  \param [in] nbOfComp - number of components in the result array.
4276  *  \param [in] func - the \a FunctionToEvaluate declared as 
4277  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4278  *              where \a pos points to the first component of a tuple of \a this array
4279  *              and \a res points to the first component of a tuple of the result array.
4280  *              Note that length (number of components) of \a pos can differ from
4281  *              that of \a res.
4282  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4283  *          same number of tuples as \a this array.
4284  *          The caller is to delete this result array using decrRef() as it is no more
4285  *          needed.
4286  *  \throw If \a this is not allocated.
4287  *  \throw If \a func returns \a false.
4288  */
4289 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4290 {
4291   checkAllocated();
4292   DataArrayDouble *newArr=DataArrayDouble::New();
4293   int nbOfTuples=getNumberOfTuples();
4294   int oldNbOfComp=getNumberOfComponents();
4295   newArr->alloc(nbOfTuples,nbOfComp);
4296   const double *ptr=getConstPointer();
4297   double *ptrToFill=newArr->getPointer();
4298   for(int i=0;i<nbOfTuples;i++)
4299     {
4300       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4301         {
4302           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4303           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4304           oss << ") : Evaluation of function failed !";
4305           newArr->decrRef();
4306           throw INTERP_KERNEL::Exception(oss.str().c_str());
4307         }
4308     }
4309   return newArr;
4310 }
4311
4312 /*!
4313  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4314  * tuple of \a this array. Textual data is not copied.
4315  * For more info see \ref MEDCouplingArrayApplyFunc1.
4316  *  \param [in] nbOfComp - number of components in the result array.
4317  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4318  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4319  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4320  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4321  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4322  *          same number of tuples as \a this array and \a nbOfComp components.
4323  *          The caller is to delete this result array using decrRef() as it is no more
4324  *          needed.
4325  *  \throw If \a this is not allocated.
4326  *  \throw If computing \a func fails.
4327  */
4328 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4329 {
4330   INTERP_KERNEL::ExprParser expr(func);
4331   expr.parse();
4332   std::set<std::string> vars;
4333   expr.getTrueSetOfVars(vars);
4334   std::vector<std::string> varsV(vars.begin(),vars.end());
4335   return applyFunc3(nbOfComp,varsV,func,isSafe);
4336 }
4337
4338 /*!
4339  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4340  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4341  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4342  *
4343  * For more info see \ref MEDCouplingArrayApplyFunc0.
4344  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4345  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4346  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4347  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4348  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4349  *          same number of tuples and components as \a this array.
4350  *          The caller is to delete this result array using decrRef() as it is no more
4351  *          needed.
4352  *  \sa applyFuncOnThis
4353  *  \throw If \a this is not allocated.
4354  *  \throw If computing \a func fails.
4355  */
4356 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4357 {
4358   int nbOfComp(getNumberOfComponents());
4359   if(nbOfComp<=0)
4360     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4361   checkAllocated();
4362   int nbOfTuples(getNumberOfTuples());
4363   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4364   newArr->alloc(nbOfTuples,nbOfComp);
4365   INTERP_KERNEL::ExprParser expr(func);
4366   expr.parse();
4367   std::set<std::string> vars;
4368   expr.getTrueSetOfVars(vars);
4369   if((int)vars.size()>1)
4370     {
4371       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 : ";
4372       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4373       throw INTERP_KERNEL::Exception(oss.str().c_str());
4374     }
4375   if(vars.empty())
4376     {
4377       expr.prepareFastEvaluator();
4378       newArr->rearrange(1);
4379       newArr->fillWithValue(expr.evaluateDouble());
4380       newArr->rearrange(nbOfComp);
4381       return newArr.retn();
4382     }
4383   std::vector<std::string> vars2(vars.begin(),vars.end());
4384   double buff,*ptrToFill(newArr->getPointer());
4385   const double *ptr(begin());
4386   std::vector<double> stck;
4387   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4388   expr.prepareFastEvaluator();
4389   if(!isSafe)
4390     {
4391       for(int i=0;i<nbOfTuples;i++)
4392         {
4393           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4394             {
4395               buff=*ptr;
4396               expr.evaluateDoubleInternal(stck);
4397               *ptrToFill=stck.back();
4398               stck.pop_back();
4399             }
4400         }
4401     }
4402   else
4403     {
4404       for(int i=0;i<nbOfTuples;i++)
4405         {
4406           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4407             {
4408               buff=*ptr;
4409               try
4410               {
4411                   expr.evaluateDoubleInternalSafe(stck);
4412               }
4413               catch(INTERP_KERNEL::Exception& e)
4414               {
4415                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4416                   oss << buff;
4417                   oss << ") : Evaluation of function failed !" << e.what();
4418                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4419               }
4420               *ptrToFill=stck.back();
4421               stck.pop_back();
4422             }
4423         }
4424     }
4425   return newArr.retn();
4426 }
4427
4428 /*!
4429  * This method is a non const method that modify the array in \a this.
4430  * This method only works on one component array. It means that function \a func must
4431  * contain at most one variable.
4432  * This method is a specialization of applyFunc method with one parameter on one component array.
4433  *
4434  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4435  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4436  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4437  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4438  *
4439  * \sa applyFunc
4440  */
4441 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4442 {
4443   int nbOfComp(getNumberOfComponents());
4444   if(nbOfComp<=0)
4445     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4446   checkAllocated();
4447   int nbOfTuples(getNumberOfTuples());
4448   INTERP_KERNEL::ExprParser expr(func);
4449   expr.parse();
4450   std::set<std::string> vars;
4451   expr.getTrueSetOfVars(vars);
4452   if((int)vars.size()>1)
4453     {
4454       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 : ";
4455       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4456       throw INTERP_KERNEL::Exception(oss.str().c_str());
4457     }
4458   if(vars.empty())
4459     {
4460       expr.prepareFastEvaluator();
4461       std::vector<std::string> compInfo(getInfoOnComponents());
4462       rearrange(1);
4463       fillWithValue(expr.evaluateDouble());
4464       rearrange(nbOfComp);
4465       setInfoOnComponents(compInfo);
4466       return ;
4467     }
4468   std::vector<std::string> vars2(vars.begin(),vars.end());
4469   double buff,*ptrToFill(getPointer());
4470   const double *ptr(begin());
4471   std::vector<double> stck;
4472   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4473   expr.prepareFastEvaluator();
4474   if(!isSafe)
4475     {
4476       for(int i=0;i<nbOfTuples;i++)
4477         {
4478           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4479             {
4480               buff=*ptr;
4481               expr.evaluateDoubleInternal(stck);
4482               *ptrToFill=stck.back();
4483               stck.pop_back();
4484             }
4485         }
4486     }
4487   else
4488     {
4489       for(int i=0;i<nbOfTuples;i++)
4490         {
4491           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4492             {
4493               buff=*ptr;
4494               try
4495               {
4496                   expr.evaluateDoubleInternalSafe(stck);
4497               }
4498               catch(INTERP_KERNEL::Exception& e)
4499               {
4500                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4501                   oss << buff;
4502                   oss << ") : Evaluation of function failed !" << e.what();
4503                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4504               }
4505               *ptrToFill=stck.back();
4506               stck.pop_back();
4507             }
4508         }
4509     }
4510 }
4511
4512 /*!
4513  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4514  * tuple of \a this array. Textual data is not copied.
4515  * For more info see \ref MEDCouplingArrayApplyFunc2.
4516  *  \param [in] nbOfComp - number of components in the result array.
4517  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4518  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4519  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4520  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4521  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4522  *          same number of tuples as \a this array.
4523  *          The caller is to delete this result array using decrRef() as it is no more
4524  *          needed.
4525  *  \throw If \a this is not allocated.
4526  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4527  *  \throw If computing \a func fails.
4528  */
4529 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const
4530 {
4531   return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe);
4532 }
4533
4534 /*!
4535  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4536  * tuple of \a this array. Textual data is not copied.
4537  * For more info see \ref MEDCouplingArrayApplyFunc3.
4538  *  \param [in] nbOfComp - number of components in the result array.
4539  *  \param [in] varsOrder - sequence of vars defining their order.
4540  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4541  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4542  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4543  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4544  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4545  *          same number of tuples as \a this array.
4546  *          The caller is to delete this result array using decrRef() as it is no more
4547  *          needed.
4548  *  \throw If \a this is not allocated.
4549  *  \throw If \a func contains vars not in \a varsOrder.
4550  *  \throw If computing \a func fails.
4551  */
4552 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4553 {
4554   if(nbOfComp<=0)
4555     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !");
4556   std::vector<std::string> varsOrder2(varsOrder);
4557   int oldNbOfComp(getNumberOfComponents());
4558   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4559     varsOrder2.push_back(std::string());
4560   checkAllocated();
4561   int nbOfTuples(getNumberOfTuples());
4562   INTERP_KERNEL::ExprParser expr(func);
4563   expr.parse();
4564   std::set<std::string> vars;
4565   expr.getTrueSetOfVars(vars);
4566   if((int)vars.size()>oldNbOfComp)
4567     {
4568       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4569       oss << vars.size() << " variables : ";
4570       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4571       throw INTERP_KERNEL::Exception(oss.str().c_str());
4572     }
4573   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4574   newArr->alloc(nbOfTuples,nbOfComp);
4575   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4576   double *buffPtr(buff),*ptrToFill;
4577   std::vector<double> stck;
4578   for(int iComp=0;iComp<nbOfComp;iComp++)
4579     {
4580       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4581       expr.prepareFastEvaluator();
4582       const double *ptr(getConstPointer());
4583       ptrToFill=newArr->getPointer()+iComp;
4584       if(!isSafe)
4585         {
4586           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4587             {
4588               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4589               expr.evaluateDoubleInternal(stck);
4590               *ptrToFill=stck.back();
4591               stck.pop_back();
4592             }
4593         }
4594       else
4595         {
4596           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4597             {
4598               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4599               try
4600               {
4601                   expr.evaluateDoubleInternalSafe(stck);
4602                   *ptrToFill=stck.back();
4603                   stck.pop_back();
4604               }
4605               catch(INTERP_KERNEL::Exception& e)
4606               {
4607                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4608                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4609                   oss << ") : Evaluation of function failed !" << e.what();
4610                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4611               }
4612             }
4613         }
4614     }
4615   return newArr.retn();
4616 }
4617
4618 void DataArrayDouble::applyFuncFast32(const std::string& func)
4619 {
4620   checkAllocated();
4621   INTERP_KERNEL::ExprParser expr(func);
4622   expr.parse();
4623   char *funcStr=expr.compileX86();
4624   MYFUNCPTR funcPtr;
4625   *((void **)&funcPtr)=funcStr;//he he...
4626   //
4627   double *ptr=getPointer();
4628   int nbOfComp=getNumberOfComponents();
4629   int nbOfTuples=getNumberOfTuples();
4630   int nbOfElems=nbOfTuples*nbOfComp;
4631   for(int i=0;i<nbOfElems;i++,ptr++)
4632     *ptr=funcPtr(*ptr);
4633   declareAsNew();
4634 }
4635
4636 void DataArrayDouble::applyFuncFast64(const std::string& func)
4637 {
4638   checkAllocated();
4639   INTERP_KERNEL::ExprParser expr(func);
4640   expr.parse();
4641   char *funcStr=expr.compileX86_64();
4642   MYFUNCPTR funcPtr;
4643   *((void **)&funcPtr)=funcStr;//he he...
4644   //
4645   double *ptr=getPointer();
4646   int nbOfComp=getNumberOfComponents();
4647   int nbOfTuples=getNumberOfTuples();
4648   int nbOfElems=nbOfTuples*nbOfComp;
4649   for(int i=0;i<nbOfElems;i++,ptr++)
4650     *ptr=funcPtr(*ptr);
4651   declareAsNew();
4652 }
4653
4654 DataArrayDoubleIterator *DataArrayDouble::iterator()
4655 {
4656   return new DataArrayDoubleIterator(this);
4657 }
4658
4659 /*!
4660  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4661  * array whose values are within a given range. Textual data is not copied.
4662  *  \param [in] vmin - a lowest acceptable value (included).
4663  *  \param [in] vmax - a greatest acceptable value (included).
4664  *  \return DataArrayInt * - the new instance of DataArrayInt.
4665  *          The caller is to delete this result array using decrRef() as it is no more
4666  *          needed.
4667  *  \throw If \a this->getNumberOfComponents() != 1.
4668  *
4669  *  \sa DataArrayDouble::getIdsNotInRange
4670  *
4671  *  \if ENABLE_EXAMPLES
4672  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4673  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4674  *  \endif
4675  */
4676 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4677 {
4678   checkAllocated();
4679   if(getNumberOfComponents()!=1)
4680     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4681   const double *cptr(begin());
4682   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4683   int nbOfTuples(getNumberOfTuples());
4684   for(int i=0;i<nbOfTuples;i++,cptr++)
4685     if(*cptr>=vmin && *cptr<=vmax)
4686       ret->pushBackSilent(i);
4687   return ret.retn();
4688 }
4689
4690 /*!
4691  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4692  * array whose values are not within a given range. Textual data is not copied.
4693  *  \param [in] vmin - a lowest not acceptable value (excluded).
4694  *  \param [in] vmax - a greatest not acceptable value (excluded).
4695  *  \return DataArrayInt * - the new instance of DataArrayInt.
4696  *          The caller is to delete this result array using decrRef() as it is no more
4697  *          needed.
4698  *  \throw If \a this->getNumberOfComponents() != 1.
4699  *
4700  *  \sa DataArrayDouble::getIdsInRange
4701  */
4702 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4703 {
4704   checkAllocated();
4705   if(getNumberOfComponents()!=1)
4706     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4707   const double *cptr(begin());
4708   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4709   int nbOfTuples(getNumberOfTuples());
4710   for(int i=0;i<nbOfTuples;i++,cptr++)
4711     if(*cptr<vmin || *cptr>vmax)
4712       ret->pushBackSilent(i);
4713   return ret.retn();
4714 }
4715
4716 /*!
4717  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4718  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4719  * the number of component in the result array is same as that of each of given arrays.
4720  * Info on components is copied from the first of the given arrays. Number of components
4721  * in the given arrays must be  the same.
4722  *  \param [in] a1 - an array to include in the result array.
4723  *  \param [in] a2 - another array to include in the result array.
4724  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4725  *          The caller is to delete this result array using decrRef() as it is no more
4726  *          needed.
4727  *  \throw If both \a a1 and \a a2 are NULL.
4728  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4729  */
4730 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4731 {
4732   std::vector<const DataArrayDouble *> tmp(2);
4733   tmp[0]=a1; tmp[1]=a2;
4734   return Aggregate(tmp);
4735 }
4736
4737 /*!
4738  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4739  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4740  * the number of component in the result array is same as that of each of given arrays.
4741  * Info on components is copied from the first of the given arrays. Number of components
4742  * in the given arrays must be  the same.
4743  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4744  * not the object itself.
4745  *  \param [in] arr - a sequence of arrays to include in the result array.
4746  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4747  *          The caller is to delete this result array using decrRef() as it is no more
4748  *          needed.
4749  *  \throw If all arrays within \a arr are NULL.
4750  *  \throw If getNumberOfComponents() of arrays within \a arr.
4751  */
4752 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4753 {
4754   std::vector<const DataArrayDouble *> a;
4755   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4756     if(*it4)
4757       a.push_back(*it4);
4758   if(a.empty())
4759     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4760   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4761   int nbOfComp=(*it)->getNumberOfComponents();
4762   int nbt=(*it++)->getNumberOfTuples();
4763   for(int i=1;it!=a.end();it++,i++)
4764     {
4765       if((*it)->getNumberOfComponents()!=nbOfComp)
4766         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4767       nbt+=(*it)->getNumberOfTuples();
4768     }
4769   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4770   ret->alloc(nbt,nbOfComp);
4771   double *pt=ret->getPointer();
4772   for(it=a.begin();it!=a.end();it++)
4773     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4774   ret->copyStringInfoFrom(*(a[0]));
4775   return ret.retn();
4776 }
4777
4778 /*!
4779  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4780  * of components in the result array is a sum of the number of components of given arrays
4781  * and (2) the number of tuples in the result array is same as that of each of given
4782  * arrays. In other words the i-th tuple of result array includes all components of
4783  * i-th tuples of all given arrays.
4784  * Number of tuples in the given arrays must be  the same.
4785  *  \param [in] a1 - an array to include in the result array.
4786  *  \param [in] a2 - another array to include in the result array.
4787  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4788  *          The caller is to delete this result array using decrRef() as it is no more
4789  *          needed.
4790  *  \throw If both \a a1 and \a a2 are NULL.
4791  *  \throw If any given array is not allocated.
4792  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4793  */
4794 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4795 {
4796   std::vector<const DataArrayDouble *> arr(2);
4797   arr[0]=a1; arr[1]=a2;
4798   return Meld(arr);
4799 }
4800
4801 /*!
4802  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4803  * of components in the result array is a sum of the number of components of given arrays
4804  * and (2) the number of tuples in the result array is same as that of each of given
4805  * arrays. In other words the i-th tuple of result array includes all components of
4806  * i-th tuples of all given arrays.
4807  * Number of tuples in the given arrays must be  the same.
4808  *  \param [in] arr - a sequence of arrays to include in the result array.
4809  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4810  *          The caller is to delete this result array using decrRef() as it is no more
4811  *          needed.
4812  *  \throw If all arrays within \a arr are NULL.
4813  *  \throw If any given array is not allocated.
4814  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4815  */
4816 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4817 {
4818   std::vector<const DataArrayDouble *> a;
4819   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4820     if(*it4)
4821       a.push_back(*it4);
4822   if(a.empty())
4823     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4824   std::vector<const DataArrayDouble *>::const_iterator it;
4825   for(it=a.begin();it!=a.end();it++)
4826     (*it)->checkAllocated();
4827   it=a.begin();
4828   int nbOfTuples=(*it)->getNumberOfTuples();
4829   std::vector<int> nbc(a.size());
4830   std::vector<const double *> pts(a.size());
4831   nbc[0]=(*it)->getNumberOfComponents();
4832   pts[0]=(*it++)->getConstPointer();
4833   for(int i=1;it!=a.end();it++,i++)
4834     {
4835       if(nbOfTuples!=(*it)->getNumberOfTuples())
4836         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4837       nbc[i]=(*it)->getNumberOfComponents();
4838       pts[i]=(*it)->getConstPointer();
4839     }
4840   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4841   DataArrayDouble *ret=DataArrayDouble::New();
4842   ret->alloc(nbOfTuples,totalNbOfComp);
4843   double *retPtr=ret->getPointer();
4844   for(int i=0;i<nbOfTuples;i++)
4845     for(int j=0;j<(int)a.size();j++)
4846       {
4847         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4848         pts[j]+=nbc[j];
4849       }
4850   int k=0;
4851   for(int i=0;i<(int)a.size();i++)
4852     for(int j=0;j<nbc[i];j++,k++)
4853       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4854   return ret;
4855 }
4856
4857 /*!
4858  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4859  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4860  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4861  * Info on components and name is copied from the first of the given arrays.
4862  * Number of tuples and components in the given arrays must be the same.
4863  *  \param [in] a1 - a given array.
4864  *  \param [in] a2 - another given array.
4865  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4866  *          The caller is to delete this result array using decrRef() as it is no more
4867  *          needed.
4868  *  \throw If either \a a1 or \a a2 is NULL.
4869  *  \throw If any given array is not allocated.
4870  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4871  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4872  */
4873 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4874 {
4875   if(!a1 || !a2)
4876     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4877   a1->checkAllocated();
4878   a2->checkAllocated();
4879   int nbOfComp=a1->getNumberOfComponents();
4880   if(nbOfComp!=a2->getNumberOfComponents())
4881     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4882   int nbOfTuple=a1->getNumberOfTuples();
4883   if(nbOfTuple!=a2->getNumberOfTuples())
4884     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4885   DataArrayDouble *ret=DataArrayDouble::New();
4886   ret->alloc(nbOfTuple,1);
4887   double *retPtr=ret->getPointer();
4888   const double *a1Ptr=a1->getConstPointer();
4889   const double *a2Ptr=a2->getConstPointer();
4890   for(int i=0;i<nbOfTuple;i++)
4891     {
4892       double sum=0.;
4893       for(int j=0;j<nbOfComp;j++)
4894         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4895       retPtr[i]=sum;
4896     }
4897   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4898   ret->setName(a1->getName());
4899   return ret;
4900 }
4901
4902 /*!
4903  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4904  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4905  * product of two vectors defined by the i-th tuples of given arrays.
4906  * Info on components is copied from the first of the given arrays.
4907  * Number of tuples in the given arrays must be the same.
4908  * Number of components in the given arrays must be 3.
4909  *  \param [in] a1 - a given array.
4910  *  \param [in] a2 - another given array.
4911  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4912  *          The caller is to delete this result array using decrRef() as it is no more
4913  *          needed.
4914  *  \throw If either \a a1 or \a a2 is NULL.
4915  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4916  *  \throw If \a a1->getNumberOfComponents() != 3
4917  *  \throw If \a a2->getNumberOfComponents() != 3
4918  */
4919 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4920 {
4921   if(!a1 || !a2)
4922     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4923   int nbOfComp=a1->getNumberOfComponents();
4924   if(nbOfComp!=a2->getNumberOfComponents())
4925     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4926   if(nbOfComp!=3)
4927     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4928   int nbOfTuple=a1->getNumberOfTuples();
4929   if(nbOfTuple!=a2->getNumberOfTuples())
4930     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4931   DataArrayDouble *ret=DataArrayDouble::New();
4932   ret->alloc(nbOfTuple,3);
4933   double *retPtr=ret->getPointer();
4934   const double *a1Ptr=a1->getConstPointer();
4935   const double *a2Ptr=a2->getConstPointer();
4936   for(int i=0;i<nbOfTuple;i++)
4937     {
4938       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4939       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4940       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4941     }
4942   ret->copyStringInfoFrom(*a1);
4943   return ret;
4944 }
4945
4946 /*!
4947  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4948  * Info on components is copied from the first of the given arrays.
4949  * Number of tuples and components in the given arrays must be the same.
4950  *  \param [in] a1 - an array to compare values with another one.
4951  *  \param [in] a2 - another array to compare values with the first one.
4952  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4953  *          The caller is to delete this result array using decrRef() as it is no more
4954  *          needed.
4955  *  \throw If either \a a1 or \a a2 is NULL.
4956  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4957  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4958  */
4959 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4960 {
4961   if(!a1 || !a2)
4962     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4963   int nbOfComp=a1->getNumberOfComponents();
4964   if(nbOfComp!=a2->getNumberOfComponents())
4965     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4966   int nbOfTuple=a1->getNumberOfTuples();
4967   if(nbOfTuple!=a2->getNumberOfTuples())
4968     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4969   DataArrayDouble *ret=DataArrayDouble::New();
4970   ret->alloc(nbOfTuple,nbOfComp);
4971   double *retPtr=ret->getPointer();
4972   const double *a1Ptr=a1->getConstPointer();
4973   const double *a2Ptr=a2->getConstPointer();
4974   int nbElem=nbOfTuple*nbOfComp;
4975   for(int i=0;i<nbElem;i++)
4976     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4977   ret->copyStringInfoFrom(*a1);
4978   return ret;
4979 }
4980
4981 /*!
4982  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4983  * Info on components is copied from the first of the given arrays.
4984  * Number of tuples and components in the given arrays must be the same.
4985  *  \param [in] a1 - an array to compare values with another one.
4986  *  \param [in] a2 - another array to compare values with the first one.
4987  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4988  *          The caller is to delete this result array using decrRef() as it is no more
4989  *          needed.
4990  *  \throw If either \a a1 or \a a2 is NULL.
4991  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4992  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4993  */
4994 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4995 {
4996   if(!a1 || !a2)
4997     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4998   int nbOfComp=a1->getNumberOfComponents();
4999   if(nbOfComp!=a2->getNumberOfComponents())
5000     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5001   int nbOfTuple=a1->getNumberOfTuples();
5002   if(nbOfTuple!=a2->getNumberOfTuples())
5003     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5004   DataArrayDouble *ret=DataArrayDouble::New();
5005   ret->alloc(nbOfTuple,nbOfComp);
5006   double *retPtr=ret->getPointer();
5007   const double *a1Ptr=a1->getConstPointer();
5008   const double *a2Ptr=a2->getConstPointer();
5009   int nbElem=nbOfTuple*nbOfComp;
5010   for(int i=0;i<nbElem;i++)
5011     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5012   ret->copyStringInfoFrom(*a1);
5013   return ret;
5014 }
5015
5016 /*!
5017  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5018  * valid cases.
5019  * 1.  The arrays have same number of tuples and components. Then each value of
5020  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5021  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5022  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5023  *   component. Then
5024  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5025  * 3.  The arrays have same number of components and one array, say _a2_, has one
5026  *   tuple. Then
5027  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5028  *
5029  * Info on components is copied either from the first array (in the first case) or from
5030  * the array with maximal number of elements (getNbOfElems()).
5031  *  \param [in] a1 - an array to sum up.
5032  *  \param [in] a2 - another array to sum up.
5033  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5034  *          The caller is to delete this result array using decrRef() as it is no more
5035  *          needed.
5036  *  \throw If either \a a1 or \a a2 is NULL.
5037  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5038  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5039  *         none of them has number of tuples or components equal to 1.
5040  */
5041 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5042 {
5043   if(!a1 || !a2)
5044     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5045   int nbOfTuple=a1->getNumberOfTuples();
5046   int nbOfTuple2=a2->getNumberOfTuples();
5047   int nbOfComp=a1->getNumberOfComponents();
5048   int nbOfComp2=a2->getNumberOfComponents();
5049   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5050   if(nbOfTuple==nbOfTuple2)
5051     {
5052       if(nbOfComp==nbOfComp2)
5053         {
5054           ret=DataArrayDouble::New();
5055           ret->alloc(nbOfTuple,nbOfComp);
5056           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5057           ret->copyStringInfoFrom(*a1);
5058         }
5059       else
5060         {
5061           int nbOfCompMin,nbOfCompMax;
5062           const DataArrayDouble *aMin, *aMax;
5063           if(nbOfComp>nbOfComp2)
5064             {
5065               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5066               aMin=a2; aMax=a1;
5067             }
5068           else
5069             {
5070               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5071               aMin=a1; aMax=a2;
5072             }
5073           if(nbOfCompMin==1)
5074             {
5075               ret=DataArrayDouble::New();
5076               ret->alloc(nbOfTuple,nbOfCompMax);
5077               const double *aMinPtr=aMin->getConstPointer();
5078               const double *aMaxPtr=aMax->getConstPointer();
5079               double *res=ret->getPointer();
5080               for(int i=0;i<nbOfTuple;i++)
5081                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5082               ret->copyStringInfoFrom(*aMax);
5083             }
5084           else
5085             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5086         }
5087     }
5088   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5089     {
5090       if(nbOfComp==nbOfComp2)
5091         {
5092           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5093           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5094           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5095           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5096           ret=DataArrayDouble::New();
5097           ret->alloc(nbOfTupleMax,nbOfComp);
5098           double *res=ret->getPointer();
5099           for(int i=0;i<nbOfTupleMax;i++)
5100             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5101           ret->copyStringInfoFrom(*aMax);
5102         }
5103       else
5104         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5105     }
5106   else
5107     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5108   return ret.retn();
5109 }
5110
5111 /*!
5112  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5113  * valid cases.
5114  * 1.  The arrays have same number of tuples and components. Then each value of
5115  *   \a other array is added to the corresponding value of \a this array, i.e.:
5116  *   _a_ [ i, j ] += _other_ [ i, j ].
5117  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5118  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5119  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5120  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5121  *
5122  *  \param [in] other - an array to add to \a this one.
5123  *  \throw If \a other is NULL.
5124  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5125  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5126  *         \a other has number of both tuples and components not equal to 1.
5127  */
5128 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5129 {
5130   if(!other)
5131     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5132   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5133   checkAllocated();
5134   other->checkAllocated();
5135   int nbOfTuple=getNumberOfTuples();
5136   int nbOfTuple2=other->getNumberOfTuples();
5137   int nbOfComp=getNumberOfComponents();
5138   int nbOfComp2=other->getNumberOfComponents();
5139   if(nbOfTuple==nbOfTuple2)
5140     {
5141       if(nbOfComp==nbOfComp2)
5142         {
5143           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5144         }
5145       else if(nbOfComp2==1)
5146         {
5147           double *ptr=getPointer();
5148           const double *ptrc=other->getConstPointer();
5149           for(int i=0;i<nbOfTuple;i++)
5150             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5151         }
5152       else
5153         throw INTERP_KERNEL::Exception(msg);
5154     }
5155   else if(nbOfTuple2==1)
5156     {
5157       if(nbOfComp2==nbOfComp)
5158         {
5159           double *ptr=getPointer();
5160           const double *ptrc=other->getConstPointer();
5161           for(int i=0;i<nbOfTuple;i++)
5162             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5163         }
5164       else
5165         throw INTERP_KERNEL::Exception(msg);
5166     }
5167   else
5168     throw INTERP_KERNEL::Exception(msg);
5169   declareAsNew();
5170 }
5171
5172 /*!
5173  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5174  * valid cases.
5175  * 1.  The arrays have same number of tuples and components. Then each value of
5176  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5177  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5178  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5179  *   component. Then
5180  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5181  * 3.  The arrays have same number of components and one array, say _a2_, has one
5182  *   tuple. Then
5183  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5184  *
5185  * Info on components is copied either from the first array (in the first case) or from
5186  * the array with maximal number of elements (getNbOfElems()).
5187  *  \param [in] a1 - an array to subtract from.
5188  *  \param [in] a2 - an array to subtract.
5189  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5190  *          The caller is to delete this result array using decrRef() as it is no more
5191  *          needed.
5192  *  \throw If either \a a1 or \a a2 is NULL.
5193  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5194  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5195  *         none of them has number of tuples or components equal to 1.
5196  */
5197 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5198 {
5199   if(!a1 || !a2)
5200     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5201   int nbOfTuple1=a1->getNumberOfTuples();
5202   int nbOfTuple2=a2->getNumberOfTuples();
5203   int nbOfComp1=a1->getNumberOfComponents();
5204   int nbOfComp2=a2->getNumberOfComponents();
5205   if(nbOfTuple2==nbOfTuple1)
5206     {
5207       if(nbOfComp1==nbOfComp2)
5208         {
5209           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5210           ret->alloc(nbOfTuple2,nbOfComp1);
5211           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5212           ret->copyStringInfoFrom(*a1);
5213           return ret.retn();
5214         }
5215       else if(nbOfComp2==1)
5216         {
5217           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5218           ret->alloc(nbOfTuple1,nbOfComp1);
5219           const double *a2Ptr=a2->getConstPointer();
5220           const double *a1Ptr=a1->getConstPointer();
5221           double *res=ret->getPointer();
5222           for(int i=0;i<nbOfTuple1;i++)
5223             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5224           ret->copyStringInfoFrom(*a1);
5225           return ret.retn();
5226         }
5227       else
5228         {
5229           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5230           return 0;
5231         }
5232     }
5233   else if(nbOfTuple2==1)
5234     {
5235       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5236       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5237       ret->alloc(nbOfTuple1,nbOfComp1);
5238       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5239       double *pt=ret->getPointer();
5240       for(int i=0;i<nbOfTuple1;i++)
5241         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5242       ret->copyStringInfoFrom(*a1);
5243       return ret.retn();
5244     }
5245   else
5246     {
5247       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5248       return 0;
5249     }
5250 }
5251
5252 /*!
5253  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5254  * valid cases.
5255  * 1.  The arrays have same number of tuples and components. Then each value of
5256  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5257  *   _a_ [ i, j ] -= _other_ [ i, j ].
5258  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5259  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5260  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5261  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5262  *
5263  *  \param [in] other - an array to subtract from \a this one.
5264  *  \throw If \a other is NULL.
5265  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5266  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5267  *         \a other has number of both tuples and components not equal to 1.
5268  */
5269 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5270 {
5271   if(!other)
5272     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5273   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5274   checkAllocated();
5275   other->checkAllocated();
5276   int nbOfTuple=getNumberOfTuples();
5277   int nbOfTuple2=other->getNumberOfTuples();
5278   int nbOfComp=getNumberOfComponents();
5279   int nbOfComp2=other->getNumberOfComponents();
5280   if(nbOfTuple==nbOfTuple2)
5281     {
5282       if(nbOfComp==nbOfComp2)
5283         {
5284           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5285         }
5286       else if(nbOfComp2==1)
5287         {
5288           double *ptr=getPointer();
5289           const double *ptrc=other->getConstPointer();
5290           for(int i=0;i<nbOfTuple;i++)
5291             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5292         }
5293       else
5294         throw INTERP_KERNEL::Exception(msg);
5295     }
5296   else if(nbOfTuple2==1)
5297     {
5298       if(nbOfComp2==nbOfComp)
5299         {
5300           double *ptr=getPointer();
5301           const double *ptrc=other->getConstPointer();
5302           for(int i=0;i<nbOfTuple;i++)
5303             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5304         }
5305       else
5306         throw INTERP_KERNEL::Exception(msg);
5307     }
5308   else
5309     throw INTERP_KERNEL::Exception(msg);
5310   declareAsNew();
5311 }
5312
5313 /*!
5314  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5315  * valid cases.
5316  * 1.  The arrays have same number of tuples and components. Then each value of
5317  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5318  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5319  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5320  *   component. Then
5321  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5322  * 3.  The arrays have same number of components and one array, say _a2_, has one
5323  *   tuple. Then
5324  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5325  *
5326  * Info on components is copied either from the first array (in the first case) or from
5327  * the array with maximal number of elements (getNbOfElems()).
5328  *  \param [in] a1 - a factor array.
5329  *  \param [in] a2 - another factor array.
5330  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5331  *          The caller is to delete this result array using decrRef() as it is no more
5332  *          needed.
5333  *  \throw If either \a a1 or \a a2 is NULL.
5334  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5335  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5336  *         none of them has number of tuples or components equal to 1.
5337  */
5338 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5339 {
5340   if(!a1 || !a2)
5341     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5342   int nbOfTuple=a1->getNumberOfTuples();
5343   int nbOfTuple2=a2->getNumberOfTuples();
5344   int nbOfComp=a1->getNumberOfComponents();
5345   int nbOfComp2=a2->getNumberOfComponents();
5346   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5347   if(nbOfTuple==nbOfTuple2)
5348     {
5349       if(nbOfComp==nbOfComp2)
5350         {
5351           ret=DataArrayDouble::New();
5352           ret->alloc(nbOfTuple,nbOfComp);
5353           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5354           ret->copyStringInfoFrom(*a1);
5355         }
5356       else
5357         {
5358           int nbOfCompMin,nbOfCompMax;
5359           const DataArrayDouble *aMin, *aMax;
5360           if(nbOfComp>nbOfComp2)
5361             {
5362               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5363               aMin=a2; aMax=a1;
5364             }
5365           else
5366             {
5367               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5368               aMin=a1; aMax=a2;
5369             }
5370           if(nbOfCompMin==1)
5371             {
5372               ret=DataArrayDouble::New();
5373               ret->alloc(nbOfTuple,nbOfCompMax);
5374               const double *aMinPtr=aMin->getConstPointer();
5375               const double *aMaxPtr=aMax->getConstPointer();
5376               double *res=ret->getPointer();
5377               for(int i=0;i<nbOfTuple;i++)
5378                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5379               ret->copyStringInfoFrom(*aMax);
5380             }
5381           else
5382             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5383         }
5384     }
5385   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5386     {
5387       if(nbOfComp==nbOfComp2)
5388         {
5389           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5390           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5391           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5392           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5393           ret=DataArrayDouble::New();
5394           ret->alloc(nbOfTupleMax,nbOfComp);
5395           double *res=ret->getPointer();
5396           for(int i=0;i<nbOfTupleMax;i++)
5397             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5398           ret->copyStringInfoFrom(*aMax);
5399         }
5400       else
5401         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5402     }
5403   else
5404     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5405   return ret.retn();
5406 }
5407
5408 /*!
5409  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5410  * valid cases.
5411  * 1.  The arrays have same number of tuples and components. Then each value of
5412  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5413  *   _this_ [ i, j ] *= _other_ [ i, j ].
5414  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5415  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5416  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5417  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5418  *
5419  *  \param [in] other - an array to multiply to \a this one.
5420  *  \throw If \a other is NULL.
5421  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5422  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5423  *         \a other has number of both tuples and components not equal to 1.
5424  */
5425 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5426 {
5427   if(!other)
5428     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5429   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5430   checkAllocated();
5431   other->checkAllocated();
5432   int nbOfTuple=getNumberOfTuples();
5433   int nbOfTuple2=other->getNumberOfTuples();
5434   int nbOfComp=getNumberOfComponents();
5435   int nbOfComp2=other->getNumberOfComponents();
5436   if(nbOfTuple==nbOfTuple2)
5437     {
5438       if(nbOfComp==nbOfComp2)
5439         {
5440           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5441         }
5442       else if(nbOfComp2==1)
5443         {
5444           double *ptr=getPointer();
5445           const double *ptrc=other->getConstPointer();
5446           for(int i=0;i<nbOfTuple;i++)
5447             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5448         }
5449       else
5450         throw INTERP_KERNEL::Exception(msg);
5451     }
5452   else if(nbOfTuple2==1)
5453     {
5454       if(nbOfComp2==nbOfComp)
5455         {
5456           double *ptr=getPointer();
5457           const double *ptrc=other->getConstPointer();
5458           for(int i=0;i<nbOfTuple;i++)
5459             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5460         }
5461       else
5462         throw INTERP_KERNEL::Exception(msg);
5463     }
5464   else
5465     throw INTERP_KERNEL::Exception(msg);
5466   declareAsNew();
5467 }
5468
5469 /*!
5470  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5471  * valid cases.
5472  * 1.  The arrays have same number of tuples and components. Then each value of
5473  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5474  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5475  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5476  *   component. Then
5477  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5478  * 3.  The arrays have same number of components and one array, say _a2_, has one
5479  *   tuple. Then
5480  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5481  *
5482  * Info on components is copied either from the first array (in the first case) or from
5483  * the array with maximal number of elements (getNbOfElems()).
5484  *  \warning No check of division by zero is performed!
5485  *  \param [in] a1 - a numerator array.
5486  *  \param [in] a2 - a denominator array.
5487  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5488  *          The caller is to delete this result array using decrRef() as it is no more
5489  *          needed.
5490  *  \throw If either \a a1 or \a a2 is NULL.
5491  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5492  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5493  *         none of them has number of tuples or components equal to 1.
5494  */
5495 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5496 {
5497   if(!a1 || !a2)
5498     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5499   int nbOfTuple1=a1->getNumberOfTuples();
5500   int nbOfTuple2=a2->getNumberOfTuples();
5501   int nbOfComp1=a1->getNumberOfComponents();
5502   int nbOfComp2=a2->getNumberOfComponents();
5503   if(nbOfTuple2==nbOfTuple1)
5504     {
5505       if(nbOfComp1==nbOfComp2)
5506         {
5507           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5508           ret->alloc(nbOfTuple2,nbOfComp1);
5509           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5510           ret->copyStringInfoFrom(*a1);
5511           return ret.retn();
5512         }
5513       else if(nbOfComp2==1)
5514         {
5515           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5516           ret->alloc(nbOfTuple1,nbOfComp1);
5517           const double *a2Ptr=a2->getConstPointer();
5518           const double *a1Ptr=a1->getConstPointer();
5519           double *res=ret->getPointer();
5520           for(int i=0;i<nbOfTuple1;i++)
5521             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5522           ret->copyStringInfoFrom(*a1);
5523           return ret.retn();
5524         }
5525       else
5526         {
5527           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5528           return 0;
5529         }
5530     }
5531   else if(nbOfTuple2==1)
5532     {
5533       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5534       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5535       ret->alloc(nbOfTuple1,nbOfComp1);
5536       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5537       double *pt=ret->getPointer();
5538       for(int i=0;i<nbOfTuple1;i++)
5539         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5540       ret->copyStringInfoFrom(*a1);
5541       return ret.retn();
5542     }
5543   else
5544     {
5545       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5546       return 0;
5547     }
5548 }
5549
5550 /*!
5551  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5552  * valid cases.
5553  * 1.  The arrays have same number of tuples and components. Then each value of
5554  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5555  *   _a_ [ i, j ] /= _other_ [ i, j ].
5556  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5557  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5558  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5559  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5560  *
5561  *  \warning No check of division by zero is performed!
5562  *  \param [in] other - an array to divide \a this one by.
5563  *  \throw If \a other is NULL.
5564  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5565  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5566  *         \a other has number of both tuples and components not equal to 1.
5567  */
5568 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5569 {
5570   if(!other)
5571     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5572   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5573   checkAllocated();
5574   other->checkAllocated();
5575   int nbOfTuple=getNumberOfTuples();
5576   int nbOfTuple2=other->getNumberOfTuples();
5577   int nbOfComp=getNumberOfComponents();
5578   int nbOfComp2=other->getNumberOfComponents();
5579   if(nbOfTuple==nbOfTuple2)
5580     {
5581       if(nbOfComp==nbOfComp2)
5582         {
5583           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5584         }
5585       else if(nbOfComp2==1)
5586         {
5587           double *ptr=getPointer();
5588           const double *ptrc=other->getConstPointer();
5589           for(int i=0;i<nbOfTuple;i++)
5590             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5591         }
5592       else
5593         throw INTERP_KERNEL::Exception(msg);
5594     }
5595   else if(nbOfTuple2==1)
5596     {
5597       if(nbOfComp2==nbOfComp)
5598         {
5599           double *ptr=getPointer();
5600           const double *ptrc=other->getConstPointer();
5601           for(int i=0;i<nbOfTuple;i++)
5602             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5603         }
5604       else
5605         throw INTERP_KERNEL::Exception(msg);
5606     }
5607   else
5608     throw INTERP_KERNEL::Exception(msg);
5609   declareAsNew();
5610 }
5611
5612 /*!
5613  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5614  * valid cases.
5615  *
5616  *  \param [in] a1 - an array to pow up.
5617  *  \param [in] a2 - another array to sum up.
5618  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5619  *          The caller is to delete this result array using decrRef() as it is no more
5620  *          needed.
5621  *  \throw If either \a a1 or \a a2 is NULL.
5622  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5623  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5624  *  \throw If there is a negative value in \a a1.
5625  */
5626 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5627 {
5628   if(!a1 || !a2)
5629     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5630   int nbOfTuple=a1->getNumberOfTuples();
5631   int nbOfTuple2=a2->getNumberOfTuples();
5632   int nbOfComp=a1->getNumberOfComponents();
5633   int nbOfComp2=a2->getNumberOfComponents();
5634   if(nbOfTuple!=nbOfTuple2)
5635     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5636   if(nbOfComp!=1 || nbOfComp2!=1)
5637     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5638   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5639   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5640   double *ptr=ret->getPointer();
5641   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5642     {
5643       if(*ptr1>=0)
5644         {
5645           *ptr=pow(*ptr1,*ptr2);
5646         }
5647       else
5648         {
5649           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5650           throw INTERP_KERNEL::Exception(oss.str().c_str());
5651         }
5652     }
5653   return ret.retn();
5654 }
5655
5656 /*!
5657  * Apply pow on values of another DataArrayDouble to values of \a this one.
5658  *
5659  *  \param [in] other - an array to pow to \a this one.
5660  *  \throw If \a other is NULL.
5661  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5662  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5663  *  \throw If there is a negative value in \a this.
5664  */
5665 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5666 {
5667   if(!other)
5668     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5669   int nbOfTuple=getNumberOfTuples();
5670   int nbOfTuple2=other->getNumberOfTuples();
5671   int nbOfComp=getNumberOfComponents();
5672   int nbOfComp2=other->getNumberOfComponents();
5673   if(nbOfTuple!=nbOfTuple2)
5674     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5675   if(nbOfComp!=1 || nbOfComp2!=1)
5676     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5677   double *ptr=getPointer();
5678   const double *ptrc=other->begin();
5679   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5680     {
5681       if(*ptr>=0)
5682         *ptr=pow(*ptr,*ptrc);
5683       else
5684         {
5685           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5686           throw INTERP_KERNEL::Exception(oss.str().c_str());
5687         }
5688     }
5689   declareAsNew();
5690 }
5691
5692 /*!
5693  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5694  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5695  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5696  *
5697  * \throw if \a this is not allocated.
5698  * \throw if \a this has not exactly one component.
5699  */
5700 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5701 {
5702   checkAllocated();
5703   if(getNumberOfComponents()!=1)
5704     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5705   int nbt(getNumberOfTuples());
5706   std::vector<bool> ret(nbt);
5707   const double *pt(begin());
5708   for(int i=0;i<nbt;i++)
5709     {
5710       if(fabs(pt[i])<eps)
5711         ret[i]=false;
5712       else if(fabs(pt[i]-1.)<eps)
5713         ret[i]=true;
5714       else
5715         {
5716           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5717           throw INTERP_KERNEL::Exception(oss.str().c_str());
5718         }
5719     }
5720   return ret;
5721 }
5722
5723 /*!
5724  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5725  * Server side.
5726  */
5727 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5728 {
5729   tinyInfo.resize(2);
5730   if(isAllocated())
5731     {
5732       tinyInfo[0]=getNumberOfTuples();
5733       tinyInfo[1]=getNumberOfComponents();
5734     }
5735   else
5736     {
5737       tinyInfo[0]=-1;
5738       tinyInfo[1]=-1;
5739     }
5740 }
5741
5742 /*!
5743  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5744  * Server side.
5745  */
5746 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5747 {
5748   if(isAllocated())
5749     {
5750       int nbOfCompo=getNumberOfComponents();
5751       tinyInfo.resize(nbOfCompo+1);
5752       tinyInfo[0]=getName();
5753       for(int i=0;i<nbOfCompo;i++)
5754         tinyInfo[i+1]=getInfoOnComponent(i);
5755     }
5756   else
5757     {
5758       tinyInfo.resize(1);
5759       tinyInfo[0]=getName();
5760     }
5761 }
5762
5763 /*!
5764  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5765  * This method returns if a feeding is needed.
5766  */
5767 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5768 {
5769   int nbOfTuple=tinyInfoI[0];
5770   int nbOfComp=tinyInfoI[1];
5771   if(nbOfTuple!=-1 || nbOfComp!=-1)
5772     {
5773       alloc(nbOfTuple,nbOfComp);
5774       return true;
5775     }
5776   return false;
5777 }
5778
5779 /*!
5780  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5781  */
5782 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5783 {
5784   setName(tinyInfoS[0]);
5785   if(isAllocated())
5786     {
5787       int nbOfCompo=getNumberOfComponents();
5788       for(int i=0;i<nbOfCompo;i++)
5789         setInfoOnComponent(i,tinyInfoS[i+1]);
5790     }
5791 }
5792
5793 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5794 {
5795   if(_da)
5796     {
5797       _da->incrRef();
5798       if(_da->isAllocated())
5799         {
5800           _nb_comp=da->getNumberOfComponents();
5801           _nb_tuple=da->getNumberOfTuples();
5802           _pt=da->getPointer();
5803         }
5804     }
5805 }
5806
5807 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5808 {
5809   if(_da)
5810     _da->decrRef();
5811 }
5812
5813 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5814 {
5815   if(_tuple_id<_nb_tuple)
5816     {
5817       _tuple_id++;
5818       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5819       _pt+=_nb_comp;
5820       return ret;
5821     }
5822   else
5823     return 0;
5824 }
5825
5826 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5827 {
5828 }
5829
5830
5831 std::string DataArrayDoubleTuple::repr() const
5832 {
5833   std::ostringstream oss; oss.precision(17); oss << "(";
5834   for(int i=0;i<_nb_of_compo-1;i++)
5835     oss << _pt[i] << ", ";
5836   oss << _pt[_nb_of_compo-1] << ")";
5837   return oss.str();
5838 }
5839
5840 double DataArrayDoubleTuple::doubleValue() const
5841 {
5842   if(_nb_of_compo==1)
5843     return *_pt;
5844   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5845 }
5846
5847 /*!
5848  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5849  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5850  * 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
5851  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5852  */
5853 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5854 {
5855   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5856     {
5857       DataArrayDouble *ret=DataArrayDouble::New();
5858       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5859       return ret;
5860     }
5861   else
5862     {
5863       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5864       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5865       throw INTERP_KERNEL::Exception(oss.str().c_str());
5866     }
5867 }
5868
5869 /*!
5870  * Returns a new instance of DataArrayInt. The caller is to delete this array
5871  * using decrRef() as it is no more needed. 
5872  */
5873 DataArrayInt *DataArrayInt::New()
5874 {
5875   return new DataArrayInt;
5876 }
5877
5878 /*!
5879  * Checks if raw data is allocated. Read more on the raw data
5880  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5881  *  \return bool - \a true if the raw data is allocated, \a false else.
5882  */
5883 bool DataArrayInt::isAllocated() const
5884 {
5885   return getConstPointer()!=0;
5886 }
5887
5888 /*!
5889  * Checks if raw data is allocated and throws an exception if it is not the case.
5890  *  \throw If the raw data is not allocated.
5891  */
5892 void DataArrayInt::checkAllocated() const
5893 {
5894   if(!isAllocated())
5895     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5896 }
5897
5898 /*!
5899  * This method desallocated \a this without modification of informations relative to the components.
5900  * After call of this method, DataArrayInt::isAllocated will return false.
5901  * If \a this is already not allocated, \a this is let unchanged.
5902  */
5903 void DataArrayInt::desallocate()
5904 {
5905   _mem.destroy();
5906 }
5907
5908 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5909 {
5910   std::size_t sz(_mem.getNbOfElemAllocated());
5911   sz*=sizeof(int);
5912   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5913 }
5914
5915 /*!
5916  * Returns the only one value in \a this, if and only if number of elements
5917  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5918  *  \return double - the sole value stored in \a this array.
5919  *  \throw If at least one of conditions stated above is not fulfilled.
5920  */
5921 int DataArrayInt::intValue() const
5922 {
5923   if(isAllocated())
5924     {
5925       if(getNbOfElems()==1)
5926         {
5927           return *getConstPointer();
5928         }
5929       else
5930         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5931     }
5932   else
5933     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5934 }
5935
5936 /*!
5937  * Returns an integer value characterizing \a this array, which is useful for a quick
5938  * comparison of many instances of DataArrayInt.
5939  *  \return int - the hash value.
5940  *  \throw If \a this is not allocated.
5941  */
5942 int DataArrayInt::getHashCode() const
5943 {
5944   checkAllocated();
5945   std::size_t nbOfElems=getNbOfElems();
5946   int ret=nbOfElems*65536;
5947   int delta=3;
5948   if(nbOfElems>48)
5949     delta=nbOfElems/8;
5950   int ret0=0;
5951   const int *pt=begin();
5952   for(std::size_t i=0;i<nbOfElems;i+=delta)
5953     ret0+=pt[i] & 0x1FFF;
5954   return ret+ret0;
5955 }
5956
5957 /*!
5958  * Checks the number of tuples.
5959  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5960  *  \throw If \a this is not allocated.
5961  */
5962 bool DataArrayInt::empty() const
5963 {
5964   checkAllocated();
5965   return getNumberOfTuples()==0;
5966 }
5967
5968 /*!
5969  * Returns a full copy of \a this. For more info on copying data arrays see
5970  * \ref MEDCouplingArrayBasicsCopyDeep.
5971  *  \return DataArrayInt * - a new instance of DataArrayInt.
5972  */
5973 DataArrayInt *DataArrayInt::deepCpy() const
5974 {
5975   return new DataArrayInt(*this);
5976 }
5977
5978 /*!
5979  * Returns either a \a deep or \a shallow copy of this array. For more info see
5980  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5981  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5982  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5983  *          == \a true) or \a this instance (if \a dCpy == \a false).
5984  */
5985 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5986 {
5987   if(dCpy)
5988     return deepCpy();
5989   else
5990     {
5991       incrRef();
5992       return const_cast<DataArrayInt *>(this);
5993     }
5994 }
5995
5996 /*!
5997  * Copies all the data from another DataArrayInt. For more info see
5998  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5999  *  \param [in] other - another instance of DataArrayInt to copy data from.
6000  *  \throw If the \a other is not allocated.
6001  */
6002 void DataArrayInt::cpyFrom(const DataArrayInt& other)
6003 {
6004   other.checkAllocated();
6005   int nbOfTuples=other.getNumberOfTuples();
6006   int nbOfComp=other.getNumberOfComponents();
6007   allocIfNecessary(nbOfTuples,nbOfComp);
6008   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6009   int *pt=getPointer();
6010   const int *ptI=other.getConstPointer();
6011   for(std::size_t i=0;i<nbOfElems;i++)
6012     pt[i]=ptI[i];
6013   copyStringInfoFrom(other);
6014 }
6015
6016 /*!
6017  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6018  * 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.
6019  * If \a this has not already been allocated, number of components is set to one.
6020  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6021  * 
6022  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6023  */
6024 void DataArrayInt::reserve(std::size_t nbOfElems)
6025 {
6026   int nbCompo=getNumberOfComponents();
6027   if(nbCompo==1)
6028     {
6029       _mem.reserve(nbOfElems);
6030     }
6031   else if(nbCompo==0)
6032     {
6033       _mem.reserve(nbOfElems);
6034       _info_on_compo.resize(1);
6035     }
6036   else
6037     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6038 }
6039
6040 /*!
6041  * 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
6042  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6043  *
6044  * \param [in] val the value to be added in \a this
6045  * \throw If \a this has already been allocated with number of components different from one.
6046  * \sa DataArrayInt::pushBackValsSilent
6047  */
6048 void DataArrayInt::pushBackSilent(int val)
6049 {
6050   int nbCompo=getNumberOfComponents();
6051   if(nbCompo==1)
6052     _mem.pushBack(val);
6053   else if(nbCompo==0)
6054     {
6055       _info_on_compo.resize(1);
6056       _mem.pushBack(val);
6057     }
6058   else
6059     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6060 }
6061
6062 /*!
6063  * 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
6064  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6065  *
6066  *  \param [in] valsBg - an array of values to push at the end of \this.
6067  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6068  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6069  * \throw If \a this has already been allocated with number of components different from one.
6070  * \sa DataArrayInt::pushBackSilent
6071  */
6072 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6073 {
6074   int nbCompo=getNumberOfComponents();
6075   if(nbCompo==1)
6076     _mem.insertAtTheEnd(valsBg,valsEnd);
6077   else if(nbCompo==0)
6078     {
6079       _info_on_compo.resize(1);
6080       _mem.insertAtTheEnd(valsBg,valsEnd);
6081     }
6082   else
6083     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6084 }
6085
6086 /*!
6087  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6088  * \throw If \a this is already empty.
6089  * \throw If \a this has number of components different from one.
6090  */
6091 int DataArrayInt::popBackSilent()
6092 {
6093   if(getNumberOfComponents()==1)
6094     return _mem.popBack();
6095   else
6096     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6097 }
6098
6099 /*!
6100  * 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.
6101  *
6102  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6103  */
6104 void DataArrayInt::pack() const
6105 {
6106   _mem.pack();
6107 }
6108
6109 /*!
6110  * Allocates the raw data in memory. If exactly as same memory as needed already
6111  * allocated, it is not re-allocated.
6112  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6113  *  \param [in] nbOfCompo - number of components of data to allocate.
6114  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6115  */
6116 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6117 {
6118   if(isAllocated())
6119     {
6120       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6121         alloc(nbOfTuple,nbOfCompo);
6122     }
6123   else
6124     alloc(nbOfTuple,nbOfCompo);
6125 }
6126
6127 /*!
6128  * Allocates the raw data in memory. If the memory was already allocated, then it is
6129  * freed and re-allocated. See an example of this method use
6130  * \ref MEDCouplingArraySteps1WC "here".
6131  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6132  *  \param [in] nbOfCompo - number of components of data to allocate.
6133  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6134  */
6135 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6136 {
6137   if(nbOfTuple<0 || nbOfCompo<0)
6138     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6139   _info_on_compo.resize(nbOfCompo);
6140   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6141   declareAsNew();
6142 }
6143
6144 /*!
6145  * Assign zero to all values in \a this array. To know more on filling arrays see
6146  * \ref MEDCouplingArrayFill.
6147  * \throw If \a this is not allocated.
6148  */
6149 void DataArrayInt::fillWithZero()
6150 {
6151   checkAllocated();
6152   _mem.fillWithValue(0);
6153   declareAsNew();
6154 }
6155
6156 /*!
6157  * Assign \a val to all values in \a this array. To know more on filling arrays see
6158  * \ref MEDCouplingArrayFill.
6159  *  \param [in] val - the value to fill with.
6160  *  \throw If \a this is not allocated.
6161  */
6162 void DataArrayInt::fillWithValue(int val)
6163 {
6164   checkAllocated();
6165   _mem.fillWithValue(val);
6166   declareAsNew();
6167 }
6168
6169 /*!
6170  * Set all values in \a this array so that the i-th element equals to \a init + i
6171  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6172  *  \param [in] init - value to assign to the first element of array.
6173  *  \throw If \a this->getNumberOfComponents() != 1
6174  *  \throw If \a this is not allocated.
6175  */
6176 void DataArrayInt::iota(int init)
6177 {
6178   checkAllocated();
6179   if(getNumberOfComponents()!=1)
6180     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6181   int *ptr=getPointer();
6182   int ntuples=getNumberOfTuples();
6183   for(int i=0;i<ntuples;i++)
6184     ptr[i]=init+i;
6185   declareAsNew();
6186 }
6187
6188 /*!
6189  * Returns a textual and human readable representation of \a this instance of
6190  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6191  *  \return std::string - text describing \a this DataArrayInt.
6192  */
6193 std::string DataArrayInt::repr() const
6194 {
6195   std::ostringstream ret;
6196   reprStream(ret);
6197   return ret.str();
6198 }
6199
6200 std::string DataArrayInt::reprZip() const
6201 {
6202   std::ostringstream ret;
6203   reprZipStream(ret);
6204   return ret.str();
6205 }
6206
6207 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6208 {
6209   static const char SPACE[4]={' ',' ',' ',' '};
6210   checkAllocated();
6211   std::string idt(indent,' ');
6212   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6213   if(byteArr)
6214     {
6215       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6216       if(std::string(type)=="Int32")
6217         {
6218           const char *data(reinterpret_cast<const char *>(begin()));
6219           std::size_t sz(getNbOfElems()*sizeof(int));
6220           byteArr->insertAtTheEnd(data,data+sz);
6221           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6222         }
6223       else if(std::string(type)=="Int8")
6224         {
6225           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6226           std::copy(begin(),end(),(char *)tmp);
6227           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6228           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6229         }
6230       else if(std::string(type)=="UInt8")
6231         {
6232           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6233           std::copy(begin(),end(),(unsigned char *)tmp);
6234           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6235           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6236         }
6237       else
6238         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6239     }
6240   else
6241     {
6242       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6243       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6244     }
6245   ofs << std::endl << idt << "</DataArray>\n";
6246 }
6247
6248 void DataArrayInt::reprStream(std::ostream& stream) const
6249 {
6250   stream << "Name of int array : \"" << _name << "\"\n";
6251   reprWithoutNameStream(stream);
6252 }
6253
6254 void DataArrayInt::reprZipStream(std::ostream& stream) const
6255 {
6256   stream << "Name of int array : \"" << _name << "\"\n";
6257   reprZipWithoutNameStream(stream);
6258 }
6259
6260 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6261 {
6262   DataArray::reprWithoutNameStream(stream);
6263   _mem.repr(getNumberOfComponents(),stream);
6264 }
6265
6266 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6267 {
6268   DataArray::reprWithoutNameStream(stream);
6269   _mem.reprZip(getNumberOfComponents(),stream);
6270 }
6271
6272 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6273 {
6274   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6275   const int *data=getConstPointer();
6276   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6277   if(nbTuples*nbComp>=1)
6278     {
6279       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6280       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6281       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6282       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6283     }
6284   else
6285     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6286   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6287 }
6288
6289 /*!
6290  * Method that gives a quick overvien of \a this for python.
6291  */
6292 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6293 {
6294   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6295   stream << "DataArrayInt C++ instance at " << this << ". ";
6296   if(isAllocated())
6297     {
6298       int nbOfCompo=(int)_info_on_compo.size();
6299       if(nbOfCompo>=1)
6300         {
6301           int nbOfTuples=getNumberOfTuples();
6302           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6303           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6304         }
6305       else
6306         stream << "Number of components : 0.";
6307     }
6308   else
6309     stream << "*** No data allocated ****";
6310 }
6311
6312 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6313 {
6314   const int *data=begin();
6315   int nbOfTuples=getNumberOfTuples();
6316   int nbOfCompo=(int)_info_on_compo.size();
6317   std::ostringstream oss2; oss2 << "[";
6318   std::string oss2Str(oss2.str());
6319   bool isFinished=true;
6320   for(int i=0;i<nbOfTuples && isFinished;i++)
6321     {
6322       if(nbOfCompo>1)
6323         {
6324           oss2 << "(";
6325           for(int j=0;j<nbOfCompo;j++,data++)
6326             {
6327               oss2 << *data;
6328               if(j!=nbOfCompo-1) oss2 << ", ";
6329             }
6330           oss2 << ")";
6331         }
6332       else
6333         oss2 << *data++;
6334       if(i!=nbOfTuples-1) oss2 << ", ";
6335       std::string oss3Str(oss2.str());
6336       if(oss3Str.length()<maxNbOfByteInRepr)
6337         oss2Str=oss3Str;
6338       else
6339         isFinished=false;
6340     }
6341   stream << oss2Str;
6342   if(!isFinished)
6343     stream << "... ";
6344   stream << "]";
6345 }
6346
6347 /*!
6348  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6349  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6350  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6351  *         to \a this array.
6352  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6353  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6354  *  \throw If \a this->getNumberOfComponents() != 1
6355  *  \throw If any value of \a this can't be used as a valid index for 
6356  *         [\a indArrBg, \a indArrEnd).
6357  */
6358 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6359 {
6360   checkAllocated();
6361   if(getNumberOfComponents()!=1)
6362     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6363   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6364   int nbOfTuples=getNumberOfTuples();
6365   int *pt=getPointer();
6366   for(int i=0;i<nbOfTuples;i++,pt++)
6367     {
6368       if(*pt>=0 && *pt<nbElemsIn)
6369         *pt=indArrBg[*pt];
6370       else
6371         {
6372           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6373           throw INTERP_KERNEL::Exception(oss.str().c_str());
6374         }
6375     }
6376   declareAsNew();
6377 }
6378
6379 /*!
6380  * Computes distribution of values of \a this one-dimensional array between given value
6381  * ranges (casts). This method is typically useful for entity number spliting by types,
6382  * for example. 
6383  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6384  *           check of this is be done. If not, the result is not warranted. 
6385  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6386  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6387  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6388  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6389  *         should be more than every value in \a this array.
6390  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6391  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6392  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6393  *         (same number of tuples and components), the caller is to delete 
6394  *         using decrRef() as it is no more needed.
6395  *         This array contains indices of ranges for every value of \a this array. I.e.
6396  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6397  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6398  *         this in which cast it holds.
6399  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6400  *         array, the caller is to delete using decrRef() as it is no more needed.
6401  *         This array contains ranks of values of \a this array within ranges
6402  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6403  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6404  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6405  *         for each tuple its rank inside its cast. The rank is computed as difference
6406  *         between the value and the lowest value of range.
6407  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6408  *         ranges (casts) to which at least one value of \a this array belongs.
6409  *         Or, in other words, this param contains the casts that \a this contains.
6410  *         The caller is to delete this array using decrRef() as it is no more needed.
6411  *
6412  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6413  *            the output of this method will be : 
6414  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6415  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6416  * - \a castsPresent  : [0,1]
6417  *
6418  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6419  * range #1 and its rank within this range is 2; etc.
6420  *
6421  *  \throw If \a this->getNumberOfComponents() != 1.
6422  *  \throw If \a arrEnd - arrBg < 2.
6423  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6424  */
6425 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6426                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6427     {
6428   checkAllocated();
6429   if(getNumberOfComponents()!=1)
6430     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6431   int nbOfTuples=getNumberOfTuples();
6432   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6433   if(nbOfCast<2)
6434     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6435   nbOfCast--;
6436   const int *work=getConstPointer();
6437   typedef std::reverse_iterator<const int *> rintstart;
6438   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6439   rintstart end2(arrBg);
6440   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6441   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6442   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6443   ret1->alloc(nbOfTuples,1);
6444   ret2->alloc(nbOfTuples,1);
6445   int *ret1Ptr=ret1->getPointer();
6446   int *ret2Ptr=ret2->getPointer();
6447   std::set<std::size_t> castsDetected;
6448   for(int i=0;i<nbOfTuples;i++)
6449     {
6450       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6451       std::size_t pos=std::distance(bg,res);
6452       std::size_t pos2=nbOfCast-pos;
6453       if(pos2<nbOfCast)
6454         {
6455           ret1Ptr[i]=(int)pos2;
6456           ret2Ptr[i]=work[i]-arrBg[pos2];
6457           castsDetected.insert(pos2);
6458         }
6459       else
6460         {
6461           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6462           throw INTERP_KERNEL::Exception(oss.str().c_str());
6463         }
6464     }
6465   ret3->alloc((int)castsDetected.size(),1);
6466   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6467   castArr=ret1.retn();
6468   rankInsideCast=ret2.retn();
6469   castsPresent=ret3.retn();
6470     }
6471
6472 /*!
6473  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6474  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6475  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6476  * new value in place \a indArr[ \a v ] is i.
6477  *  \param [in] indArrBg - the array holding indices within the result array to assign
6478  *         indices of values of \a this array pointing to values of \a indArrBg.
6479  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6480  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6481  *  \return DataArrayInt * - the new instance of DataArrayInt.
6482  *          The caller is to delete this result array using decrRef() as it is no more
6483  *          needed.
6484  *  \throw If \a this->getNumberOfComponents() != 1.
6485  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6486  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6487  */
6488 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6489 {
6490   checkAllocated();
6491   if(getNumberOfComponents()!=1)
6492     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6493   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6494   int nbOfTuples=getNumberOfTuples();
6495   const int *pt=getConstPointer();
6496   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6497   ret->alloc(nbOfTuples,1);
6498   ret->fillWithValue(-1);
6499   int *tmp=ret->getPointer();
6500   for(int i=0;i<nbOfTuples;i++,pt++)
6501     {
6502       if(*pt>=0 && *pt<nbElemsIn)
6503         {
6504           int pos=indArrBg[*pt];
6505           if(pos>=0 && pos<nbOfTuples)
6506             tmp[pos]=i;
6507           else
6508             {
6509               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6510               throw INTERP_KERNEL::Exception(oss.str().c_str());
6511             }
6512         }
6513       else
6514         {
6515           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6516           throw INTERP_KERNEL::Exception(oss.str().c_str());
6517         }
6518     }
6519   return ret.retn();
6520 }
6521
6522 /*!
6523  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6524  * from values of \a this array, which is supposed to contain a renumbering map in 
6525  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6526  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6527  *  \param [in] newNbOfElem - the number of tuples in the result array.
6528  *  \return DataArrayInt * - the new instance of DataArrayInt.
6529  *          The caller is to delete this result array using decrRef() as it is no more
6530  *          needed.
6531  * 
6532  *  \if ENABLE_EXAMPLES
6533  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6534  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6535  *  \endif
6536  */
6537 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6538 {
6539   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6540   ret->alloc(newNbOfElem,1);
6541   int nbOfOldNodes=getNumberOfTuples();
6542   const int *old2New=getConstPointer();
6543   int *pt=ret->getPointer();
6544   for(int i=0;i!=nbOfOldNodes;i++)
6545     {
6546       int newp(old2New[i]);
6547       if(newp!=-1)
6548         {
6549           if(newp>=0 && newp<newNbOfElem)
6550             pt[newp]=i;
6551           else
6552             {
6553               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6554               throw INTERP_KERNEL::Exception(oss.str().c_str());
6555             }
6556         }
6557     }
6558   return ret.retn();
6559 }
6560
6561 /*!
6562  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6563  * 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]
6564  */
6565 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6566 {
6567   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6568   ret->alloc(newNbOfElem,1);
6569   int nbOfOldNodes=getNumberOfTuples();
6570   const int *old2New=getConstPointer();
6571   int *pt=ret->getPointer();
6572   for(int i=nbOfOldNodes-1;i>=0;i--)
6573     {
6574       int newp(old2New[i]);
6575       if(newp!=-1)
6576         {
6577           if(newp>=0 && newp<newNbOfElem)
6578             pt[newp]=i;
6579           else
6580             {
6581               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6582               throw INTERP_KERNEL::Exception(oss.str().c_str());
6583             }
6584         }
6585     }
6586   return ret.retn();
6587 }
6588
6589 /*!
6590  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6591  * from values of \a this array, which is supposed to contain a renumbering map in 
6592  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6593  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6594  *  \param [in] newNbOfElem - the number of tuples in the result array.
6595  *  \return DataArrayInt * - the new instance of DataArrayInt.
6596  *          The caller is to delete this result array using decrRef() as it is no more
6597  *          needed.
6598  * 
6599  *  \if ENABLE_EXAMPLES
6600  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6601  *
6602  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6603  *  \endif
6604  */
6605 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6606 {
6607   checkAllocated();
6608   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6609   ret->alloc(oldNbOfElem,1);
6610   const int *new2Old=getConstPointer();
6611   int *pt=ret->getPointer();
6612   std::fill(pt,pt+oldNbOfElem,-1);
6613   int nbOfNewElems=getNumberOfTuples();
6614   for(int i=0;i<nbOfNewElems;i++)
6615     {
6616       int v(new2Old[i]);
6617       if(v>=0 && v<oldNbOfElem)
6618         pt[v]=i;
6619       else
6620         {
6621           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6622           throw INTERP_KERNEL::Exception(oss.str().c_str());
6623         }
6624     }
6625   return ret.retn();
6626 }
6627
6628 /*!
6629  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6630  * mismatch is given.
6631  * 
6632  * \param [in] other the instance to be compared with \a this
6633  * \param [out] reason In case of inequality returns the reason.
6634  * \sa DataArrayInt::isEqual
6635  */
6636 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6637 {
6638   if(!areInfoEqualsIfNotWhy(other,reason))
6639     return false;
6640   return _mem.isEqual(other._mem,0,reason);
6641 }
6642
6643 /*!
6644  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6645  * \ref MEDCouplingArrayBasicsCompare.
6646  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6647  *  \return bool - \a true if the two arrays are equal, \a false else.
6648  */
6649 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6650 {
6651   std::string tmp;
6652   return isEqualIfNotWhy(other,tmp);
6653 }
6654
6655 /*!
6656  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6657  * \ref MEDCouplingArrayBasicsCompare.
6658  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6659  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6660  */
6661 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6662 {
6663   std::string tmp;
6664   return _mem.isEqual(other._mem,0,tmp);
6665 }
6666
6667 /*!
6668  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6669  * performed on sorted value sequences.
6670  * For more info see\ref MEDCouplingArrayBasicsCompare.
6671  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6672  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6673  */
6674 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6675 {
6676   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6677   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6678   a->sort();
6679   b->sort();
6680   return a->isEqualWithoutConsideringStr(*b);
6681 }
6682
6683 /*!
6684  * This method compares content of input vector \a v and \a this.
6685  * 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.
6686  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6687  *
6688  * \param [in] v - the vector of 'flags' to be compared with \a this.
6689  *
6690  * \throw If \a this is not sorted ascendingly.
6691  * \throw If \a this has not exactly one component.
6692  * \throw If \a this is not allocated.
6693  */
6694 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6695 {
6696   checkAllocated();
6697   if(getNumberOfComponents()!=1)
6698     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6699   const int *w(begin()),*end2(end());
6700   int refVal=-std::numeric_limits<int>::max();
6701   int i=0;
6702   std::vector<bool>::const_iterator it(v.begin());
6703   for(;it!=v.end();it++,i++)
6704     {
6705       if(*it)
6706         {
6707           if(w!=end2)
6708             {
6709               if(*w++==i)
6710                 {
6711                   if(i>refVal)
6712                     refVal=i;
6713                   else
6714                     {
6715                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6716                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6717                     }
6718                 }
6719               else
6720                 return false;
6721             }
6722           else
6723             return false;
6724         }
6725     }
6726   return w==end2;
6727 }
6728
6729 /*!
6730  * Sorts values of the array.
6731  *  \param [in] asc - \a true means ascending order, \a false, descending.
6732  *  \throw If \a this is not allocated.
6733  *  \throw If \a this->getNumberOfComponents() != 1.
6734  */
6735 void DataArrayInt::sort(bool asc)
6736 {
6737   checkAllocated();
6738   if(getNumberOfComponents()!=1)
6739     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6740   _mem.sort(asc);
6741   declareAsNew();
6742 }
6743
6744 /*!
6745  * Computes for each tuple the sum of number of components values in the tuple and return it.
6746  * 
6747  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6748  *          same number of tuples as \a this array and one component.
6749  *          The caller is to delete this result array using decrRef() as it is no more
6750  *          needed.
6751  *  \throw If \a this is not allocated.
6752  */
6753 DataArrayInt *DataArrayInt::sumPerTuple() const
6754 {
6755   checkAllocated();
6756   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6757   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6758   ret->alloc(nbOfTuple,1);
6759   const int *src(getConstPointer());
6760   int *dest(ret->getPointer());
6761   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6762     *dest=std::accumulate(src,src+nbOfComp,0);
6763   return ret.retn();
6764 }
6765
6766 /*!
6767  * Reverse the array values.
6768  *  \throw If \a this->getNumberOfComponents() < 1.
6769  *  \throw If \a this is not allocated.
6770  */
6771 void DataArrayInt::reverse()
6772 {
6773   checkAllocated();
6774   _mem.reverse(getNumberOfComponents());
6775   declareAsNew();
6776 }
6777
6778 /*!
6779  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6780  * If not an exception is thrown.
6781  *  \param [in] increasing - if \a true, the array values should be increasing.
6782  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6783  *         increasing arg.
6784  *  \throw If \a this->getNumberOfComponents() != 1.
6785  *  \throw If \a this is not allocated.
6786  */
6787 void DataArrayInt::checkMonotonic(bool increasing) const
6788 {
6789   if(!isMonotonic(increasing))
6790     {
6791       if (increasing)
6792         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6793       else
6794         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6795     }
6796 }
6797
6798 /*!
6799  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6800  *  \param [in] increasing - if \a true, array values should be increasing.
6801  *  \return bool - \a true if values change in accordance with \a increasing arg.
6802  *  \throw If \a this->getNumberOfComponents() != 1.
6803  *  \throw If \a this is not allocated.
6804  */
6805 bool DataArrayInt::isMonotonic(bool increasing) const
6806 {
6807   checkAllocated();
6808   if(getNumberOfComponents()!=1)
6809     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6810   int nbOfElements=getNumberOfTuples();
6811   const int *ptr=getConstPointer();
6812   if(nbOfElements==0)
6813     return true;
6814   int ref=ptr[0];
6815   if(increasing)
6816     {
6817       for(int i=1;i<nbOfElements;i++)
6818         {
6819           if(ptr[i]>=ref)
6820             ref=ptr[i];
6821           else
6822             return false;
6823         }
6824     }
6825   else
6826     {
6827       for(int i=1;i<nbOfElements;i++)
6828         {
6829           if(ptr[i]<=ref)
6830             ref=ptr[i];
6831           else
6832             return false;
6833         }
6834     }
6835   return true;
6836 }
6837
6838 /*!
6839  * This method check that array consistently INCREASING or DECREASING in value.
6840  */
6841 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6842 {
6843   checkAllocated();
6844   if(getNumberOfComponents()!=1)
6845     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6846   int nbOfElements=getNumberOfTuples();
6847   const int *ptr=getConstPointer();
6848   if(nbOfElements==0)
6849     return true;
6850   int ref=ptr[0];
6851   if(increasing)
6852     {
6853       for(int i=1;i<nbOfElements;i++)
6854         {
6855           if(ptr[i]>ref)
6856             ref=ptr[i];
6857           else
6858             return false;
6859         }
6860     }
6861   else
6862     {
6863       for(int i=1;i<nbOfElements;i++)
6864         {
6865           if(ptr[i]<ref)
6866             ref=ptr[i];
6867           else
6868             return false;
6869         }
6870     }
6871   return true;
6872 }
6873
6874 /*!
6875  * This method check that array consistently INCREASING or DECREASING in value.
6876  */
6877 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6878 {
6879   if(!isStrictlyMonotonic(increasing))
6880     {
6881       if (increasing)
6882         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6883       else
6884         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6885     }
6886 }
6887
6888 /*!
6889  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6890  * one-dimensional arrays that must be of the same length. The result array describes
6891  * correspondence between \a this and \a other arrays, so that 
6892  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6893  * not possible because some element in \a other is not in \a this, an exception is thrown.
6894  *  \param [in] other - an array to compute permutation to.
6895  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6896  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6897  * no more needed.
6898  *  \throw If \a this->getNumberOfComponents() != 1.
6899  *  \throw If \a other->getNumberOfComponents() != 1.
6900  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6901  *  \throw If \a other includes a value which is not in \a this array.
6902  * 
6903  *  \if ENABLE_EXAMPLES
6904  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6905  *
6906  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6907  *  \endif
6908  */
6909 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6910 {
6911   checkAllocated();
6912   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6913     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6914   int nbTuple=getNumberOfTuples();
6915   other.checkAllocated();
6916   if(nbTuple!=other.getNumberOfTuples())
6917     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6918   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6919   ret->alloc(nbTuple,1);
6920   ret->fillWithValue(-1);
6921   const int *pt=getConstPointer();
6922   std::map<int,int> mm;
6923   for(int i=0;i<nbTuple;i++)
6924     mm[pt[i]]=i;
6925   pt=other.getConstPointer();
6926   int *retToFill=ret->getPointer();
6927   for(int i=0;i<nbTuple;i++)
6928     {
6929       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6930       if(it==mm.end())
6931         {
6932           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6933           throw INTERP_KERNEL::Exception(oss.str().c_str());
6934         }
6935       retToFill[i]=(*it).second;
6936     }
6937   return ret.retn();
6938 }
6939
6940 /*!
6941  * Sets a C array to be used as raw data of \a this. The previously set info
6942  *  of components is retained and re-sized. 
6943  * For more info see \ref MEDCouplingArraySteps1.
6944  *  \param [in] array - the C array to be used as raw data of \a this.
6945  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6946  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6947  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6948  *                     \c free(\c array ) will be called.
6949  *  \param [in] nbOfTuple - new number of tuples in \a this.
6950  *  \param [in] nbOfCompo - new number of components in \a this.
6951  */
6952 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6953 {
6954   _info_on_compo.resize(nbOfCompo);
6955   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6956   declareAsNew();
6957 }
6958
6959 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6960 {
6961   _info_on_compo.resize(nbOfCompo);
6962   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6963   declareAsNew();
6964 }
6965
6966 /*!
6967  * Returns a new DataArrayInt holding the same values as \a this array but differently
6968  * arranged in memory. If \a this array holds 2 components of 3 values:
6969  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6970  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6971  *  \warning Do not confuse this method with transpose()!
6972  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6973  *          is to delete using decrRef() as it is no more needed.
6974  *  \throw If \a this is not allocated.
6975  */
6976 DataArrayInt *DataArrayInt::fromNoInterlace() const
6977 {
6978   checkAllocated();
6979   if(_mem.isNull())
6980     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6981   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6982   DataArrayInt *ret=DataArrayInt::New();
6983   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6984   return ret;
6985 }
6986
6987 /*!
6988  * Returns a new DataArrayInt holding the same values as \a this array but differently
6989  * arranged in memory. If \a this array holds 2 components of 3 values:
6990  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6991  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6992  *  \warning Do not confuse this method with transpose()!
6993  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6994  *          is to delete using decrRef() as it is no more needed.
6995  *  \throw If \a this is not allocated.
6996  */
6997 DataArrayInt *DataArrayInt::toNoInterlace() const
6998 {
6999   checkAllocated();
7000   if(_mem.isNull())
7001     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7002   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7003   DataArrayInt *ret=DataArrayInt::New();
7004   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7005   return ret;
7006 }
7007
7008 /*!
7009  * Permutes values of \a this array as required by \a old2New array. The values are
7010  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7011  * the same as in \this one.
7012  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7013  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7014  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7015  *     giving a new position for i-th old value.
7016  */
7017 void DataArrayInt::renumberInPlace(const int *old2New)
7018 {
7019   checkAllocated();
7020   int nbTuples=getNumberOfTuples();
7021   int nbOfCompo=getNumberOfComponents();
7022   int *tmp=new int[nbTuples*nbOfCompo];
7023   const int *iptr=getConstPointer();
7024   for(int i=0;i<nbTuples;i++)
7025     {
7026       int v=old2New[i];
7027       if(v>=0 && v<nbTuples)
7028         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7029       else
7030         {
7031           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7032           throw INTERP_KERNEL::Exception(oss.str().c_str());
7033         }
7034     }
7035   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7036   delete [] tmp;
7037   declareAsNew();
7038 }
7039
7040 /*!
7041  * Permutes values of \a this array as required by \a new2Old array. The values are
7042  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7043  * the same as in \this one.
7044  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7045  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7046  *     giving a previous position of i-th new value.
7047  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7048  *          is to delete using decrRef() as it is no more needed.
7049  */
7050 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7051 {
7052   checkAllocated();
7053   int nbTuples=getNumberOfTuples();
7054   int nbOfCompo=getNumberOfComponents();
7055   int *tmp=new int[nbTuples*nbOfCompo];
7056   const int *iptr=getConstPointer();
7057   for(int i=0;i<nbTuples;i++)
7058     {
7059       int v=new2Old[i];
7060       if(v>=0 && v<nbTuples)
7061         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7062       else
7063         {
7064           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7065           throw INTERP_KERNEL::Exception(oss.str().c_str());
7066         }
7067     }
7068   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7069   delete [] tmp;
7070   declareAsNew();
7071 }
7072
7073 /*!
7074  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7075  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7076  * Number of tuples in the result array remains the same as in \this one.
7077  * If a permutation reduction is needed, renumberAndReduce() should be used.
7078  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7079  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7080  *          giving a new position for i-th old value.
7081  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7082  *          is to delete using decrRef() as it is no more needed.
7083  *  \throw If \a this is not allocated.
7084  */
7085 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7086 {
7087   checkAllocated();
7088   int nbTuples=getNumberOfTuples();
7089   int nbOfCompo=getNumberOfComponents();
7090   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7091   ret->alloc(nbTuples,nbOfCompo);
7092   ret->copyStringInfoFrom(*this);
7093   const int *iptr=getConstPointer();
7094   int *optr=ret->getPointer();
7095   for(int i=0;i<nbTuples;i++)
7096     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7097   ret->copyStringInfoFrom(*this);
7098   return ret.retn();
7099 }
7100
7101 /*!
7102  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7103  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7104  * tuples in the result array remains the same as in \this one.
7105  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7106  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7107  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7108  *     giving a previous position of i-th new value.
7109  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7110  *          is to delete using decrRef() as it is no more needed.
7111  */
7112 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7113 {
7114   checkAllocated();
7115   int nbTuples=getNumberOfTuples();
7116   int nbOfCompo=getNumberOfComponents();
7117   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7118   ret->alloc(nbTuples,nbOfCompo);
7119   ret->copyStringInfoFrom(*this);
7120   const int *iptr=getConstPointer();
7121   int *optr=ret->getPointer();
7122   for(int i=0;i<nbTuples;i++)
7123     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7124   ret->copyStringInfoFrom(*this);
7125   return ret.retn();
7126 }
7127
7128 /*!
7129  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7130  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7131  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7132  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7133  * \a old2New[ i ] is negative, is missing from the result array.
7134  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7135  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7136  *     giving a new position for i-th old tuple and giving negative position for
7137  *     for i-th old tuple that should be omitted.
7138  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7139  *          is to delete using decrRef() as it is no more needed.
7140  */
7141 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7142 {
7143   checkAllocated();
7144   int nbTuples=getNumberOfTuples();
7145   int nbOfCompo=getNumberOfComponents();
7146   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7147   ret->alloc(newNbOfTuple,nbOfCompo);
7148   const int *iptr=getConstPointer();
7149   int *optr=ret->getPointer();
7150   for(int i=0;i<nbTuples;i++)
7151     {
7152       int w=old2New[i];
7153       if(w>=0)
7154         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7155     }
7156   ret->copyStringInfoFrom(*this);
7157   return ret.retn();
7158 }
7159
7160 /*!
7161  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7162  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7163  * \a new2OldBg array.
7164  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7165  * This method is equivalent to renumberAndReduce() except that convention in input is
7166  * \c new2old and \b not \c old2new.
7167  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7168  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7169  *              tuple index in \a this array to fill the i-th tuple in the new array.
7170  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7171  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7172  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7173  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7174  *          is to delete using decrRef() as it is no more needed.
7175  */
7176 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7177 {
7178   checkAllocated();
7179   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7180   int nbComp=getNumberOfComponents();
7181   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7182   ret->copyStringInfoFrom(*this);
7183   int *pt=ret->getPointer();
7184   const int *srcPt=getConstPointer();
7185   int i=0;
7186   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7187     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7188   ret->copyStringInfoFrom(*this);
7189   return ret.retn();
7190 }
7191
7192 /*!
7193  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7194  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7195  * \a new2OldBg array.
7196  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7197  * This method is equivalent to renumberAndReduce() except that convention in input is
7198  * \c new2old and \b not \c old2new.
7199  * This method is equivalent to selectByTupleId() except that it prevents coping data
7200  * from behind the end of \a this array.
7201  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7202  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7203  *              tuple index in \a this array to fill the i-th tuple in the new array.
7204  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7205  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7206  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7207  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7208  *          is to delete using decrRef() as it is no more needed.
7209  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7210  */
7211 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7212 {
7213   checkAllocated();
7214   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7215   int nbComp=getNumberOfComponents();
7216   int oldNbOfTuples=getNumberOfTuples();
7217   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7218   ret->copyStringInfoFrom(*this);
7219   int *pt=ret->getPointer();
7220   const int *srcPt=getConstPointer();
7221   int i=0;
7222   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7223     if(*w>=0 && *w<oldNbOfTuples)
7224       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7225     else
7226       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7227   ret->copyStringInfoFrom(*this);
7228   return ret.retn();
7229 }
7230
7231 /*!
7232  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7233  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7234  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7235  * command \c range( \a bg, \a end2, \a step ).
7236  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7237  * not constructed explicitly.
7238  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7239  *  \param [in] bg - index of the first tuple to copy from \a this array.
7240  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7241  *  \param [in] step - index increment to get index of the next tuple to copy.
7242  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7243  *          is to delete using decrRef() as it is no more needed.
7244  *  \sa DataArrayInt::substr.
7245  */
7246 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7247 {
7248   checkAllocated();
7249   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7250   int nbComp=getNumberOfComponents();
7251   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7252   ret->alloc(newNbOfTuples,nbComp);
7253   int *pt=ret->getPointer();
7254   const int *srcPt=getConstPointer()+bg*nbComp;
7255   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7256     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7257   ret->copyStringInfoFrom(*this);
7258   return ret.retn();
7259 }
7260
7261 /*!
7262  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7263  * of tuples specified by \a ranges parameter.
7264  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7265  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7266  *              of tuples in [\c begin,\c end) format.
7267  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7268  *          is to delete using decrRef() as it is no more needed.
7269  *  \throw If \a end < \a begin.
7270  *  \throw If \a end > \a this->getNumberOfTuples().
7271  *  \throw If \a this is not allocated.
7272  */
7273 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7274 {
7275   checkAllocated();
7276   int nbOfComp=getNumberOfComponents();
7277   int nbOfTuplesThis=getNumberOfTuples();
7278   if(ranges.empty())
7279     {
7280       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7281       ret->alloc(0,nbOfComp);
7282       ret->copyStringInfoFrom(*this);
7283       return ret.retn();
7284     }
7285   int ref=ranges.front().first;
7286   int nbOfTuples=0;
7287   bool isIncreasing=true;
7288   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7289     {
7290       if((*it).first<=(*it).second)
7291         {
7292           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7293             {
7294               nbOfTuples+=(*it).second-(*it).first;
7295               if(isIncreasing)
7296                 isIncreasing=ref<=(*it).first;
7297               ref=(*it).second;
7298             }
7299           else
7300             {
7301               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7302               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7303               throw INTERP_KERNEL::Exception(oss.str().c_str());
7304             }
7305         }
7306       else
7307         {
7308           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7309           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7310           throw INTERP_KERNEL::Exception(oss.str().c_str());
7311         }
7312     }
7313   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7314     return deepCpy();
7315   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7316   ret->alloc(nbOfTuples,nbOfComp);
7317   ret->copyStringInfoFrom(*this);
7318   const int *src=getConstPointer();
7319   int *work=ret->getPointer();
7320   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7321     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7322   return ret.retn();
7323 }
7324
7325 /*!
7326  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7327  * This map, if applied to \a this array, would make it sorted. For example, if
7328  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7329  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7330  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7331  * This method is useful for renumbering (in MED file for example). For more info
7332  * on renumbering see \ref MEDCouplingArrayRenumbering.
7333  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7334  *          array using decrRef() as it is no more needed.
7335  *  \throw If \a this is not allocated.
7336  *  \throw If \a this->getNumberOfComponents() != 1.
7337  *  \throw If there are equal values in \a this array.
7338  */
7339 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7340 {
7341   checkAllocated();
7342   if(getNumberOfComponents()!=1)
7343     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7344   int nbTuples=getNumberOfTuples();
7345   const int *pt=getConstPointer();
7346   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7347   DataArrayInt *ret=DataArrayInt::New();
7348   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7349   return ret;
7350 }
7351
7352 /*!
7353  * 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
7354  * input array \a ids2.
7355  * \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.
7356  * 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
7357  * inversely.
7358  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7359  *
7360  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7361  *          array using decrRef() as it is no more needed.
7362  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7363  * 
7364  */
7365 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7366 {
7367   if(!ids1 || !ids2)
7368     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7369   if(!ids1->isAllocated() || !ids2->isAllocated())
7370     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7371   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7372     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7373   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7374     {
7375       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 !";
7376       throw INTERP_KERNEL::Exception(oss.str().c_str());
7377     }
7378   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7379   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7380   p1->sort(true); p2->sort(true);
7381   if(!p1->isEqualWithoutConsideringStr(*p2))
7382     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7383   p1=ids1->checkAndPreparePermutation();
7384   p2=ids2->checkAndPreparePermutation();
7385   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7386   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7387   return p2.retn();
7388 }
7389
7390 /*!
7391  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7392  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7393  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7394  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7395  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7396  * The first of out arrays returns indices of elements of \a this array, grouped by their
7397  * place in the set \a B. The second out array is the index of the first one; it shows how
7398  * many elements of \a A are mapped into each element of \a B. <br>
7399  * For more info on
7400  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7401  * \b Example:
7402  * - \a this: [0,3,2,3,2,2,1,2]
7403  * - \a targetNb: 4
7404  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7405  * - \a arrI: [0,1,2,6,8]
7406  *
7407  * This result means: <br>
7408  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7409  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7410  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7411  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7412  * \a arrI[ 2+1 ]]); <br> etc.
7413  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7414  *         than the maximal value of \a A.
7415  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7416  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7417  *         this array using decrRef() as it is no more needed.
7418  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7419  *         elements of \a this. The caller is to delete this array using decrRef() as it
7420  *         is no more needed.
7421  *  \throw If \a this is not allocated.
7422  *  \throw If \a this->getNumberOfComponents() != 1.
7423  *  \throw If any value in \a this is more or equal to \a targetNb.
7424  */
7425 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7426 {
7427   checkAllocated();
7428   if(getNumberOfComponents()!=1)
7429     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7430   int nbOfTuples=getNumberOfTuples();
7431   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7432   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7433   retI->alloc(targetNb+1,1);
7434   const int *input=getConstPointer();
7435   std::vector< std::vector<int> > tmp(targetNb);
7436   for(int i=0;i<nbOfTuples;i++)
7437     {
7438       int tmp2=input[i];
7439       if(tmp2>=0 && tmp2<targetNb)
7440         tmp[tmp2].push_back(i);
7441       else
7442         {
7443           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7444           throw INTERP_KERNEL::Exception(oss.str().c_str());
7445         }
7446     }
7447   int *retIPtr=retI->getPointer();
7448   *retIPtr=0;
7449   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7450     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7451   if(nbOfTuples!=retI->getIJ(targetNb,0))
7452     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7453   ret->alloc(nbOfTuples,1);
7454   int *retPtr=ret->getPointer();
7455   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7456     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7457   arr=ret.retn();
7458   arrI=retI.retn();
7459 }
7460
7461
7462 /*!
7463  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7464  * from a zip representation of a surjective format (returned e.g. by
7465  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7466  * for example). The result array minimizes the permutation. <br>
7467  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7468  * \b Example: <br>
7469  * - \a nbOfOldTuples: 10 
7470  * - \a arr          : [0,3, 5,7,9]
7471  * - \a arrIBg       : [0,2,5]
7472  * - \a newNbOfTuples: 7
7473  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7474  *
7475  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7476  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7477  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7478  *         (indices of) equal values. Its every element (except the last one) points to
7479  *         the first element of a group of equal values.
7480  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7481  *          arrIBg is \a arrIEnd[ -1 ].
7482  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7483  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7484  *          array using decrRef() as it is no more needed.
7485  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7486  */
7487 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7488 {
7489   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7490   ret->alloc(nbOfOldTuples,1);
7491   int *pt=ret->getPointer();
7492   std::fill(pt,pt+nbOfOldTuples,-1);
7493   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7494   const int *cIPtr=arrIBg;
7495   for(int i=0;i<nbOfGrps;i++)
7496     pt[arr[cIPtr[i]]]=-(i+2);
7497   int newNb=0;
7498   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7499     {
7500       if(pt[iNode]<0)
7501         {
7502           if(pt[iNode]==-1)
7503             pt[iNode]=newNb++;
7504           else
7505             {
7506               int grpId=-(pt[iNode]+2);
7507               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7508                 {
7509                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7510                     pt[arr[j]]=newNb;
7511                   else
7512                     {
7513                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7514                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7515                     }
7516                 }
7517               newNb++;
7518             }
7519         }
7520     }
7521   newNbOfTuples=newNb;
7522   return ret.retn();
7523 }
7524
7525 /*!
7526  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7527  * which if applied to \a this array would make it sorted ascendingly.
7528  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7529  * \b Example: <br>
7530  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7531  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7532  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7533  *
7534  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7535  *          array using decrRef() as it is no more needed.
7536  *  \throw If \a this is not allocated.
7537  *  \throw If \a this->getNumberOfComponents() != 1.
7538  */
7539 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7540 {
7541   checkAllocated();
7542   if(getNumberOfComponents()!=1)
7543     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7544   int nbOfTuples=getNumberOfTuples();
7545   const int *pt=getConstPointer();
7546   std::map<int,int> m;
7547   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7548   ret->alloc(nbOfTuples,1);
7549   int *opt=ret->getPointer();
7550   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7551     {
7552       int val=*pt;
7553       std::map<int,int>::iterator it=m.find(val);
7554       if(it!=m.end())
7555         {
7556           *opt=(*it).second;
7557           (*it).second++;
7558         }
7559       else
7560         {
7561           *opt=0;
7562           m.insert(std::pair<int,int>(val,1));
7563         }
7564     }
7565   int sum=0;
7566   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7567     {
7568       int vt=(*it).second;
7569       (*it).second=sum;
7570       sum+=vt;
7571     }
7572   pt=getConstPointer();
7573   opt=ret->getPointer();
7574   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7575     *opt+=m[*pt];
7576   //
7577   return ret.retn();
7578 }
7579
7580 /*!
7581  * Checks if contents of \a this array are equal to that of an array filled with
7582  * iota(). This method is particularly useful for DataArrayInt instances that represent
7583  * a renumbering array to check the real need in renumbering. 
7584  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7585  *  \throw If \a this is not allocated.
7586  *  \throw If \a this->getNumberOfComponents() != 1.
7587  */
7588 bool DataArrayInt::isIdentity() const
7589 {
7590   checkAllocated();
7591   if(getNumberOfComponents()!=1)
7592     return false;
7593   int nbOfTuples=getNumberOfTuples();
7594   const int *pt=getConstPointer();
7595   for(int i=0;i<nbOfTuples;i++,pt++)
7596     if(*pt!=i)
7597       return false;
7598   return true;
7599 }
7600
7601 /*!
7602  * Checks if all values in \a this array are equal to \a val.
7603  *  \param [in] val - value to check equality of array values to.
7604  *  \return bool - \a true if all values are \a val.
7605  *  \throw If \a this is not allocated.
7606  *  \throw If \a this->getNumberOfComponents() != 1
7607  */
7608 bool DataArrayInt::isUniform(int val) const
7609 {
7610   checkAllocated();
7611   if(getNumberOfComponents()!=1)
7612     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7613   int nbOfTuples=getNumberOfTuples();
7614   const int *w=getConstPointer();
7615   const int *end2=w+nbOfTuples;
7616   for(;w!=end2;w++)
7617     if(*w!=val)
7618       return false;
7619   return true;
7620 }
7621
7622 /*!
7623  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7624  * array to the new one.
7625  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7626  */
7627 DataArrayDouble *DataArrayInt::convertToDblArr() const
7628 {
7629   checkAllocated();
7630   DataArrayDouble *ret=DataArrayDouble::New();
7631   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7632   std::size_t nbOfVals=getNbOfElems();
7633   const int *src=getConstPointer();
7634   double *dest=ret->getPointer();
7635   std::copy(src,src+nbOfVals,dest);
7636   ret->copyStringInfoFrom(*this);
7637   return ret;
7638 }
7639
7640 /*!
7641  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7642  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7643  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7644  * This method is a specialization of selectByTupleId2().
7645  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7646  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7647  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7648  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7649  *          is to delete using decrRef() as it is no more needed.
7650  *  \throw If \a tupleIdBg < 0.
7651  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7652     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7653  *  \sa DataArrayInt::selectByTupleId2
7654  */
7655 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7656 {
7657   checkAllocated();
7658   int nbt=getNumberOfTuples();
7659   if(tupleIdBg<0)
7660     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7661   if(tupleIdBg>nbt)
7662     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7663   int trueEnd=tupleIdEnd;
7664   if(tupleIdEnd!=-1)
7665     {
7666       if(tupleIdEnd>nbt)
7667         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7668     }
7669   else
7670     trueEnd=nbt;
7671   int nbComp=getNumberOfComponents();
7672   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7673   ret->alloc(trueEnd-tupleIdBg,nbComp);
7674   ret->copyStringInfoFrom(*this);
7675   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7676   return ret.retn();
7677 }
7678
7679 /*!
7680  * Changes the number of components within \a this array so that its raw data **does
7681  * not** change, instead splitting this data into tuples changes.
7682  *  \warning This method erases all (name and unit) component info set before!
7683  *  \param [in] newNbOfComp - number of components for \a this array to have.
7684  *  \throw If \a this is not allocated
7685  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7686  *  \throw If \a newNbOfCompo is lower than 1.
7687  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7688  *  \warning This method erases all (name and unit) component info set before!
7689  */
7690 void DataArrayInt::rearrange(int newNbOfCompo)
7691 {
7692   checkAllocated();
7693   if(newNbOfCompo<1)
7694     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7695   std::size_t nbOfElems=getNbOfElems();
7696   if(nbOfElems%newNbOfCompo!=0)
7697     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7698   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7699     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7700   _info_on_compo.clear();
7701   _info_on_compo.resize(newNbOfCompo);
7702   declareAsNew();
7703 }
7704
7705 /*!
7706  * Changes the number of components within \a this array to be equal to its number
7707  * of tuples, and inversely its number of tuples to become equal to its number of 
7708  * components. So that its raw data **does not** change, instead splitting this
7709  * data into tuples changes.
7710  *  \warning This method erases all (name and unit) component info set before!
7711  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7712  *  \throw If \a this is not allocated.
7713  *  \sa rearrange()
7714  */
7715 void DataArrayInt::transpose()
7716 {
7717   checkAllocated();
7718   int nbOfTuples=getNumberOfTuples();
7719   rearrange(nbOfTuples);
7720 }
7721
7722 /*!
7723  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7724  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7725  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7726  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7727  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7728  * components.  
7729  *  \param [in] newNbOfComp - number of components for the new array to have.
7730  *  \param [in] dftValue - value assigned to new values added to the new array.
7731  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7732  *          is to delete using decrRef() as it is no more needed.
7733  *  \throw If \a this is not allocated.
7734  */
7735 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7736 {
7737   checkAllocated();
7738   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7739   ret->alloc(getNumberOfTuples(),newNbOfComp);
7740   const int *oldc=getConstPointer();
7741   int *nc=ret->getPointer();
7742   int nbOfTuples=getNumberOfTuples();
7743   int oldNbOfComp=getNumberOfComponents();
7744   int dim=std::min(oldNbOfComp,newNbOfComp);
7745   for(int i=0;i<nbOfTuples;i++)
7746     {
7747       int j=0;
7748       for(;j<dim;j++)
7749         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7750       for(;j<newNbOfComp;j++)
7751         nc[newNbOfComp*i+j]=dftValue;
7752     }
7753   ret->setName(getName());
7754   for(int i=0;i<dim;i++)
7755     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7756   ret->setName(getName());
7757   return ret.retn();
7758 }
7759
7760 /*!
7761  * Changes number of tuples in the array. If the new number of tuples is smaller
7762  * than the current number the array is truncated, otherwise the array is extended.
7763  *  \param [in] nbOfTuples - new number of tuples. 
7764  *  \throw If \a this is not allocated.
7765  *  \throw If \a nbOfTuples is negative.
7766  */
7767 void DataArrayInt::reAlloc(int nbOfTuples)
7768 {
7769   if(nbOfTuples<0)
7770     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7771   checkAllocated();
7772   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7773   declareAsNew();
7774 }
7775
7776
7777 /*!
7778  * Returns a copy of \a this array composed of selected components.
7779  * The new DataArrayInt has the same number of tuples but includes components
7780  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7781  * can be either less, same or more than \a this->getNbOfElems().
7782  *  \param [in] compoIds - sequence of zero based indices of components to include
7783  *              into the new array.
7784  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7785  *          is to delete using decrRef() as it is no more needed.
7786  *  \throw If \a this is not allocated.
7787  *  \throw If a component index (\a i) is not valid: 
7788  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7789  *
7790  *  \if ENABLE_EXAMPLES
7791  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7792  *  \endif
7793  */
7794 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7795 {
7796   checkAllocated();
7797   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7798   int newNbOfCompo=(int)compoIds.size();
7799   int oldNbOfCompo=getNumberOfComponents();
7800   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7801     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7802   int nbOfTuples=getNumberOfTuples();
7803   ret->alloc(nbOfTuples,newNbOfCompo);
7804   ret->copyPartOfStringInfoFrom(*this,compoIds);
7805   const int *oldc=getConstPointer();
7806   int *nc=ret->getPointer();
7807   for(int i=0;i<nbOfTuples;i++)
7808     for(int j=0;j<newNbOfCompo;j++,nc++)
7809       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7810   return ret.retn();
7811 }
7812
7813 /*!
7814  * Appends components of another array to components of \a this one, tuple by tuple.
7815  * So that the number of tuples of \a this array remains the same and the number of 
7816  * components increases.
7817  *  \param [in] other - the DataArrayInt to append to \a this one.
7818  *  \throw If \a this is not allocated.
7819  *  \throw If \a this and \a other arrays have different number of tuples.
7820  *
7821  *  \if ENABLE_EXAMPLES
7822  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7823  *
7824  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7825  *  \endif
7826  */
7827 void DataArrayInt::meldWith(const DataArrayInt *other)
7828 {
7829   if(!other)
7830     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7831   checkAllocated();
7832   other->checkAllocated();
7833   int nbOfTuples=getNumberOfTuples();
7834   if(nbOfTuples!=other->getNumberOfTuples())
7835     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7836   int nbOfComp1=getNumberOfComponents();
7837   int nbOfComp2=other->getNumberOfComponents();
7838   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7839   int *w=newArr;
7840   const int *inp1=getConstPointer();
7841   const int *inp2=other->getConstPointer();
7842   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7843     {
7844       w=std::copy(inp1,inp1+nbOfComp1,w);
7845       w=std::copy(inp2,inp2+nbOfComp2,w);
7846     }
7847   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7848   std::vector<int> compIds(nbOfComp2);
7849   for(int i=0;i<nbOfComp2;i++)
7850     compIds[i]=nbOfComp1+i;
7851   copyPartOfStringInfoFrom2(compIds,*other);
7852 }
7853
7854 /*!
7855  * Copy all components in a specified order from another DataArrayInt.
7856  * The specified components become the first ones in \a this array.
7857  * Both numerical and textual data is copied. The number of tuples in \a this and
7858  * the other array can be different.
7859  *  \param [in] a - the array to copy data from.
7860  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7861  *              to be copied.
7862  *  \throw If \a a is NULL.
7863  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7864  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7865  *
7866  *  \if ENABLE_EXAMPLES
7867  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7868  *  \endif
7869  */
7870 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7871 {
7872   if(!a)
7873     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7874   checkAllocated();
7875   a->checkAllocated();
7876   copyPartOfStringInfoFrom2(compoIds,*a);
7877   std::size_t partOfCompoSz=compoIds.size();
7878   int nbOfCompo=getNumberOfComponents();
7879   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7880   const int *ac=a->getConstPointer();
7881   int *nc=getPointer();
7882   for(int i=0;i<nbOfTuples;i++)
7883     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7884       nc[nbOfCompo*i+compoIds[j]]=*ac;
7885 }
7886
7887 /*!
7888  * Copy all values from another DataArrayInt into specified tuples and components
7889  * of \a this array. Textual data is not copied.
7890  * The tree parameters defining set of indices of tuples and components are similar to
7891  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7892  *  \param [in] a - the array to copy values from.
7893  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7894  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7895  *              are located.
7896  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7897  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7898  *  \param [in] endComp - index of the component before which the components to assign
7899  *              to are located.
7900  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7901  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7902  *              must be equal to the number of columns to assign to, else an
7903  *              exception is thrown; if \a false, then it is only required that \a
7904  *              a->getNbOfElems() equals to number of values to assign to (this condition
7905  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7906  *              values to assign to is given by following Python expression:
7907  *              \a nbTargetValues = 
7908  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7909  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7910  *  \throw If \a a is NULL.
7911  *  \throw If \a a is not allocated.
7912  *  \throw If \a this is not allocated.
7913  *  \throw If parameters specifying tuples and components to assign to do not give a
7914  *            non-empty range of increasing indices.
7915  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7916  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7917  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7918  *
7919  *  \if ENABLE_EXAMPLES
7920  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7921  *  \endif
7922  */
7923 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7924 {
7925   if(!a)
7926     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7927   const char msg[]="DataArrayInt::setPartOfValues1";
7928   checkAllocated();
7929   a->checkAllocated();
7930   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7931   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7932   int nbComp=getNumberOfComponents();
7933   int nbOfTuples=getNumberOfTuples();
7934   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7935   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7936   bool assignTech=true;
7937   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7938     {
7939       if(strictCompoCompare)
7940         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7941     }
7942   else
7943     {
7944       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7945       assignTech=false;
7946     }
7947   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7948   const int *srcPt=a->getConstPointer();
7949   if(assignTech)
7950     {
7951       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7952         for(int j=0;j<newNbOfComp;j++,srcPt++)
7953           pt[j*stepComp]=*srcPt;
7954     }
7955   else
7956     {
7957       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7958         {
7959           const int *srcPt2=srcPt;
7960           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7961             pt[j*stepComp]=*srcPt2;
7962         }
7963     }
7964 }
7965
7966 /*!
7967  * Assign a given value to values at specified tuples and components of \a this array.
7968  * The tree parameters defining set of indices of tuples and components are similar to
7969  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7970  *  \param [in] a - the value to assign.
7971  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7972  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7973  *              are located.
7974  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7975  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7976  *  \param [in] endComp - index of the component before which the components to assign
7977  *              to are located.
7978  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7979  *  \throw If \a this is not allocated.
7980  *  \throw If parameters specifying tuples and components to assign to, do not give a
7981  *            non-empty range of increasing indices or indices are out of a valid range
7982  *            for \this array.
7983  *
7984  *  \if ENABLE_EXAMPLES
7985  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7986  *  \endif
7987  */
7988 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7989 {
7990   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7991   checkAllocated();
7992   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7993   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7994   int nbComp=getNumberOfComponents();
7995   int nbOfTuples=getNumberOfTuples();
7996   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7997   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7998   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7999   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8000     for(int j=0;j<newNbOfComp;j++)
8001       pt[j*stepComp]=a;
8002 }
8003
8004
8005 /*!
8006  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8007  * components of \a this array. Textual data is not copied.
8008  * The tuples and components to assign to are defined by C arrays of indices.
8009  * There are two *modes of usage*:
8010  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8011  *   of \a a is assigned to its own location within \a this array. 
8012  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8013  *   components of every specified tuple of \a this array. In this mode it is required
8014  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8015  * 
8016  *  \param [in] a - the array to copy values from.
8017  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8018  *              assign values of \a a to.
8019  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8020  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8021  *              \a bgTuples <= \a pi < \a endTuples.
8022  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8023  *              assign values of \a a to.
8024  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8025  *              pointer to a component index <em>(pi)</em> varies as this: 
8026  *              \a bgComp <= \a pi < \a endComp.
8027  *  \param [in] strictCompoCompare - this parameter is checked only if the
8028  *               *mode of usage* is the first; if it is \a true (default), 
8029  *               then \a a->getNumberOfComponents() must be equal 
8030  *               to the number of specified columns, else this is not required.
8031  *  \throw If \a a is NULL.
8032  *  \throw If \a a is not allocated.
8033  *  \throw If \a this is not allocated.
8034  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8035  *         out of a valid range for \a this array.
8036  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8037  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8038  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8039  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8040  *
8041  *  \if ENABLE_EXAMPLES
8042  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8043  *  \endif
8044  */
8045 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8046 {
8047   if(!a)
8048     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8049   const char msg[]="DataArrayInt::setPartOfValues2";
8050   checkAllocated();
8051   a->checkAllocated();
8052   int nbComp=getNumberOfComponents();
8053   int nbOfTuples=getNumberOfTuples();
8054   for(const int *z=bgComp;z!=endComp;z++)
8055     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8056   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8057   int newNbOfComp=(int)std::distance(bgComp,endComp);
8058   bool assignTech=true;
8059   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8060     {
8061       if(strictCompoCompare)
8062         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8063     }
8064   else
8065     {
8066       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8067       assignTech=false;
8068     }
8069   int *pt=getPointer();
8070   const int *srcPt=a->getConstPointer();
8071   if(assignTech)
8072     {    
8073       for(const int *w=bgTuples;w!=endTuples;w++)
8074         {
8075           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8076           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8077             {    
8078               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8079             }
8080         }
8081     }
8082   else
8083     {
8084       for(const int *w=bgTuples;w!=endTuples;w++)
8085         {
8086           const int *srcPt2=srcPt;
8087           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8088           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8089             {    
8090               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8091             }
8092         }
8093     }
8094 }
8095
8096 /*!
8097  * Assign a given value to values at specified tuples and components of \a this array.
8098  * The tuples and components to assign to are defined by C arrays of indices.
8099  *  \param [in] a - the value to assign.
8100  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8101  *              assign \a a to.
8102  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8103  *              pointer to a tuple index (\a pi) varies as this: 
8104  *              \a bgTuples <= \a pi < \a endTuples.
8105  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8106  *              assign \a a to.
8107  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8108  *              pointer to a component index (\a pi) varies as this: 
8109  *              \a bgComp <= \a pi < \a endComp.
8110  *  \throw If \a this is not allocated.
8111  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8112  *         out of a valid range for \a this array.
8113  *
8114  *  \if ENABLE_EXAMPLES
8115  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8116  *  \endif
8117  */
8118 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8119 {
8120   checkAllocated();
8121   int nbComp=getNumberOfComponents();
8122   int nbOfTuples=getNumberOfTuples();
8123   for(const int *z=bgComp;z!=endComp;z++)
8124     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8125   int *pt=getPointer();
8126   for(const int *w=bgTuples;w!=endTuples;w++)
8127     for(const int *z=bgComp;z!=endComp;z++)
8128       {
8129         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8130         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8131       }
8132 }
8133
8134 /*!
8135  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8136  * components of \a this array. Textual data is not copied.
8137  * The tuples to assign to are defined by a C array of indices.
8138  * The components to assign to are defined by three values similar to parameters of
8139  * the Python function \c range(\c start,\c stop,\c step).
8140  * There are two *modes of usage*:
8141  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8142  *   of \a a is assigned to its own location within \a this array. 
8143  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8144  *   components of every specified tuple of \a this array. In this mode it is required
8145  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8146  *
8147  *  \param [in] a - the array to copy values from.
8148  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8149  *              assign values of \a a to.
8150  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8151  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8152  *              \a bgTuples <= \a pi < \a endTuples.
8153  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8154  *  \param [in] endComp - index of the component before which the components to assign
8155  *              to are located.
8156  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8157  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8158  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8159  *               then \a a->getNumberOfComponents() must be equal 
8160  *               to the number of specified columns, else this is not required.
8161  *  \throw If \a a is NULL.
8162  *  \throw If \a a is not allocated.
8163  *  \throw If \a this is not allocated.
8164  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8165  *         \a this array.
8166  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8167  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8168  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8169  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8170  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8171  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8172  *  \throw If parameters specifying components to assign to, do not give a
8173  *            non-empty range of increasing indices or indices are out of a valid range
8174  *            for \this array.
8175  *
8176  *  \if ENABLE_EXAMPLES
8177  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8178  *  \endif
8179  */
8180 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8181 {
8182   if(!a)
8183     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8184   const char msg[]="DataArrayInt::setPartOfValues3";
8185   checkAllocated();
8186   a->checkAllocated();
8187   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8188   int nbComp=getNumberOfComponents();
8189   int nbOfTuples=getNumberOfTuples();
8190   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8191   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8192   bool assignTech=true;
8193   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8194     {
8195       if(strictCompoCompare)
8196         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8197     }
8198   else
8199     {
8200       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8201       assignTech=false;
8202     }
8203   int *pt=getPointer()+bgComp;
8204   const int *srcPt=a->getConstPointer();
8205   if(assignTech)
8206     {
8207       for(const int *w=bgTuples;w!=endTuples;w++)
8208         for(int j=0;j<newNbOfComp;j++,srcPt++)
8209           {
8210             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8211             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8212           }
8213     }
8214   else
8215     {
8216       for(const int *w=bgTuples;w!=endTuples;w++)
8217         {
8218           const int *srcPt2=srcPt;
8219           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8220             {
8221               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8222               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8223             }
8224         }
8225     }
8226 }
8227
8228 /*!
8229  * Assign a given value to values at specified tuples and components of \a this array.
8230  * The tuples to assign to are defined by a C array of indices.
8231  * The components to assign to are defined by three values similar to parameters of
8232  * the Python function \c range(\c start,\c stop,\c step).
8233  *  \param [in] a - the value to assign.
8234  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8235  *              assign \a a to.
8236  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8237  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8238  *              \a bgTuples <= \a pi < \a endTuples.
8239  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8240  *  \param [in] endComp - index of the component before which the components to assign
8241  *              to are located.
8242  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8243  *  \throw If \a this is not allocated.
8244  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8245  *         \a this array.
8246  *  \throw If parameters specifying components to assign to, do not give a
8247  *            non-empty range of increasing indices or indices are out of a valid range
8248  *            for \this array.
8249  *
8250  *  \if ENABLE_EXAMPLES
8251  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8252  *  \endif
8253  */
8254 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8255 {
8256   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8257   checkAllocated();
8258   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8259   int nbComp=getNumberOfComponents();
8260   int nbOfTuples=getNumberOfTuples();
8261   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8262   int *pt=getPointer()+bgComp;
8263   for(const int *w=bgTuples;w!=endTuples;w++)
8264     for(int j=0;j<newNbOfComp;j++)
8265       {
8266         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8267         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8268       }
8269 }
8270
8271 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8272 {
8273   if(!a)
8274     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8275   const char msg[]="DataArrayInt::setPartOfValues4";
8276   checkAllocated();
8277   a->checkAllocated();
8278   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8279   int newNbOfComp=(int)std::distance(bgComp,endComp);
8280   int nbComp=getNumberOfComponents();
8281   for(const int *z=bgComp;z!=endComp;z++)
8282     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8283   int nbOfTuples=getNumberOfTuples();
8284   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8285   bool assignTech=true;
8286   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8287     {
8288       if(strictCompoCompare)
8289         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8290     }
8291   else
8292     {
8293       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8294       assignTech=false;
8295     }
8296   const int *srcPt=a->getConstPointer();
8297   int *pt=getPointer()+bgTuples*nbComp;
8298   if(assignTech)
8299     {
8300       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8301         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8302           pt[*z]=*srcPt;
8303     }
8304   else
8305     {
8306       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8307         {
8308           const int *srcPt2=srcPt;
8309           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8310             pt[*z]=*srcPt2;
8311         }
8312     }
8313 }
8314
8315 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8316 {
8317   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8318   checkAllocated();
8319   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8320   int nbComp=getNumberOfComponents();
8321   for(const int *z=bgComp;z!=endComp;z++)
8322     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8323   int nbOfTuples=getNumberOfTuples();
8324   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8325   int *pt=getPointer()+bgTuples*nbComp;
8326   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8327     for(const int *z=bgComp;z!=endComp;z++)
8328       pt[*z]=a;
8329 }
8330
8331 /*!
8332  * Copy some tuples from another DataArrayInt into specified tuples
8333  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8334  * components.
8335  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8336  * All components of selected tuples are copied.
8337  *  \param [in] a - the array to copy values from.
8338  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8339  *              target tuples of \a this. \a tuplesSelec has two components, and the
8340  *              first component specifies index of the source tuple and the second
8341  *              one specifies index of the target tuple.
8342  *  \throw If \a this is not allocated.
8343  *  \throw If \a a is NULL.
8344  *  \throw If \a a is not allocated.
8345  *  \throw If \a tuplesSelec is NULL.
8346  *  \throw If \a tuplesSelec is not allocated.
8347  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8348  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8349  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8350  *         the corresponding (\a this or \a a) array.
8351  */
8352 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8353 {
8354   if(!a || !tuplesSelec)
8355     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8356   checkAllocated();
8357   a->checkAllocated();
8358   tuplesSelec->checkAllocated();
8359   int nbOfComp=getNumberOfComponents();
8360   if(nbOfComp!=a->getNumberOfComponents())
8361     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8362   if(tuplesSelec->getNumberOfComponents()!=2)
8363     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8364   int thisNt=getNumberOfTuples();
8365   int aNt=a->getNumberOfTuples();
8366   int *valsToSet=getPointer();
8367   const int *valsSrc=a->getConstPointer();
8368   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8369     {
8370       if(tuple[1]>=0 && tuple[1]<aNt)
8371         {
8372           if(tuple[0]>=0 && tuple[0]<thisNt)
8373             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8374           else
8375             {
8376               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8377               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8378               throw INTERP_KERNEL::Exception(oss.str().c_str());
8379             }
8380         }
8381       else
8382         {
8383           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8384           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8385           throw INTERP_KERNEL::Exception(oss.str().c_str());
8386         }
8387     }
8388 }
8389
8390 /*!
8391  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8392  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8393  * components.
8394  * The tuples to assign to are defined by index of the first tuple, and
8395  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8396  * The tuples to copy are defined by values of a DataArrayInt.
8397  * All components of selected tuples are copied.
8398  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8399  *              values to.
8400  *  \param [in] aBase - the array to copy values from.
8401  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8402  *  \throw If \a this is not allocated.
8403  *  \throw If \a aBase is NULL.
8404  *  \throw If \a aBase is not allocated.
8405  *  \throw If \a tuplesSelec is NULL.
8406  *  \throw If \a tuplesSelec is not allocated.
8407  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8408  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8409  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8410  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8411  *         \a aBase array.
8412  */
8413 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8414 {
8415   if(!aBase || !tuplesSelec)
8416     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8417   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8418   if(!a)
8419     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8420   checkAllocated();
8421   a->checkAllocated();
8422   tuplesSelec->checkAllocated();
8423   int nbOfComp=getNumberOfComponents();
8424   if(nbOfComp!=a->getNumberOfComponents())
8425     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8426   if(tuplesSelec->getNumberOfComponents()!=1)
8427     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8428   int thisNt=getNumberOfTuples();
8429   int aNt=a->getNumberOfTuples();
8430   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8431   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8432   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8433     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8434   const int *valsSrc=a->getConstPointer();
8435   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8436     {
8437       if(*tuple>=0 && *tuple<aNt)
8438         {
8439           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8440         }
8441       else
8442         {
8443           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8444           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8445           throw INTERP_KERNEL::Exception(oss.str().c_str());
8446         }
8447     }
8448 }
8449
8450 /*!
8451  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8452  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8453  * components.
8454  * The tuples to copy are defined by three values similar to parameters of
8455  * the Python function \c range(\c start,\c stop,\c step).
8456  * The tuples to assign to are defined by index of the first tuple, and
8457  * their number is defined by number of tuples to copy.
8458  * All components of selected tuples are copied.
8459  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8460  *              values to.
8461  *  \param [in] aBase - the array to copy values from.
8462  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8463  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8464  *              are located.
8465  *  \param [in] step - index increment to get index of the next tuple to copy.
8466  *  \throw If \a this is not allocated.
8467  *  \throw If \a aBase is NULL.
8468  *  \throw If \a aBase is not allocated.
8469  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8470  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8471  *  \throw If parameters specifying tuples to copy, do not give a
8472  *            non-empty range of increasing indices or indices are out of a valid range
8473  *            for the array \a aBase.
8474  */
8475 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8476 {
8477   if(!aBase)
8478     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8479   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8480   if(!a)
8481     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8482   checkAllocated();
8483   a->checkAllocated();
8484   int nbOfComp=getNumberOfComponents();
8485   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8486   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8487   if(nbOfComp!=a->getNumberOfComponents())
8488     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8489   int thisNt=getNumberOfTuples();
8490   int aNt=a->getNumberOfTuples();
8491   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8492   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8493     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8494   if(end2>aNt)
8495     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8496   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8497   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8498     {
8499       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8500     }
8501 }
8502
8503 /*!
8504  * Returns a value located at specified tuple and component.
8505  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8506  * parameters is checked. So this method is safe but expensive if used to go through
8507  * all values of \a this.
8508  *  \param [in] tupleId - index of tuple of interest.
8509  *  \param [in] compoId - index of component of interest.
8510  *  \return double - value located by \a tupleId and \a compoId.
8511  *  \throw If \a this is not allocated.
8512  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8513  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8514  */
8515 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8516 {
8517   checkAllocated();
8518   if(tupleId<0 || tupleId>=getNumberOfTuples())
8519     {
8520       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8521       throw INTERP_KERNEL::Exception(oss.str().c_str());
8522     }
8523   if(compoId<0 || compoId>=getNumberOfComponents())
8524     {
8525       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8526       throw INTERP_KERNEL::Exception(oss.str().c_str());
8527     }
8528   return _mem[tupleId*_info_on_compo.size()+compoId];
8529 }
8530
8531 /*!
8532  * Returns the first value of \a this. 
8533  *  \return int - the last value of \a this array.
8534  *  \throw If \a this is not allocated.
8535  *  \throw If \a this->getNumberOfComponents() != 1.
8536  *  \throw If \a this->getNumberOfTuples() < 1.
8537  */
8538 int DataArrayInt::front() const
8539 {
8540   checkAllocated();
8541   if(getNumberOfComponents()!=1)
8542     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8543   int nbOfTuples=getNumberOfTuples();
8544   if(nbOfTuples<1)
8545     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8546   return *(getConstPointer());
8547 }
8548
8549 /*!
8550  * Returns the last value of \a this. 
8551  *  \return int - the last value of \a this array.
8552  *  \throw If \a this is not allocated.
8553  *  \throw If \a this->getNumberOfComponents() != 1.
8554  *  \throw If \a this->getNumberOfTuples() < 1.
8555  */
8556 int DataArrayInt::back() const
8557 {
8558   checkAllocated();
8559   if(getNumberOfComponents()!=1)
8560     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8561   int nbOfTuples=getNumberOfTuples();
8562   if(nbOfTuples<1)
8563     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8564   return *(getConstPointer()+nbOfTuples-1);
8565 }
8566
8567 /*!
8568  * Assign pointer to one array to a pointer to another appay. Reference counter of
8569  * \a arrayToSet is incremented / decremented.
8570  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8571  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8572  */
8573 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8574 {
8575   if(newArray!=arrayToSet)
8576     {
8577       if(arrayToSet)
8578         arrayToSet->decrRef();
8579       arrayToSet=newArray;
8580       if(arrayToSet)
8581         arrayToSet->incrRef();
8582     }
8583 }
8584
8585 DataArrayIntIterator *DataArrayInt::iterator()
8586 {
8587   return new DataArrayIntIterator(this);
8588 }
8589
8590 /*!
8591  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8592  * given one. The ids are sorted in the ascending order.
8593  *  \param [in] val - the value to find within \a this.
8594  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8595  *          array using decrRef() as it is no more needed.
8596  *  \throw If \a this is not allocated.
8597  *  \throw If \a this->getNumberOfComponents() != 1.
8598  *  \sa DataArrayInt::getIdsEqualTuple
8599  */
8600 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8601 {
8602   checkAllocated();
8603   if(getNumberOfComponents()!=1)
8604     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8605   const int *cptr(getConstPointer());
8606   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8607   int nbOfTuples=getNumberOfTuples();
8608   for(int i=0;i<nbOfTuples;i++,cptr++)
8609     if(*cptr==val)
8610       ret->pushBackSilent(i);
8611   return ret.retn();
8612 }
8613
8614 /*!
8615  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8616  * equal to a given one. 
8617  *  \param [in] val - the value to ignore within \a this.
8618  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8619  *          array using decrRef() as it is no more needed.
8620  *  \throw If \a this is not allocated.
8621  *  \throw If \a this->getNumberOfComponents() != 1.
8622  */
8623 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8624 {
8625   checkAllocated();
8626   if(getNumberOfComponents()!=1)
8627     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8628   const int *cptr(getConstPointer());
8629   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8630   int nbOfTuples=getNumberOfTuples();
8631   for(int i=0;i<nbOfTuples;i++,cptr++)
8632     if(*cptr!=val)
8633       ret->pushBackSilent(i);
8634   return ret.retn();
8635 }
8636
8637 /*!
8638  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8639  * This method is an extension of  DataArrayInt::getIdsEqual method.
8640  *
8641  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8642  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8643  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8644  *          array using decrRef() as it is no more needed.
8645  *  \throw If \a this is not allocated.
8646  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8647  * \throw If \a this->getNumberOfComponents() is equal to 0.
8648  * \sa DataArrayInt::getIdsEqual
8649  */
8650 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8651 {
8652   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8653   checkAllocated();
8654   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8655     {
8656       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8657       throw INTERP_KERNEL::Exception(oss.str().c_str());
8658     }
8659   if(nbOfCompoExp==0)
8660     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8661   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8662   const int *bg(begin()),*end2(end()),*work(begin());
8663   while(work!=end2)
8664     {
8665       work=std::search(work,end2,tupleBg,tupleEnd);
8666       if(work!=end2)
8667         {
8668           std::size_t pos(std::distance(bg,work));
8669           if(pos%nbOfCompoExp==0)
8670             ret->pushBackSilent(pos/nbOfCompoExp);
8671           work++;
8672         }
8673     }
8674   return ret.retn();
8675 }
8676
8677 /*!
8678  * Assigns \a newValue to all elements holding \a oldValue within \a this
8679  * one-dimensional array.
8680  *  \param [in] oldValue - the value to replace.
8681  *  \param [in] newValue - the value to assign.
8682  *  \return int - number of replacements performed.
8683  *  \throw If \a this is not allocated.
8684  *  \throw If \a this->getNumberOfComponents() != 1.
8685  */
8686 int DataArrayInt::changeValue(int oldValue, int newValue)
8687 {
8688   checkAllocated();
8689   if(getNumberOfComponents()!=1)
8690     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8691   int *start=getPointer();
8692   int *end2=start+getNbOfElems();
8693   int ret=0;
8694   for(int *val=start;val!=end2;val++)
8695     {
8696       if(*val==oldValue)
8697         {
8698           *val=newValue;
8699           ret++;
8700         }
8701     }
8702   return ret;
8703 }
8704
8705 /*!
8706  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8707  * one of given values.
8708  *  \param [in] valsBg - an array of values to find within \a this array.
8709  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8710  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8711  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8712  *          array using decrRef() as it is no more needed.
8713  *  \throw If \a this->getNumberOfComponents() != 1.
8714  */
8715 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8716 {
8717   if(getNumberOfComponents()!=1)
8718     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8719   std::set<int> vals2(valsBg,valsEnd);
8720   const int *cptr=getConstPointer();
8721   std::vector<int> res;
8722   int nbOfTuples=getNumberOfTuples();
8723   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8724   for(int i=0;i<nbOfTuples;i++,cptr++)
8725     if(vals2.find(*cptr)!=vals2.end())
8726       ret->pushBackSilent(i);
8727   return ret.retn();
8728 }
8729
8730 /*!
8731  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8732  * equal to any of given values.
8733  *  \param [in] valsBg - an array of values to ignore within \a this array.
8734  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8735  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8736  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8737  *          array using decrRef() as it is no more needed.
8738  *  \throw If \a this->getNumberOfComponents() != 1.
8739  */
8740 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8741 {
8742   if(getNumberOfComponents()!=1)
8743     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8744   std::set<int> vals2(valsBg,valsEnd);
8745   const int *cptr=getConstPointer();
8746   std::vector<int> res;
8747   int nbOfTuples=getNumberOfTuples();
8748   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8749   for(int i=0;i<nbOfTuples;i++,cptr++)
8750     if(vals2.find(*cptr)==vals2.end())
8751       ret->pushBackSilent(i);
8752   return ret.retn();
8753 }
8754
8755 /*!
8756  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8757  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8758  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8759  * If any the tuple id is returned. If not -1 is returned.
8760  * 
8761  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8762  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8763  *
8764  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8765  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8766  */
8767 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8768 {
8769   checkAllocated();
8770   int nbOfCompo=getNumberOfComponents();
8771   if(nbOfCompo==0)
8772     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8773   if(nbOfCompo!=(int)tupl.size())
8774     {
8775       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8776       throw INTERP_KERNEL::Exception(oss.str().c_str());
8777     }
8778   const int *cptr=getConstPointer();
8779   std::size_t nbOfVals=getNbOfElems();
8780   for(const int *work=cptr;work!=cptr+nbOfVals;)
8781     {
8782       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8783       if(work!=cptr+nbOfVals)
8784         {
8785           if(std::distance(cptr,work)%nbOfCompo!=0)
8786             work++;
8787           else
8788             return std::distance(cptr,work)/nbOfCompo;
8789         }
8790     }
8791   return -1;
8792 }
8793
8794 /*!
8795  * This method searches the sequence specified in input parameter \b vals in \b this.
8796  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8797  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8798  * \sa DataArrayInt::locateTuple
8799  */
8800 int DataArrayInt::search(const std::vector<int>& vals) const
8801 {
8802   checkAllocated();
8803   int nbOfCompo=getNumberOfComponents();
8804   if(nbOfCompo!=1)
8805     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8806   const int *cptr=getConstPointer();
8807   std::size_t nbOfVals=getNbOfElems();
8808   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8809   if(loc!=cptr+nbOfVals)
8810     return std::distance(cptr,loc);
8811   return -1;
8812 }
8813
8814 /*!
8815  * This method expects to be called when number of components of this is equal to one.
8816  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8817  * If not any tuple contains \b value -1 is returned.
8818  * \sa DataArrayInt::presenceOfValue
8819  */
8820 int DataArrayInt::locateValue(int value) const
8821 {
8822   checkAllocated();
8823   if(getNumberOfComponents()!=1)
8824     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8825   const int *cptr=getConstPointer();
8826   int nbOfTuples=getNumberOfTuples();
8827   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8828   if(ret!=cptr+nbOfTuples)
8829     return std::distance(cptr,ret);
8830   return -1;
8831 }
8832
8833 /*!
8834  * This method expects to be called when number of components of this is equal to one.
8835  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8836  * If not any tuple contains one of the values contained in 'vals' false is returned.
8837  * \sa DataArrayInt::presenceOfValue
8838  */
8839 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8840 {
8841   checkAllocated();
8842   if(getNumberOfComponents()!=1)
8843     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8844   std::set<int> vals2(vals.begin(),vals.end());
8845   const int *cptr=getConstPointer();
8846   int nbOfTuples=getNumberOfTuples();
8847   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8848     if(vals2.find(*w)!=vals2.end())
8849       return std::distance(cptr,w);
8850   return -1;
8851 }
8852
8853 /*!
8854  * This method returns the number of values in \a this that are equals to input parameter \a value.
8855  * This method only works for single component array.
8856  *
8857  * \return a value in [ 0, \c this->getNumberOfTuples() )
8858  *
8859  * \throw If \a this is not allocated
8860  *
8861  */
8862 int DataArrayInt::count(int value) const
8863 {
8864   int ret=0;
8865   checkAllocated();
8866   if(getNumberOfComponents()!=1)
8867     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8868   const int *vals=begin();
8869   int nbOfTuples=getNumberOfTuples();
8870   for(int i=0;i<nbOfTuples;i++,vals++)
8871     if(*vals==value)
8872       ret++;
8873   return ret;
8874 }
8875
8876 /*!
8877  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8878  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8879  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8880  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8881  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8882  * \sa DataArrayInt::locateTuple
8883  */
8884 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8885 {
8886   return locateTuple(tupl)!=-1;
8887 }
8888
8889
8890 /*!
8891  * Returns \a true if a given value is present within \a this one-dimensional array.
8892  *  \param [in] value - the value to find within \a this array.
8893  *  \return bool - \a true in case if \a value is present within \a this array.
8894  *  \throw If \a this is not allocated.
8895  *  \throw If \a this->getNumberOfComponents() != 1.
8896  *  \sa locateValue()
8897  */
8898 bool DataArrayInt::presenceOfValue(int value) const
8899 {
8900   return locateValue(value)!=-1;
8901 }
8902
8903 /*!
8904  * This method expects to be called when number of components of this is equal to one.
8905  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8906  * If not any tuple contains one of the values contained in 'vals' false is returned.
8907  * \sa DataArrayInt::locateValue
8908  */
8909 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8910 {
8911   return locateValue(vals)!=-1;
8912 }
8913
8914 /*!
8915  * Accumulates values of each component of \a this array.
8916  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8917  *         by the caller, that is filled by this method with sum value for each
8918  *         component.
8919  *  \throw If \a this is not allocated.
8920  */
8921 void DataArrayInt::accumulate(int *res) const
8922 {
8923   checkAllocated();
8924   const int *ptr=getConstPointer();
8925   int nbTuple=getNumberOfTuples();
8926   int nbComps=getNumberOfComponents();
8927   std::fill(res,res+nbComps,0);
8928   for(int i=0;i<nbTuple;i++)
8929     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8930 }
8931
8932 int DataArrayInt::accumulate(int compId) const
8933 {
8934   checkAllocated();
8935   const int *ptr=getConstPointer();
8936   int nbTuple=getNumberOfTuples();
8937   int nbComps=getNumberOfComponents();
8938   if(compId<0 || compId>=nbComps)
8939     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8940   int ret=0;
8941   for(int i=0;i<nbTuple;i++)
8942     ret+=ptr[i*nbComps+compId];
8943   return ret;
8944 }
8945
8946 /*!
8947  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8948  * The returned array will have same number of components than \a this and number of tuples equal to
8949  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8950  *
8951  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8952  *
8953  * \param [in] bgOfIndex - begin (included) of the input index array.
8954  * \param [in] endOfIndex - end (excluded) of the input index array.
8955  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8956  * 
8957  * \throw If bgOfIndex or end is NULL.
8958  * \throw If input index array is not ascendingly sorted.
8959  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8960  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8961  */
8962 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8963 {
8964   if(!bgOfIndex || !endOfIndex)
8965     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8966   checkAllocated();
8967   int nbCompo=getNumberOfComponents();
8968   int nbOfTuples=getNumberOfTuples();
8969   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8970   if(sz<1)
8971     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8972   sz--;
8973   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8974   const int *w=bgOfIndex;
8975   if(*w<0 || *w>=nbOfTuples)
8976     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8977   const int *srcPt=begin()+(*w)*nbCompo;
8978   int *tmp=ret->getPointer();
8979   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8980     {
8981       std::fill(tmp,tmp+nbCompo,0);
8982       if(w[1]>=w[0])
8983         {
8984           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8985             {
8986               if(j>=0 && j<nbOfTuples)
8987                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8988               else
8989                 {
8990                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8991                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8992                 }
8993             }
8994         }
8995       else
8996         {
8997           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8998           throw INTERP_KERNEL::Exception(oss.str().c_str());
8999         }
9000     }
9001   ret->copyStringInfoFrom(*this);
9002   return ret.retn();
9003 }
9004
9005 /*!
9006  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9007  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9008  * offsetA2</em> and (2)
9009  * the number of component in the result array is same as that of each of given arrays.
9010  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9011  * Info on components is copied from the first of the given arrays. Number of components
9012  * in the given arrays must be the same.
9013  *  \param [in] a1 - an array to include in the result array.
9014  *  \param [in] a2 - another array to include in the result array.
9015  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9016  *  \return DataArrayInt * - the new instance of DataArrayInt.
9017  *          The caller is to delete this result array using decrRef() as it is no more
9018  *          needed.
9019  *  \throw If either \a a1 or \a a2 is NULL.
9020  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9021  */
9022 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9023 {
9024   if(!a1 || !a2)
9025     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9026   int nbOfComp=a1->getNumberOfComponents();
9027   if(nbOfComp!=a2->getNumberOfComponents())
9028     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9029   int nbOfTuple1=a1->getNumberOfTuples();
9030   int nbOfTuple2=a2->getNumberOfTuples();
9031   DataArrayInt *ret=DataArrayInt::New();
9032   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9033   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9034   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9035   ret->copyStringInfoFrom(*a1);
9036   return ret;
9037 }
9038
9039 /*!
9040  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9041  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9042  * the number of component in the result array is same as that of each of given arrays.
9043  * Info on components is copied from the first of the given arrays. Number of components
9044  * in the given arrays must be  the same.
9045  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9046  * not the object itself.
9047  *  \param [in] arr - a sequence of arrays to include in the result array.
9048  *  \return DataArrayInt * - the new instance of DataArrayInt.
9049  *          The caller is to delete this result array using decrRef() as it is no more
9050  *          needed.
9051  *  \throw If all arrays within \a arr are NULL.
9052  *  \throw If getNumberOfComponents() of arrays within \a arr.
9053  */
9054 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9055 {
9056   std::vector<const DataArrayInt *> a;
9057   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9058     if(*it4)
9059       a.push_back(*it4);
9060   if(a.empty())
9061     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9062   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9063   int nbOfComp=(*it)->getNumberOfComponents();
9064   int nbt=(*it++)->getNumberOfTuples();
9065   for(int i=1;it!=a.end();it++,i++)
9066     {
9067       if((*it)->getNumberOfComponents()!=nbOfComp)
9068         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9069       nbt+=(*it)->getNumberOfTuples();
9070     }
9071   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9072   ret->alloc(nbt,nbOfComp);
9073   int *pt=ret->getPointer();
9074   for(it=a.begin();it!=a.end();it++)
9075     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9076   ret->copyStringInfoFrom(*(a[0]));
9077   return ret.retn();
9078 }
9079
9080 /*!
9081  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9082  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9083  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9084  * 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.
9085  * 
9086  * \return DataArrayInt * - a new object to be managed by the caller.
9087  */
9088 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9089 {
9090   int retSz=1;
9091   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9092     {
9093       if(*it4)
9094         {
9095           (*it4)->checkAllocated();
9096           if((*it4)->getNumberOfComponents()!=1)
9097             {
9098               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9099               throw INTERP_KERNEL::Exception(oss.str().c_str());
9100             }
9101           int nbTupl=(*it4)->getNumberOfTuples();
9102           if(nbTupl<1)
9103             {
9104               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9105               throw INTERP_KERNEL::Exception(oss.str().c_str());
9106             }
9107           if((*it4)->front()!=0)
9108             {
9109               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9110               throw INTERP_KERNEL::Exception(oss.str().c_str());
9111             }
9112           retSz+=nbTupl-1;
9113         }
9114       else
9115         {
9116           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9117           throw INTERP_KERNEL::Exception(oss.str().c_str());
9118         }
9119     }
9120   if(arrs.empty())
9121     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9123   ret->alloc(retSz,1);
9124   int *pt=ret->getPointer(); *pt++=0;
9125   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9126     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9127   ret->copyStringInfoFrom(*(arrs[0]));
9128   return ret.retn();
9129 }
9130
9131 /*!
9132  * Returns the maximal value and its location within \a this one-dimensional array.
9133  *  \param [out] tupleId - index of the tuple holding the maximal value.
9134  *  \return int - the maximal value among all values of \a this array.
9135  *  \throw If \a this->getNumberOfComponents() != 1
9136  *  \throw If \a this->getNumberOfTuples() < 1
9137  */
9138 int DataArrayInt::getMaxValue(int& tupleId) const
9139 {
9140   checkAllocated();
9141   if(getNumberOfComponents()!=1)
9142     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9143   int nbOfTuples=getNumberOfTuples();
9144   if(nbOfTuples<=0)
9145     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9146   const int *vals=getConstPointer();
9147   const int *loc=std::max_element(vals,vals+nbOfTuples);
9148   tupleId=(int)std::distance(vals,loc);
9149   return *loc;
9150 }
9151
9152 /*!
9153  * Returns the maximal value within \a this array that is allowed to have more than
9154  *  one component.
9155  *  \return int - the maximal value among all values of \a this array.
9156  *  \throw If \a this is not allocated.
9157  */
9158 int DataArrayInt::getMaxValueInArray() const
9159 {
9160   checkAllocated();
9161   const int *loc=std::max_element(begin(),end());
9162   return *loc;
9163 }
9164
9165 /*!
9166  * Returns the minimal value and its location within \a this one-dimensional array.
9167  *  \param [out] tupleId - index of the tuple holding the minimal value.
9168  *  \return int - the minimal value among all values of \a this array.
9169  *  \throw If \a this->getNumberOfComponents() != 1
9170  *  \throw If \a this->getNumberOfTuples() < 1
9171  */
9172 int DataArrayInt::getMinValue(int& tupleId) const
9173 {
9174   checkAllocated();
9175   if(getNumberOfComponents()!=1)
9176     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9177   int nbOfTuples=getNumberOfTuples();
9178   if(nbOfTuples<=0)
9179     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9180   const int *vals=getConstPointer();
9181   const int *loc=std::min_element(vals,vals+nbOfTuples);
9182   tupleId=(int)std::distance(vals,loc);
9183   return *loc;
9184 }
9185
9186 /*!
9187  * Returns the minimal value within \a this array that is allowed to have more than
9188  *  one component.
9189  *  \return int - the minimal value among all values of \a this array.
9190  *  \throw If \a this is not allocated.
9191  */
9192 int DataArrayInt::getMinValueInArray() const
9193 {
9194   checkAllocated();
9195   const int *loc=std::min_element(begin(),end());
9196   return *loc;
9197 }
9198
9199 /*!
9200  * Converts every value of \a this array to its absolute value.
9201  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9202  * should be called instead.
9203  *
9204  * \throw If \a this is not allocated.
9205  * \sa DataArrayInt::computeAbs
9206  */
9207 void DataArrayInt::abs()
9208 {
9209   checkAllocated();
9210   int *ptr(getPointer());
9211   std::size_t nbOfElems(getNbOfElems());
9212   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9213   declareAsNew();
9214 }
9215
9216 /*!
9217  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9218  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9219  *
9220  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9221  *         same number of tuples and component as \a this array.
9222  *         The caller is to delete this result array using decrRef() as it is no more
9223  *         needed.
9224  * \throw If \a this is not allocated.
9225  * \sa DataArrayInt::abs
9226  */
9227 DataArrayInt *DataArrayInt::computeAbs() const
9228 {
9229   checkAllocated();
9230   DataArrayInt *newArr(DataArrayInt::New());
9231   int nbOfTuples(getNumberOfTuples());
9232   int nbOfComp(getNumberOfComponents());
9233   newArr->alloc(nbOfTuples,nbOfComp);
9234   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9235   newArr->copyStringInfoFrom(*this);
9236   return newArr;
9237 }
9238
9239 /*!
9240  * Apply a liner function to a given component of \a this array, so that
9241  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9242  *  \param [in] a - the first coefficient of the function.
9243  *  \param [in] b - the second coefficient of the function.
9244  *  \param [in] compoId - the index of component to modify.
9245  *  \throw If \a this is not allocated.
9246  */
9247 void DataArrayInt::applyLin(int a, int b, int compoId)
9248 {
9249   checkAllocated();
9250   int *ptr=getPointer()+compoId;
9251   int nbOfComp=getNumberOfComponents();
9252   int nbOfTuple=getNumberOfTuples();
9253   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9254     *ptr=a*(*ptr)+b;
9255   declareAsNew();
9256 }
9257
9258 /*!
9259  * Apply a liner function to all elements of \a this array, so that
9260  * an element _x_ becomes \f$ a * x + b \f$.
9261  *  \param [in] a - the first coefficient of the function.
9262  *  \param [in] b - the second coefficient of the function.
9263  *  \throw If \a this is not allocated.
9264  */
9265 void DataArrayInt::applyLin(int a, int b)
9266 {
9267   checkAllocated();
9268   int *ptr=getPointer();
9269   std::size_t nbOfElems=getNbOfElems();
9270   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9271     *ptr=a*(*ptr)+b;
9272   declareAsNew();
9273 }
9274
9275 /*!
9276  * Returns a full copy of \a this array except that sign of all elements is reversed.
9277  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9278  *          same number of tuples and component as \a this array.
9279  *          The caller is to delete this result array using decrRef() as it is no more
9280  *          needed.
9281  *  \throw If \a this is not allocated.
9282  */
9283 DataArrayInt *DataArrayInt::negate() const
9284 {
9285   checkAllocated();
9286   DataArrayInt *newArr=DataArrayInt::New();
9287   int nbOfTuples=getNumberOfTuples();
9288   int nbOfComp=getNumberOfComponents();
9289   newArr->alloc(nbOfTuples,nbOfComp);
9290   const int *cptr=getConstPointer();
9291   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9292   newArr->copyStringInfoFrom(*this);
9293   return newArr;
9294 }
9295
9296 /*!
9297  * Modify all elements of \a this array, so that
9298  * an element _x_ becomes \f$ numerator / x \f$.
9299  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9300  *           array, all elements processed before detection of the zero element remain
9301  *           modified.
9302  *  \param [in] numerator - the numerator used to modify array elements.
9303  *  \throw If \a this is not allocated.
9304  *  \throw If there is an element equal to 0 in \a this array.
9305  */
9306 void DataArrayInt::applyInv(int numerator)
9307 {
9308   checkAllocated();
9309   int *ptr=getPointer();
9310   std::size_t nbOfElems=getNbOfElems();
9311   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9312     {
9313       if(*ptr!=0)
9314         {
9315           *ptr=numerator/(*ptr);
9316         }
9317       else
9318         {
9319           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9320           oss << " !";
9321           throw INTERP_KERNEL::Exception(oss.str().c_str());
9322         }
9323     }
9324   declareAsNew();
9325 }
9326
9327 /*!
9328  * Modify all elements of \a this array, so that
9329  * an element _x_ becomes \f$ x / val \f$.
9330  *  \param [in] val - the denominator used to modify array elements.
9331  *  \throw If \a this is not allocated.
9332  *  \throw If \a val == 0.
9333  */
9334 void DataArrayInt::applyDivideBy(int val)
9335 {
9336   if(val==0)
9337     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9338   checkAllocated();
9339   int *ptr=getPointer();
9340   std::size_t nbOfElems=getNbOfElems();
9341   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9342   declareAsNew();
9343 }
9344
9345 /*!
9346  * Modify all elements of \a this array, so that
9347  * an element _x_ becomes  <em> x % val </em>.
9348  *  \param [in] val - the divisor used to modify array elements.
9349  *  \throw If \a this is not allocated.
9350  *  \throw If \a val <= 0.
9351  */
9352 void DataArrayInt::applyModulus(int val)
9353 {
9354   if(val<=0)
9355     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9356   checkAllocated();
9357   int *ptr=getPointer();
9358   std::size_t nbOfElems=getNbOfElems();
9359   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9360   declareAsNew();
9361 }
9362
9363 /*!
9364  * This method works only on data array with one component.
9365  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9366  * this[*id] in [\b vmin,\b vmax)
9367  * 
9368  * \param [in] vmin begin of range. This value is included in range (included).
9369  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9370  * \return a newly allocated data array that the caller should deal with.
9371  *
9372  * \sa DataArrayInt::getIdsNotInRange
9373  */
9374 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9375 {
9376   checkAllocated();
9377   if(getNumberOfComponents()!=1)
9378     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9379   const int *cptr(begin());
9380   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9381   int nbOfTuples(getNumberOfTuples());
9382   for(int i=0;i<nbOfTuples;i++,cptr++)
9383     if(*cptr>=vmin && *cptr<vmax)
9384       ret->pushBackSilent(i);
9385   return ret.retn();
9386 }
9387
9388 /*!
9389  * This method works only on data array with one component.
9390  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9391  * this[*id] \b not in [\b vmin,\b vmax)
9392  * 
9393  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9394  * \param [in] vmax end of range. This value is included in range (included).
9395  * \return a newly allocated data array that the caller should deal with.
9396  * 
9397  * \sa DataArrayInt::getIdsInRange
9398  */
9399 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9400 {
9401   checkAllocated();
9402   if(getNumberOfComponents()!=1)
9403     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9404   const int *cptr(getConstPointer());
9405   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9406   int nbOfTuples(getNumberOfTuples());
9407   for(int i=0;i<nbOfTuples;i++,cptr++)
9408     if(*cptr<vmin || *cptr>=vmax)
9409       ret->pushBackSilent(i);
9410   return ret.retn();
9411 }
9412
9413 /*!
9414  * This method works only on data array with one component.
9415  * 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.
9416  * 
9417  * \param [in] vmin begin of range. This value is included in range (included).
9418  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9419  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9420 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9421 {
9422   checkAllocated();
9423   if(getNumberOfComponents()!=1)
9424     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9425   int nbOfTuples=getNumberOfTuples();
9426   bool ret=true;
9427   const int *cptr=getConstPointer();
9428   for(int i=0;i<nbOfTuples;i++,cptr++)
9429     {
9430       if(*cptr>=vmin && *cptr<vmax)
9431         { ret=ret && *cptr==i; }
9432       else
9433         {
9434           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9435           throw INTERP_KERNEL::Exception(oss.str().c_str());
9436         }
9437     }
9438   return ret;
9439 }
9440
9441 /*!
9442  * Modify all elements of \a this array, so that
9443  * an element _x_ becomes <em> val % x </em>.
9444  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9445  *           array, all elements processed before detection of the zero element remain
9446  *           modified.
9447  *  \param [in] val - the divident used to modify array elements.
9448  *  \throw If \a this is not allocated.
9449  *  \throw If there is an element equal to or less than 0 in \a this array.
9450  */
9451 void DataArrayInt::applyRModulus(int val)
9452 {
9453   checkAllocated();
9454   int *ptr=getPointer();
9455   std::size_t nbOfElems=getNbOfElems();
9456   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9457     {
9458       if(*ptr>0)
9459         {
9460           *ptr=val%(*ptr);
9461         }
9462       else
9463         {
9464           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9465           oss << " !";
9466           throw INTERP_KERNEL::Exception(oss.str().c_str());
9467         }
9468     }
9469   declareAsNew();
9470 }
9471
9472 /*!
9473  * Modify all elements of \a this array, so that
9474  * an element _x_ becomes <em> val ^ x </em>.
9475  *  \param [in] val - the value used to apply pow on all array elements.
9476  *  \throw If \a this is not allocated.
9477  *  \throw If \a val < 0.
9478  */
9479 void DataArrayInt::applyPow(int val)
9480 {
9481   checkAllocated();
9482   if(val<0)
9483     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9484   int *ptr=getPointer();
9485   std::size_t nbOfElems=getNbOfElems();
9486   if(val==0)
9487     {
9488       std::fill(ptr,ptr+nbOfElems,1);
9489       return ;
9490     }
9491   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9492     {
9493       int tmp=1;
9494       for(int j=0;j<val;j++)
9495         tmp*=*ptr;
9496       *ptr=tmp;
9497     }
9498   declareAsNew();
9499 }
9500
9501 /*!
9502  * Modify all elements of \a this array, so that
9503  * an element _x_ becomes \f$ val ^ x \f$.
9504  *  \param [in] val - the value used to apply pow on all array elements.
9505  *  \throw If \a this is not allocated.
9506  *  \throw If there is an element < 0 in \a this array.
9507  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9508  *           array, all elements processed before detection of the zero element remain
9509  *           modified.
9510  */
9511 void DataArrayInt::applyRPow(int val)
9512 {
9513   checkAllocated();
9514   int *ptr=getPointer();
9515   std::size_t nbOfElems=getNbOfElems();
9516   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9517     {
9518       if(*ptr>=0)
9519         {
9520           int tmp=1;
9521           for(int j=0;j<*ptr;j++)
9522             tmp*=val;
9523           *ptr=tmp;
9524         }
9525       else
9526         {
9527           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9528           oss << " !";
9529           throw INTERP_KERNEL::Exception(oss.str().c_str());
9530         }
9531     }
9532   declareAsNew();
9533 }
9534
9535 /*!
9536  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9537  * of components in the result array is a sum of the number of components of given arrays
9538  * and (2) the number of tuples in the result array is same as that of each of given
9539  * arrays. In other words the i-th tuple of result array includes all components of
9540  * i-th tuples of all given arrays.
9541  * Number of tuples in the given arrays must be the same.
9542  *  \param [in] a1 - an array to include in the result array.
9543  *  \param [in] a2 - another array to include in the result array.
9544  *  \return DataArrayInt * - the new instance of DataArrayInt.
9545  *          The caller is to delete this result array using decrRef() as it is no more
9546  *          needed.
9547  *  \throw If both \a a1 and \a a2 are NULL.
9548  *  \throw If any given array is not allocated.
9549  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9550  */
9551 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9552 {
9553   std::vector<const DataArrayInt *> arr(2);
9554   arr[0]=a1; arr[1]=a2;
9555   return Meld(arr);
9556 }
9557
9558 /*!
9559  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9560  * of components in the result array is a sum of the number of components of given arrays
9561  * and (2) the number of tuples in the result array is same as that of each of given
9562  * arrays. In other words the i-th tuple of result array includes all components of
9563  * i-th tuples of all given arrays.
9564  * Number of tuples in the given arrays must be  the same.
9565  *  \param [in] arr - a sequence of arrays to include in the result array.
9566  *  \return DataArrayInt * - the new instance of DataArrayInt.
9567  *          The caller is to delete this result array using decrRef() as it is no more
9568  *          needed.
9569  *  \throw If all arrays within \a arr are NULL.
9570  *  \throw If any given array is not allocated.
9571  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9572  */
9573 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9574 {
9575   std::vector<const DataArrayInt *> a;
9576   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9577     if(*it4)
9578       a.push_back(*it4);
9579   if(a.empty())
9580     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9581   std::vector<const DataArrayInt *>::const_iterator it;
9582   for(it=a.begin();it!=a.end();it++)
9583     (*it)->checkAllocated();
9584   it=a.begin();
9585   int nbOfTuples=(*it)->getNumberOfTuples();
9586   std::vector<int> nbc(a.size());
9587   std::vector<const int *> pts(a.size());
9588   nbc[0]=(*it)->getNumberOfComponents();
9589   pts[0]=(*it++)->getConstPointer();
9590   for(int i=1;it!=a.end();it++,i++)
9591     {
9592       if(nbOfTuples!=(*it)->getNumberOfTuples())
9593         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9594       nbc[i]=(*it)->getNumberOfComponents();
9595       pts[i]=(*it)->getConstPointer();
9596     }
9597   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9598   DataArrayInt *ret=DataArrayInt::New();
9599   ret->alloc(nbOfTuples,totalNbOfComp);
9600   int *retPtr=ret->getPointer();
9601   for(int i=0;i<nbOfTuples;i++)
9602     for(int j=0;j<(int)a.size();j++)
9603       {
9604         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9605         pts[j]+=nbc[j];
9606       }
9607   int k=0;
9608   for(int i=0;i<(int)a.size();i++)
9609     for(int j=0;j<nbc[i];j++,k++)
9610       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9611   return ret;
9612 }
9613
9614 /*!
9615  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9616  * The i-th item of the result array is an ID of a set of elements belonging to a
9617  * unique set of groups, which the i-th element is a part of. This set of elements
9618  * belonging to a unique set of groups is called \a family, so the result array contains
9619  * IDs of families each element belongs to.
9620  *
9621  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9622  * then there are 3 families:
9623  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9624  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9625  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9626  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9627  * stands for the element #3 which is in none of groups.
9628  *
9629  *  \param [in] groups - sequence of groups of element IDs.
9630  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9631  *         in \a groups.
9632  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9633  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9634  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9635  *         delete this array using decrRef() as it is no more needed.
9636  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9637  */
9638 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9639 {
9640   std::vector<const DataArrayInt *> groups2;
9641   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9642     if(*it4)
9643       groups2.push_back(*it4);
9644   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9645   ret->alloc(newNb,1);
9646   int *retPtr=ret->getPointer();
9647   std::fill(retPtr,retPtr+newNb,0);
9648   int fid=1;
9649   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9650     {
9651       const int *ptr=(*iter)->getConstPointer();
9652       std::size_t nbOfElem=(*iter)->getNbOfElems();
9653       int sfid=fid;
9654       for(int j=0;j<sfid;j++)
9655         {
9656           bool found=false;
9657           for(std::size_t i=0;i<nbOfElem;i++)
9658             {
9659               if(ptr[i]>=0 && ptr[i]<newNb)
9660                 {
9661                   if(retPtr[ptr[i]]==j)
9662                     {
9663                       retPtr[ptr[i]]=fid;
9664                       found=true;
9665                     }
9666                 }
9667               else
9668                 {
9669                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9670                   oss << ") !";
9671                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9672                 }
9673             }
9674           if(found)
9675             fid++;
9676         }
9677     }
9678   fidsOfGroups.clear();
9679   fidsOfGroups.resize(groups2.size());
9680   int grId=0;
9681   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9682     {
9683       std::set<int> tmp;
9684       const int *ptr=(*iter)->getConstPointer();
9685       std::size_t nbOfElem=(*iter)->getNbOfElems();
9686       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9687         tmp.insert(retPtr[*p]);
9688       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9689     }
9690   return ret.retn();
9691 }
9692
9693 /*!
9694  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9695  * arrays. The result array does not contain any duplicates and its values
9696  * are sorted in ascending order.
9697  *  \param [in] arr - sequence of DataArrayInt's to unite.
9698  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9699  *         array using decrRef() as it is no more needed.
9700  *  \throw If any \a arr[i] is not allocated.
9701  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9702  */
9703 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9704 {
9705   std::vector<const DataArrayInt *> a;
9706   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9707     if(*it4)
9708       a.push_back(*it4);
9709   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9710     {
9711       (*it)->checkAllocated();
9712       if((*it)->getNumberOfComponents()!=1)
9713         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9714     }
9715   //
9716   std::set<int> r;
9717   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9718     {
9719       const int *pt=(*it)->getConstPointer();
9720       int nbOfTuples=(*it)->getNumberOfTuples();
9721       r.insert(pt,pt+nbOfTuples);
9722     }
9723   DataArrayInt *ret=DataArrayInt::New();
9724   ret->alloc((int)r.size(),1);
9725   std::copy(r.begin(),r.end(),ret->getPointer());
9726   return ret;
9727 }
9728
9729 /*!
9730  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9731  * arrays. The result array does not contain any duplicates and its values
9732  * are sorted in ascending order.
9733  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9734  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9735  *         array using decrRef() as it is no more needed.
9736  *  \throw If any \a arr[i] is not allocated.
9737  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9738  */
9739 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9740 {
9741   std::vector<const DataArrayInt *> a;
9742   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9743     if(*it4)
9744       a.push_back(*it4);
9745   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9746     {
9747       (*it)->checkAllocated();
9748       if((*it)->getNumberOfComponents()!=1)
9749         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9750     }
9751   //
9752   std::set<int> r;
9753   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9754     {
9755       const int *pt=(*it)->getConstPointer();
9756       int nbOfTuples=(*it)->getNumberOfTuples();
9757       std::set<int> s1(pt,pt+nbOfTuples);
9758       if(it!=a.begin())
9759         {
9760           std::set<int> r2;
9761           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9762           r=r2;
9763         }
9764       else
9765         r=s1;
9766     }
9767   DataArrayInt *ret(DataArrayInt::New());
9768   ret->alloc((int)r.size(),1);
9769   std::copy(r.begin(),r.end(),ret->getPointer());
9770   return ret;
9771 }
9772
9773 /// @cond INTERNAL
9774 namespace ParaMEDMEMImpl
9775 {
9776   class OpSwitchedOn
9777   {
9778   public:
9779     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9780     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9781   private:
9782     int *_pt;
9783     int _cnt;
9784   };
9785
9786   class OpSwitchedOff
9787   {
9788   public:
9789     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9790     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9791   private:
9792     int *_pt;
9793     int _cnt;
9794   };
9795 }
9796 /// @endcond
9797
9798 /*!
9799  * This method returns the list of ids in ascending mode so that v[id]==true.
9800  */
9801 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9802 {
9803   int sz((int)std::count(v.begin(),v.end(),true));
9804   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9805   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
9806   return ret.retn();
9807 }
9808
9809 /*!
9810  * This method returns the list of ids in ascending mode so that v[id]==false.
9811  */
9812 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9813 {
9814   int sz((int)std::count(v.begin(),v.end(),false));
9815   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9816   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
9817   return ret.retn();
9818 }
9819
9820 /*!
9821  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9822  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9823  *
9824  * \param [in] v the input data structure to be translate into skyline format.
9825  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9826  * \param [out] dataIndex the second element of the skyline format.
9827  */
9828 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9829 {
9830   int sz((int)v.size());
9831   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9832   ret1->alloc(sz+1,1);
9833   int *pt(ret1->getPointer()); *pt=0;
9834   for(int i=0;i<sz;i++,pt++)
9835     pt[1]=pt[0]+(int)v[i].size();
9836   ret0->alloc(ret1->back(),1);
9837   pt=ret0->getPointer();
9838   for(int i=0;i<sz;i++)
9839     pt=std::copy(v[i].begin(),v[i].end(),pt);
9840   data=ret0.retn(); dataIndex=ret1.retn();
9841 }
9842
9843 /*!
9844  * Returns a new DataArrayInt which contains a complement of elements of \a this
9845  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9846  * \a nbOfElement) not present in \a this array.
9847  *  \param [in] nbOfElement - maximal size of the result array.
9848  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9849  *         array using decrRef() as it is no more needed.
9850  *  \throw If \a this is not allocated.
9851  *  \throw If \a this->getNumberOfComponents() != 1.
9852  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9853  *         nbOfElement ).
9854  */
9855 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9856 {
9857   checkAllocated();
9858   if(getNumberOfComponents()!=1)
9859     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9860   std::vector<bool> tmp(nbOfElement);
9861   const int *pt=getConstPointer();
9862   int nbOfTuples=getNumberOfTuples();
9863   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9864     if(*w>=0 && *w<nbOfElement)
9865       tmp[*w]=true;
9866     else
9867       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9868   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9869   DataArrayInt *ret=DataArrayInt::New();
9870   ret->alloc(nbOfRetVal,1);
9871   int j=0;
9872   int *retPtr=ret->getPointer();
9873   for(int i=0;i<nbOfElement;i++)
9874     if(!tmp[i])
9875       retPtr[j++]=i;
9876   return ret;
9877 }
9878
9879 /*!
9880  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9881  * from an \a other one-dimensional array.
9882  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9883  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9884  *         caller is to delete this array using decrRef() as it is no more needed.
9885  *  \throw If \a other is NULL.
9886  *  \throw If \a other is not allocated.
9887  *  \throw If \a other->getNumberOfComponents() != 1.
9888  *  \throw If \a this is not allocated.
9889  *  \throw If \a this->getNumberOfComponents() != 1.
9890  *  \sa DataArrayInt::buildSubstractionOptimized()
9891  */
9892 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9893 {
9894   if(!other)
9895     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9896   checkAllocated();
9897   other->checkAllocated();
9898   if(getNumberOfComponents()!=1)
9899     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9900   if(other->getNumberOfComponents()!=1)
9901     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9902   const int *pt=getConstPointer();
9903   int nbOfTuples=getNumberOfTuples();
9904   std::set<int> s1(pt,pt+nbOfTuples);
9905   pt=other->getConstPointer();
9906   nbOfTuples=other->getNumberOfTuples();
9907   std::set<int> s2(pt,pt+nbOfTuples);
9908   std::vector<int> r;
9909   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9910   DataArrayInt *ret=DataArrayInt::New();
9911   ret->alloc((int)r.size(),1);
9912   std::copy(r.begin(),r.end(),ret->getPointer());
9913   return ret;
9914 }
9915
9916 /*!
9917  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9918  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9919  * 
9920  * \param [in] other an array with one component and expected to be sorted ascendingly.
9921  * \ret list of ids in \a this but not in \a other.
9922  * \sa DataArrayInt::buildSubstraction
9923  */
9924 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9925 {
9926   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9927   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9928   checkAllocated(); other->checkAllocated();
9929   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9930   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9931   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
9932   const int *work1(pt1Bg),*work2(pt2Bg);
9933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9934   for(;work1!=pt1End;work1++)
9935     {
9936       if(work2!=pt2End && *work1==*work2)
9937         work2++;
9938       else
9939         ret->pushBackSilent(*work1);
9940     }
9941   return ret.retn();
9942 }
9943
9944
9945 /*!
9946  * Returns a new DataArrayInt which contains all elements of \a this and a given
9947  * one-dimensional arrays. The result array does not contain any duplicates
9948  * and its values are sorted in ascending order.
9949  *  \param [in] other - an array to unite with \a this one.
9950  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9951  *         array using decrRef() as it is no more needed.
9952  *  \throw If \a this or \a other is not allocated.
9953  *  \throw If \a this->getNumberOfComponents() != 1.
9954  *  \throw If \a other->getNumberOfComponents() != 1.
9955  */
9956 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9957 {
9958   std::vector<const DataArrayInt *>arrs(2);
9959   arrs[0]=this; arrs[1]=other;
9960   return BuildUnion(arrs);
9961 }
9962
9963
9964 /*!
9965  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9966  * one-dimensional arrays. The result array does not contain any duplicates
9967  * and its values are sorted in ascending order.
9968  *  \param [in] other - an array to intersect with \a this one.
9969  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9970  *         array using decrRef() as it is no more needed.
9971  *  \throw If \a this or \a other is not allocated.
9972  *  \throw If \a this->getNumberOfComponents() != 1.
9973  *  \throw If \a other->getNumberOfComponents() != 1.
9974  */
9975 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9976 {
9977   std::vector<const DataArrayInt *>arrs(2);
9978   arrs[0]=this; arrs[1]=other;
9979   return BuildIntersection(arrs);
9980 }
9981
9982 /*!
9983  * This method can be applied on allocated with one component DataArrayInt instance.
9984  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9985  * 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]
9986  * 
9987  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9988  * \throw if \a this is not allocated or if \a this has not exactly one component.
9989  */
9990 DataArrayInt *DataArrayInt::buildUnique() const
9991 {
9992   checkAllocated();
9993   if(getNumberOfComponents()!=1)
9994     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9995   int nbOfTuples=getNumberOfTuples();
9996   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9997   int *data=tmp->getPointer();
9998   int *last=std::unique(data,data+nbOfTuples);
9999   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10000   ret->alloc(std::distance(data,last),1);
10001   std::copy(data,last,ret->getPointer());
10002   return ret.retn();
10003 }
10004
10005 /*!
10006  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10007  * "index" array. Such "index" array is returned for example by 
10008  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
10009  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10010  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
10011  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10012  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
10013  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10014  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10015  *          The caller is to delete this array using decrRef() as it is no more needed. 
10016  *  \throw If \a this is not allocated.
10017  *  \throw If \a this->getNumberOfComponents() != 1.
10018  *  \throw If \a this->getNumberOfTuples() < 2.
10019  *
10020  *  \b Example: <br> 
10021  *         - this contains [1,3,6,7,7,9,15]
10022  *         - result array contains [2,3,1,0,2,6],
10023  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10024  *
10025  * \sa DataArrayInt::computeOffsets2
10026  */
10027 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10028 {
10029   checkAllocated();
10030   if(getNumberOfComponents()!=1)
10031     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10032   int nbOfTuples=getNumberOfTuples();
10033   if(nbOfTuples<2)
10034     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10035   const int *ptr=getConstPointer();
10036   DataArrayInt *ret=DataArrayInt::New();
10037   ret->alloc(nbOfTuples-1,1);
10038   int *out=ret->getPointer();
10039   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10040   return ret;
10041 }
10042
10043 /*!
10044  * Modifies \a this one-dimensional array so that value of each element \a x
10045  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10046  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10047  * and components remains the same.<br>
10048  * This method is useful for allToAllV in MPI with contiguous policy. This method
10049  * differs from computeOffsets2() in that the number of tuples is \b not changed by
10050  * this one.
10051  *  \throw If \a this is not allocated.
10052  *  \throw If \a this->getNumberOfComponents() != 1.
10053  *
10054  *  \b Example: <br>
10055  *          - Before \a this contains [3,5,1,2,0,8]
10056  *          - After \a this contains  [0,3,8,9,11,11]<br>
10057  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10058  *          array is retained and thus there is no space to store the last element.
10059  */
10060 void DataArrayInt::computeOffsets()
10061 {
10062   checkAllocated();
10063   if(getNumberOfComponents()!=1)
10064     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10065   int nbOfTuples=getNumberOfTuples();
10066   if(nbOfTuples==0)
10067     return ;
10068   int *work=getPointer();
10069   int tmp=work[0];
10070   work[0]=0;
10071   for(int i=1;i<nbOfTuples;i++)
10072     {
10073       int tmp2=work[i];
10074       work[i]=work[i-1]+tmp;
10075       tmp=tmp2;
10076     }
10077   declareAsNew();
10078 }
10079
10080
10081 /*!
10082  * Modifies \a this one-dimensional array so that value of each element \a x
10083  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10084  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10085  * components remains the same and number of tuples is inceamented by one.<br>
10086  * This method is useful for allToAllV in MPI with contiguous policy. This method
10087  * differs from computeOffsets() in that the number of tuples is changed by this one.
10088  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10089  *  \throw If \a this is not allocated.
10090  *  \throw If \a this->getNumberOfComponents() != 1.
10091  *
10092  *  \b Example: <br>
10093  *          - Before \a this contains [3,5,1,2,0,8]
10094  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10095  * \sa DataArrayInt::deltaShiftIndex
10096  */
10097 void DataArrayInt::computeOffsets2()
10098 {
10099   checkAllocated();
10100   if(getNumberOfComponents()!=1)
10101     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
10102   int nbOfTuples=getNumberOfTuples();
10103   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10104   if(nbOfTuples==0)
10105     return ;
10106   const int *work=getConstPointer();
10107   ret[0]=0;
10108   for(int i=0;i<nbOfTuples;i++)
10109     ret[i+1]=work[i]+ret[i];
10110   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10111   declareAsNew();
10112 }
10113
10114 /*!
10115  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10116  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10117  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10118  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10119  * filling completely one of the ranges in \a this.
10120  *
10121  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10122  * \param [out] rangeIdsFetched the range ids fetched
10123  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10124  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10125  *
10126  * \sa DataArrayInt::computeOffsets2
10127  *
10128  *  \b Example: <br>
10129  *          - \a this : [0,3,7,9,15,18]
10130  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10131  *          - \a rangeIdsFetched result array: [0,2,4]
10132  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10133  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10134  * <br>
10135  */
10136 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10137 {
10138   if(!listOfIds)
10139     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10140   listOfIds->checkAllocated(); checkAllocated();
10141   if(listOfIds->getNumberOfComponents()!=1)
10142     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10143   if(getNumberOfComponents()!=1)
10144     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10145   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10146   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10147   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10148   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10149   while(tupPtr!=tupEnd && offPtr!=offEnd)
10150     {
10151       if(*tupPtr==*offPtr)
10152         {
10153           int i=offPtr[0];
10154           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10155           if(i==offPtr[1])
10156             {
10157               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10158               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10159               offPtr++;
10160             }
10161         }
10162       else
10163         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10164     }
10165   rangeIdsFetched=ret0.retn();
10166   idsInInputListThatFetch=ret1.retn();
10167 }
10168
10169 /*!
10170  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10171  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10172  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10173  * beginning within the "iota" array. And \a this is a one-dimensional array
10174  * considered as a selector of groups described by \a offsets to include into the result array.
10175  *  \throw If \a offsets is NULL.
10176  *  \throw If \a offsets is not allocated.
10177  *  \throw If \a offsets->getNumberOfComponents() != 1.
10178  *  \throw If \a offsets is not monotonically increasing.
10179  *  \throw If \a this is not allocated.
10180  *  \throw If \a this->getNumberOfComponents() != 1.
10181  *  \throw If any element of \a this is not a valid index for \a offsets array.
10182  *
10183  *  \b Example: <br>
10184  *          - \a this: [0,2,3]
10185  *          - \a offsets: [0,3,6,10,14,20]
10186  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10187  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10188  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10189  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10190  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10191  */
10192 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10193 {
10194   if(!offsets)
10195     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10196   checkAllocated();
10197   if(getNumberOfComponents()!=1)
10198     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10199   offsets->checkAllocated();
10200   if(offsets->getNumberOfComponents()!=1)
10201     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10202   int othNbTuples=offsets->getNumberOfTuples()-1;
10203   int nbOfTuples=getNumberOfTuples();
10204   int retNbOftuples=0;
10205   const int *work=getConstPointer();
10206   const int *offPtr=offsets->getConstPointer();
10207   for(int i=0;i<nbOfTuples;i++)
10208     {
10209       int val=work[i];
10210       if(val>=0 && val<othNbTuples)
10211         {
10212           int delta=offPtr[val+1]-offPtr[val];
10213           if(delta>=0)
10214             retNbOftuples+=delta;
10215           else
10216             {
10217               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10218               throw INTERP_KERNEL::Exception(oss.str().c_str());
10219             }
10220         }
10221       else
10222         {
10223           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10224           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10225           throw INTERP_KERNEL::Exception(oss.str().c_str());
10226         }
10227     }
10228   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10229   ret->alloc(retNbOftuples,1);
10230   int *retPtr=ret->getPointer();
10231   for(int i=0;i<nbOfTuples;i++)
10232     {
10233       int val=work[i];
10234       int start=offPtr[val];
10235       int off=offPtr[val+1]-start;
10236       for(int j=0;j<off;j++,retPtr++)
10237         *retPtr=start+j;
10238     }
10239   return ret.retn();
10240 }
10241
10242 /*!
10243  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10244  * scaled array (monotonically increasing).
10245 from that of \a this and \a
10246  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10247  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10248  * beginning within the "iota" array. And \a this is a one-dimensional array
10249  * considered as a selector of groups described by \a offsets to include into the result array.
10250  *  \throw If \a  is NULL.
10251  *  \throw If \a this is not allocated.
10252  *  \throw If \a this->getNumberOfComponents() != 1.
10253  *  \throw If \a this->getNumberOfTuples() == 0.
10254  *  \throw If \a this is not monotonically increasing.
10255  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10256  *
10257  *  \b Example: <br>
10258  *          - \a bg , \a stop and \a step : (0,5,2)
10259  *          - \a this: [0,3,6,10,14,20]
10260  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10261  */
10262 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10263 {
10264   if(!isAllocated())
10265     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10266   if(getNumberOfComponents()!=1)
10267     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10268   int nbOfTuples(getNumberOfTuples());
10269   if(nbOfTuples==0)
10270     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10271   const int *ids(begin());
10272   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10273   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10274     {
10275       if(pos>=0 && pos<nbOfTuples-1)
10276         {
10277           int delta(ids[pos+1]-ids[pos]);
10278           sz+=delta;
10279           if(delta<0)
10280             {
10281               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10282               throw INTERP_KERNEL::Exception(oss.str().c_str());
10283             }          
10284         }
10285       else
10286         {
10287           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10288           throw INTERP_KERNEL::Exception(oss.str().c_str());
10289         }
10290     }
10291   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10292   int *retPtr(ret->getPointer());
10293   pos=bg;
10294   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10295     {
10296       int delta(ids[pos+1]-ids[pos]);
10297       for(int j=0;j<delta;j++,retPtr++)
10298         *retPtr=pos;
10299     }
10300   return ret.retn();
10301 }
10302
10303 /*!
10304  * 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.
10305  * 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
10306  * in tuple **i** of returned DataArrayInt.
10307  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10308  *
10309  * 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)]
10310  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10311  * 
10312  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10313  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10314  * \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
10315  *        is thrown if no ranges in \a ranges contains value in \a this.
10316  * 
10317  * \sa DataArrayInt::findIdInRangeForEachTuple
10318  */
10319 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10320 {
10321   if(!ranges)
10322     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10323   if(ranges->getNumberOfComponents()!=2)
10324     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10325   checkAllocated();
10326   if(getNumberOfComponents()!=1)
10327     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10328   int nbTuples=getNumberOfTuples();
10329   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10330   int nbOfRanges=ranges->getNumberOfTuples();
10331   const int *rangesPtr=ranges->getConstPointer();
10332   int *retPtr=ret->getPointer();
10333   const int *inPtr=getConstPointer();
10334   for(int i=0;i<nbTuples;i++,retPtr++)
10335     {
10336       int val=inPtr[i];
10337       bool found=false;
10338       for(int j=0;j<nbOfRanges && !found;j++)
10339         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10340           { *retPtr=j; found=true; }
10341       if(found)
10342         continue;
10343       else
10344         {
10345           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10346           throw INTERP_KERNEL::Exception(oss.str().c_str());
10347         }
10348     }
10349   return ret.retn();
10350 }
10351
10352 /*!
10353  * 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.
10354  * 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
10355  * in tuple **i** of returned DataArrayInt.
10356  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10357  *
10358  * 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)]
10359  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10360  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10361  * 
10362  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10363  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10364  * \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
10365  *        is thrown if no ranges in \a ranges contains value in \a this.
10366  * \sa DataArrayInt::findRangeIdForEachTuple
10367  */
10368 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10369 {
10370   if(!ranges)
10371     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10372   if(ranges->getNumberOfComponents()!=2)
10373     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10374   checkAllocated();
10375   if(getNumberOfComponents()!=1)
10376     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10377   int nbTuples=getNumberOfTuples();
10378   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10379   int nbOfRanges=ranges->getNumberOfTuples();
10380   const int *rangesPtr=ranges->getConstPointer();
10381   int *retPtr=ret->getPointer();
10382   const int *inPtr=getConstPointer();
10383   for(int i=0;i<nbTuples;i++,retPtr++)
10384     {
10385       int val=inPtr[i];
10386       bool found=false;
10387       for(int j=0;j<nbOfRanges && !found;j++)
10388         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10389           { *retPtr=val-rangesPtr[2*j]; found=true; }
10390       if(found)
10391         continue;
10392       else
10393         {
10394           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10395           throw INTERP_KERNEL::Exception(oss.str().c_str());
10396         }
10397     }
10398   return ret.retn();
10399 }
10400
10401 /*!
10402  * \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).
10403  * 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).
10404  * 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 !
10405  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10406  * This method does nothing if number of tuples is lower of equal to 1.
10407  *
10408  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10409  *
10410  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10411  */
10412 void DataArrayInt::sortEachPairToMakeALinkedList()
10413 {
10414   checkAllocated();
10415   if(getNumberOfComponents()!=2)
10416     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10417   int nbOfTuples(getNumberOfTuples());
10418   if(nbOfTuples<=1)
10419     return ;
10420   int *conn(getPointer());
10421   for(int i=1;i<nbOfTuples;i++,conn+=2)
10422     {
10423       if(i>1)
10424         {
10425           if(conn[2]==conn[3])
10426             {
10427               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10428               throw INTERP_KERNEL::Exception(oss.str().c_str());
10429             }
10430           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10431             std::swap(conn[2],conn[3]);
10432           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10433           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10434             {
10435               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10436               throw INTERP_KERNEL::Exception(oss.str().c_str());
10437             }
10438         }
10439       else
10440         {
10441           if(conn[0]==conn[1] || conn[2]==conn[3])
10442             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10443           int tmp[4];
10444           std::set<int> s;
10445           s.insert(conn,conn+4);
10446           if(s.size()!=3)
10447             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10448           if(std::count(conn,conn+4,conn[0])==2)
10449             {
10450               tmp[0]=conn[1];
10451               tmp[1]=conn[0];
10452               tmp[2]=conn[0];
10453               if(conn[2]==conn[0])
10454                 { tmp[3]=conn[3]; }
10455               else
10456                 { tmp[3]=conn[2];}
10457               std::copy(tmp,tmp+4,conn);
10458             }
10459         }
10460     }
10461 }
10462
10463 /*!
10464  * 
10465  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10466  *             \a nbTimes  should be at least equal to 1.
10467  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10468  * \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.
10469  */
10470 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10471 {
10472   checkAllocated();
10473   if(getNumberOfComponents()!=1)
10474     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10475   if(nbTimes<1)
10476     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10477   int nbTuples=getNumberOfTuples();
10478   const int *inPtr=getConstPointer();
10479   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10480   int *retPtr=ret->getPointer();
10481   for(int i=0;i<nbTuples;i++,inPtr++)
10482     {
10483       int val=*inPtr;
10484       for(int j=0;j<nbTimes;j++,retPtr++)
10485         *retPtr=val;
10486     }
10487   ret->copyStringInfoFrom(*this);
10488   return ret.retn();
10489 }
10490
10491 /*!
10492  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10493  * But the number of components can be different from one.
10494  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10495  */
10496 DataArrayInt *DataArrayInt::getDifferentValues() const
10497 {
10498   checkAllocated();
10499   std::set<int> ret;
10500   ret.insert(begin(),end());
10501   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10502   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10503   return ret2.retn();
10504 }
10505
10506 /*!
10507  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10508  * them it tells which tuple id have this id.
10509  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10510  * This method returns two arrays having same size.
10511  * 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.
10512  * 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]]
10513  */
10514 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10515 {
10516   checkAllocated();
10517   if(getNumberOfComponents()!=1)
10518     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10519   int id=0;
10520   std::map<int,int> m,m2,m3;
10521   for(const int *w=begin();w!=end();w++)
10522     m[*w]++;
10523   differentIds.resize(m.size());
10524   std::vector<DataArrayInt *> ret(m.size());
10525   std::vector<int *> retPtr(m.size());
10526   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10527     {
10528       m2[(*it).first]=id;
10529       ret[id]=DataArrayInt::New();
10530       ret[id]->alloc((*it).second,1);
10531       retPtr[id]=ret[id]->getPointer();
10532       differentIds[id]=(*it).first;
10533     }
10534   id=0;
10535   for(const int *w=begin();w!=end();w++,id++)
10536     {
10537       retPtr[m2[*w]][m3[*w]++]=id;
10538     }
10539   return ret;
10540 }
10541
10542 /*!
10543  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10544  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10545  *
10546  * \param [in] nbOfSlices - number of slices expected.
10547  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10548  * 
10549  * \sa DataArray::GetSlice
10550  * \throw If \a this is not allocated or not with exactly one component.
10551  * \throw If an element in \a this if < 0.
10552  */
10553 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10554 {
10555   if(!isAllocated() || getNumberOfComponents()!=1)
10556     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10557   if(nbOfSlices<=0)
10558     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10559   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10560   int sumPerSlc(sum/nbOfSlices),pos(0);
10561   const int *w(begin());
10562   std::vector< std::pair<int,int> > ret(nbOfSlices);
10563   for(int i=0;i<nbOfSlices;i++)
10564     {
10565       std::pair<int,int> p(pos,-1);
10566       int locSum(0);
10567       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10568       if(i!=nbOfSlices-1)
10569         p.second=pos;
10570       else
10571         p.second=nbOfTuples;
10572       ret[i]=p;
10573     }
10574   return ret;
10575 }
10576
10577 /*!
10578  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10579  * valid cases.
10580  * 1.  The arrays have same number of tuples and components. Then each value of
10581  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10582  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10583  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10584  *   component. Then
10585  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10586  * 3.  The arrays have same number of components and one array, say _a2_, has one
10587  *   tuple. Then
10588  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10589  *
10590  * Info on components is copied either from the first array (in the first case) or from
10591  * the array with maximal number of elements (getNbOfElems()).
10592  *  \param [in] a1 - an array to sum up.
10593  *  \param [in] a2 - another array to sum up.
10594  *  \return DataArrayInt * - the new instance of DataArrayInt.
10595  *          The caller is to delete this result array using decrRef() as it is no more
10596  *          needed.
10597  *  \throw If either \a a1 or \a a2 is NULL.
10598  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10599  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10600  *         none of them has number of tuples or components equal to 1.
10601  */
10602 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10603 {
10604   if(!a1 || !a2)
10605     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10606   int nbOfTuple=a1->getNumberOfTuples();
10607   int nbOfTuple2=a2->getNumberOfTuples();
10608   int nbOfComp=a1->getNumberOfComponents();
10609   int nbOfComp2=a2->getNumberOfComponents();
10610   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10611   if(nbOfTuple==nbOfTuple2)
10612     {
10613       if(nbOfComp==nbOfComp2)
10614         {
10615           ret=DataArrayInt::New();
10616           ret->alloc(nbOfTuple,nbOfComp);
10617           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10618           ret->copyStringInfoFrom(*a1);
10619         }
10620       else
10621         {
10622           int nbOfCompMin,nbOfCompMax;
10623           const DataArrayInt *aMin, *aMax;
10624           if(nbOfComp>nbOfComp2)
10625             {
10626               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10627               aMin=a2; aMax=a1;
10628             }
10629           else
10630             {
10631               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10632               aMin=a1; aMax=a2;
10633             }
10634           if(nbOfCompMin==1)
10635             {
10636               ret=DataArrayInt::New();
10637               ret->alloc(nbOfTuple,nbOfCompMax);
10638               const int *aMinPtr=aMin->getConstPointer();
10639               const int *aMaxPtr=aMax->getConstPointer();
10640               int *res=ret->getPointer();
10641               for(int i=0;i<nbOfTuple;i++)
10642                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10643               ret->copyStringInfoFrom(*aMax);
10644             }
10645           else
10646             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10647         }
10648     }
10649   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10650     {
10651       if(nbOfComp==nbOfComp2)
10652         {
10653           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10654           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10655           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10656           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10657           ret=DataArrayInt::New();
10658           ret->alloc(nbOfTupleMax,nbOfComp);
10659           int *res=ret->getPointer();
10660           for(int i=0;i<nbOfTupleMax;i++)
10661             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10662           ret->copyStringInfoFrom(*aMax);
10663         }
10664       else
10665         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10666     }
10667   else
10668     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10669   return ret.retn();
10670 }
10671
10672 /*!
10673  * Adds values of another DataArrayInt to values of \a this one. There are 3
10674  * valid cases.
10675  * 1.  The arrays have same number of tuples and components. Then each value of
10676  *   \a other array is added to the corresponding value of \a this array, i.e.:
10677  *   _a_ [ i, j ] += _other_ [ i, j ].
10678  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10679  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10680  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10681  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10682  *
10683  *  \param [in] other - an array to add to \a this one.
10684  *  \throw If \a other is NULL.
10685  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10686  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10687  *         \a other has number of both tuples and components not equal to 1.
10688  */
10689 void DataArrayInt::addEqual(const DataArrayInt *other)
10690 {
10691   if(!other)
10692     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10693   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10694   checkAllocated(); other->checkAllocated();
10695   int nbOfTuple=getNumberOfTuples();
10696   int nbOfTuple2=other->getNumberOfTuples();
10697   int nbOfComp=getNumberOfComponents();
10698   int nbOfComp2=other->getNumberOfComponents();
10699   if(nbOfTuple==nbOfTuple2)
10700     {
10701       if(nbOfComp==nbOfComp2)
10702         {
10703           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10704         }
10705       else if(nbOfComp2==1)
10706         {
10707           int *ptr=getPointer();
10708           const int *ptrc=other->getConstPointer();
10709           for(int i=0;i<nbOfTuple;i++)
10710             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10711         }
10712       else
10713         throw INTERP_KERNEL::Exception(msg);
10714     }
10715   else if(nbOfTuple2==1)
10716     {
10717       if(nbOfComp2==nbOfComp)
10718         {
10719           int *ptr=getPointer();
10720           const int *ptrc=other->getConstPointer();
10721           for(int i=0;i<nbOfTuple;i++)
10722             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10723         }
10724       else
10725         throw INTERP_KERNEL::Exception(msg);
10726     }
10727   else
10728     throw INTERP_KERNEL::Exception(msg);
10729   declareAsNew();
10730 }
10731
10732 /*!
10733  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10734  * valid cases.
10735  * 1.  The arrays have same number of tuples and components. Then each value of
10736  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10737  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10738  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10739  *   component. Then
10740  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10741  * 3.  The arrays have same number of components and one array, say _a2_, has one
10742  *   tuple. Then
10743  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10744  *
10745  * Info on components is copied either from the first array (in the first case) or from
10746  * the array with maximal number of elements (getNbOfElems()).
10747  *  \param [in] a1 - an array to subtract from.
10748  *  \param [in] a2 - an array to subtract.
10749  *  \return DataArrayInt * - the new instance of DataArrayInt.
10750  *          The caller is to delete this result array using decrRef() as it is no more
10751  *          needed.
10752  *  \throw If either \a a1 or \a a2 is NULL.
10753  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10754  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10755  *         none of them has number of tuples or components equal to 1.
10756  */
10757 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10758 {
10759   if(!a1 || !a2)
10760     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10761   int nbOfTuple1=a1->getNumberOfTuples();
10762   int nbOfTuple2=a2->getNumberOfTuples();
10763   int nbOfComp1=a1->getNumberOfComponents();
10764   int nbOfComp2=a2->getNumberOfComponents();
10765   if(nbOfTuple2==nbOfTuple1)
10766     {
10767       if(nbOfComp1==nbOfComp2)
10768         {
10769           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10770           ret->alloc(nbOfTuple2,nbOfComp1);
10771           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10772           ret->copyStringInfoFrom(*a1);
10773           return ret.retn();
10774         }
10775       else if(nbOfComp2==1)
10776         {
10777           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10778           ret->alloc(nbOfTuple1,nbOfComp1);
10779           const int *a2Ptr=a2->getConstPointer();
10780           const int *a1Ptr=a1->getConstPointer();
10781           int *res=ret->getPointer();
10782           for(int i=0;i<nbOfTuple1;i++)
10783             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10784           ret->copyStringInfoFrom(*a1);
10785           return ret.retn();
10786         }
10787       else
10788         {
10789           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10790           return 0;
10791         }
10792     }
10793   else if(nbOfTuple2==1)
10794     {
10795       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10796       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10797       ret->alloc(nbOfTuple1,nbOfComp1);
10798       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10799       int *pt=ret->getPointer();
10800       for(int i=0;i<nbOfTuple1;i++)
10801         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10802       ret->copyStringInfoFrom(*a1);
10803       return ret.retn();
10804     }
10805   else
10806     {
10807       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10808       return 0;
10809     }
10810 }
10811
10812 /*!
10813  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10814  * valid cases.
10815  * 1.  The arrays have same number of tuples and components. Then each value of
10816  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10817  *   _a_ [ i, j ] -= _other_ [ i, j ].
10818  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10819  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10820  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10821  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10822  *
10823  *  \param [in] other - an array to subtract from \a this one.
10824  *  \throw If \a other is NULL.
10825  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10826  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10827  *         \a other has number of both tuples and components not equal to 1.
10828  */
10829 void DataArrayInt::substractEqual(const DataArrayInt *other)
10830 {
10831   if(!other)
10832     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10833   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10834   checkAllocated(); other->checkAllocated();
10835   int nbOfTuple=getNumberOfTuples();
10836   int nbOfTuple2=other->getNumberOfTuples();
10837   int nbOfComp=getNumberOfComponents();
10838   int nbOfComp2=other->getNumberOfComponents();
10839   if(nbOfTuple==nbOfTuple2)
10840     {
10841       if(nbOfComp==nbOfComp2)
10842         {
10843           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10844         }
10845       else if(nbOfComp2==1)
10846         {
10847           int *ptr=getPointer();
10848           const int *ptrc=other->getConstPointer();
10849           for(int i=0;i<nbOfTuple;i++)
10850             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10851         }
10852       else
10853         throw INTERP_KERNEL::Exception(msg);
10854     }
10855   else if(nbOfTuple2==1)
10856     {
10857       int *ptr=getPointer();
10858       const int *ptrc=other->getConstPointer();
10859       for(int i=0;i<nbOfTuple;i++)
10860         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10861     }
10862   else
10863     throw INTERP_KERNEL::Exception(msg);
10864   declareAsNew();
10865 }
10866
10867 /*!
10868  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10869  * valid cases.
10870  * 1.  The arrays have same number of tuples and components. Then each value of
10871  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10872  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10873  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10874  *   component. Then
10875  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10876  * 3.  The arrays have same number of components and one array, say _a2_, has one
10877  *   tuple. Then
10878  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10879  *
10880  * Info on components is copied either from the first array (in the first case) or from
10881  * the array with maximal number of elements (getNbOfElems()).
10882  *  \param [in] a1 - a factor array.
10883  *  \param [in] a2 - another factor array.
10884  *  \return DataArrayInt * - the new instance of DataArrayInt.
10885  *          The caller is to delete this result array using decrRef() as it is no more
10886  *          needed.
10887  *  \throw If either \a a1 or \a a2 is NULL.
10888  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10889  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10890  *         none of them has number of tuples or components equal to 1.
10891  */
10892 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10893 {
10894   if(!a1 || !a2)
10895     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10896   int nbOfTuple=a1->getNumberOfTuples();
10897   int nbOfTuple2=a2->getNumberOfTuples();
10898   int nbOfComp=a1->getNumberOfComponents();
10899   int nbOfComp2=a2->getNumberOfComponents();
10900   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10901   if(nbOfTuple==nbOfTuple2)
10902     {
10903       if(nbOfComp==nbOfComp2)
10904         {
10905           ret=DataArrayInt::New();
10906           ret->alloc(nbOfTuple,nbOfComp);
10907           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10908           ret->copyStringInfoFrom(*a1);
10909         }
10910       else
10911         {
10912           int nbOfCompMin,nbOfCompMax;
10913           const DataArrayInt *aMin, *aMax;
10914           if(nbOfComp>nbOfComp2)
10915             {
10916               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10917               aMin=a2; aMax=a1;
10918             }
10919           else
10920             {
10921               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10922               aMin=a1; aMax=a2;
10923             }
10924           if(nbOfCompMin==1)
10925             {
10926               ret=DataArrayInt::New();
10927               ret->alloc(nbOfTuple,nbOfCompMax);
10928               const int *aMinPtr=aMin->getConstPointer();
10929               const int *aMaxPtr=aMax->getConstPointer();
10930               int *res=ret->getPointer();
10931               for(int i=0;i<nbOfTuple;i++)
10932                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10933               ret->copyStringInfoFrom(*aMax);
10934             }
10935           else
10936             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10937         }
10938     }
10939   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10940     {
10941       if(nbOfComp==nbOfComp2)
10942         {
10943           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10944           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10945           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10946           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10947           ret=DataArrayInt::New();
10948           ret->alloc(nbOfTupleMax,nbOfComp);
10949           int *res=ret->getPointer();
10950           for(int i=0;i<nbOfTupleMax;i++)
10951             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10952           ret->copyStringInfoFrom(*aMax);
10953         }
10954       else
10955         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10956     }
10957   else
10958     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10959   return ret.retn();
10960 }
10961
10962
10963 /*!
10964  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10965  * valid cases.
10966  * 1.  The arrays have same number of tuples and components. Then each value of
10967  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10968  *   _a_ [ i, j ] *= _other_ [ i, j ].
10969  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10970  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10971  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10972  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10973  *
10974  *  \param [in] other - an array to multiply to \a this one.
10975  *  \throw If \a other is NULL.
10976  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10977  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10978  *         \a other has number of both tuples and components not equal to 1.
10979  */
10980 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10981 {
10982   if(!other)
10983     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10984   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10985   checkAllocated(); other->checkAllocated();
10986   int nbOfTuple=getNumberOfTuples();
10987   int nbOfTuple2=other->getNumberOfTuples();
10988   int nbOfComp=getNumberOfComponents();
10989   int nbOfComp2=other->getNumberOfComponents();
10990   if(nbOfTuple==nbOfTuple2)
10991     {
10992       if(nbOfComp==nbOfComp2)
10993         {
10994           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10995         }
10996       else if(nbOfComp2==1)
10997         {
10998           int *ptr=getPointer();
10999           const int *ptrc=other->getConstPointer();
11000           for(int i=0;i<nbOfTuple;i++)
11001             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11002         }
11003       else
11004         throw INTERP_KERNEL::Exception(msg);
11005     }
11006   else if(nbOfTuple2==1)
11007     {
11008       if(nbOfComp2==nbOfComp)
11009         {
11010           int *ptr=getPointer();
11011           const int *ptrc=other->getConstPointer();
11012           for(int i=0;i<nbOfTuple;i++)
11013             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11014         }
11015       else
11016         throw INTERP_KERNEL::Exception(msg);
11017     }
11018   else
11019     throw INTERP_KERNEL::Exception(msg);
11020   declareAsNew();
11021 }
11022
11023
11024 /*!
11025  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11026  * valid cases.
11027  * 1.  The arrays have same number of tuples and components. Then each value of
11028  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11029  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11030  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11031  *   component. Then
11032  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11033  * 3.  The arrays have same number of components and one array, say _a2_, has one
11034  *   tuple. Then
11035  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11036  *
11037  * Info on components is copied either from the first array (in the first case) or from
11038  * the array with maximal number of elements (getNbOfElems()).
11039  *  \warning No check of division by zero is performed!
11040  *  \param [in] a1 - a numerator array.
11041  *  \param [in] a2 - a denominator array.
11042  *  \return DataArrayInt * - the new instance of DataArrayInt.
11043  *          The caller is to delete this result array using decrRef() as it is no more
11044  *          needed.
11045  *  \throw If either \a a1 or \a a2 is NULL.
11046  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11047  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11048  *         none of them has number of tuples or components equal to 1.
11049  */
11050 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11051 {
11052   if(!a1 || !a2)
11053     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11054   int nbOfTuple1=a1->getNumberOfTuples();
11055   int nbOfTuple2=a2->getNumberOfTuples();
11056   int nbOfComp1=a1->getNumberOfComponents();
11057   int nbOfComp2=a2->getNumberOfComponents();
11058   if(nbOfTuple2==nbOfTuple1)
11059     {
11060       if(nbOfComp1==nbOfComp2)
11061         {
11062           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11063           ret->alloc(nbOfTuple2,nbOfComp1);
11064           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11065           ret->copyStringInfoFrom(*a1);
11066           return ret.retn();
11067         }
11068       else if(nbOfComp2==1)
11069         {
11070           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11071           ret->alloc(nbOfTuple1,nbOfComp1);
11072           const int *a2Ptr=a2->getConstPointer();
11073           const int *a1Ptr=a1->getConstPointer();
11074           int *res=ret->getPointer();
11075           for(int i=0;i<nbOfTuple1;i++)
11076             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11077           ret->copyStringInfoFrom(*a1);
11078           return ret.retn();
11079         }
11080       else
11081         {
11082           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11083           return 0;
11084         }
11085     }
11086   else if(nbOfTuple2==1)
11087     {
11088       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11089       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11090       ret->alloc(nbOfTuple1,nbOfComp1);
11091       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11092       int *pt=ret->getPointer();
11093       for(int i=0;i<nbOfTuple1;i++)
11094         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11095       ret->copyStringInfoFrom(*a1);
11096       return ret.retn();
11097     }
11098   else
11099     {
11100       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11101       return 0;
11102     }
11103 }
11104
11105 /*!
11106  * Divide values of \a this array by values of another DataArrayInt. There are 3
11107  * valid cases.
11108  * 1.  The arrays have same number of tuples and components. Then each value of
11109  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11110  *   _a_ [ i, j ] /= _other_ [ i, j ].
11111  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11112  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11113  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11114  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11115  *
11116  *  \warning No check of division by zero is performed!
11117  *  \param [in] other - an array to divide \a this one by.
11118  *  \throw If \a other is NULL.
11119  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11120  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11121  *         \a other has number of both tuples and components not equal to 1.
11122  */
11123 void DataArrayInt::divideEqual(const DataArrayInt *other)
11124 {
11125   if(!other)
11126     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11127   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11128   checkAllocated(); other->checkAllocated();
11129   int nbOfTuple=getNumberOfTuples();
11130   int nbOfTuple2=other->getNumberOfTuples();
11131   int nbOfComp=getNumberOfComponents();
11132   int nbOfComp2=other->getNumberOfComponents();
11133   if(nbOfTuple==nbOfTuple2)
11134     {
11135       if(nbOfComp==nbOfComp2)
11136         {
11137           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11138         }
11139       else if(nbOfComp2==1)
11140         {
11141           int *ptr=getPointer();
11142           const int *ptrc=other->getConstPointer();
11143           for(int i=0;i<nbOfTuple;i++)
11144             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11145         }
11146       else
11147         throw INTERP_KERNEL::Exception(msg);
11148     }
11149   else if(nbOfTuple2==1)
11150     {
11151       if(nbOfComp2==nbOfComp)
11152         {
11153           int *ptr=getPointer();
11154           const int *ptrc=other->getConstPointer();
11155           for(int i=0;i<nbOfTuple;i++)
11156             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11157         }
11158       else
11159         throw INTERP_KERNEL::Exception(msg);
11160     }
11161   else
11162     throw INTERP_KERNEL::Exception(msg);
11163   declareAsNew();
11164 }
11165
11166
11167 /*!
11168  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11169  * valid cases.
11170  * 1.  The arrays have same number of tuples and components. Then each value of
11171  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11172  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11173  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11174  *   component. Then
11175  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11176  * 3.  The arrays have same number of components and one array, say _a2_, has one
11177  *   tuple. Then
11178  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11179  *
11180  * Info on components is copied either from the first array (in the first case) or from
11181  * the array with maximal number of elements (getNbOfElems()).
11182  *  \warning No check of division by zero is performed!
11183  *  \param [in] a1 - a dividend array.
11184  *  \param [in] a2 - a divisor array.
11185  *  \return DataArrayInt * - the new instance of DataArrayInt.
11186  *          The caller is to delete this result array using decrRef() as it is no more
11187  *          needed.
11188  *  \throw If either \a a1 or \a a2 is NULL.
11189  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11190  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11191  *         none of them has number of tuples or components equal to 1.
11192  */
11193 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11194 {
11195   if(!a1 || !a2)
11196     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11197   int nbOfTuple1=a1->getNumberOfTuples();
11198   int nbOfTuple2=a2->getNumberOfTuples();
11199   int nbOfComp1=a1->getNumberOfComponents();
11200   int nbOfComp2=a2->getNumberOfComponents();
11201   if(nbOfTuple2==nbOfTuple1)
11202     {
11203       if(nbOfComp1==nbOfComp2)
11204         {
11205           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11206           ret->alloc(nbOfTuple2,nbOfComp1);
11207           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11208           ret->copyStringInfoFrom(*a1);
11209           return ret.retn();
11210         }
11211       else if(nbOfComp2==1)
11212         {
11213           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11214           ret->alloc(nbOfTuple1,nbOfComp1);
11215           const int *a2Ptr=a2->getConstPointer();
11216           const int *a1Ptr=a1->getConstPointer();
11217           int *res=ret->getPointer();
11218           for(int i=0;i<nbOfTuple1;i++)
11219             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11220           ret->copyStringInfoFrom(*a1);
11221           return ret.retn();
11222         }
11223       else
11224         {
11225           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11226           return 0;
11227         }
11228     }
11229   else if(nbOfTuple2==1)
11230     {
11231       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11232       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11233       ret->alloc(nbOfTuple1,nbOfComp1);
11234       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11235       int *pt=ret->getPointer();
11236       for(int i=0;i<nbOfTuple1;i++)
11237         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11238       ret->copyStringInfoFrom(*a1);
11239       return ret.retn();
11240     }
11241   else
11242     {
11243       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11244       return 0;
11245     }
11246 }
11247
11248 /*!
11249  * Modify \a this array so that each value becomes a modulus of division of this value by
11250  * a value of another DataArrayInt. There are 3 valid cases.
11251  * 1.  The arrays have same number of tuples and components. Then each value of
11252  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11253  *   _a_ [ i, j ] %= _other_ [ i, j ].
11254  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11255  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11256  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11257  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11258  *
11259  *  \warning No check of division by zero is performed!
11260  *  \param [in] other - a divisor array.
11261  *  \throw If \a other is NULL.
11262  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11263  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11264  *         \a other has number of both tuples and components not equal to 1.
11265  */
11266 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11267 {
11268   if(!other)
11269     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11270   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11271   checkAllocated(); other->checkAllocated();
11272   int nbOfTuple=getNumberOfTuples();
11273   int nbOfTuple2=other->getNumberOfTuples();
11274   int nbOfComp=getNumberOfComponents();
11275   int nbOfComp2=other->getNumberOfComponents();
11276   if(nbOfTuple==nbOfTuple2)
11277     {
11278       if(nbOfComp==nbOfComp2)
11279         {
11280           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11281         }
11282       else if(nbOfComp2==1)
11283         {
11284           if(nbOfComp2==nbOfComp)
11285             {
11286               int *ptr=getPointer();
11287               const int *ptrc=other->getConstPointer();
11288               for(int i=0;i<nbOfTuple;i++)
11289                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11290             }
11291           else
11292             throw INTERP_KERNEL::Exception(msg);
11293         }
11294       else
11295         throw INTERP_KERNEL::Exception(msg);
11296     }
11297   else if(nbOfTuple2==1)
11298     {
11299       int *ptr=getPointer();
11300       const int *ptrc=other->getConstPointer();
11301       for(int i=0;i<nbOfTuple;i++)
11302         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11303     }
11304   else
11305     throw INTERP_KERNEL::Exception(msg);
11306   declareAsNew();
11307 }
11308
11309 /*!
11310  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11311  * valid cases.
11312  *
11313  *  \param [in] a1 - an array to pow up.
11314  *  \param [in] a2 - another array to sum up.
11315  *  \return DataArrayInt * - the new instance of DataArrayInt.
11316  *          The caller is to delete this result array using decrRef() as it is no more
11317  *          needed.
11318  *  \throw If either \a a1 or \a a2 is NULL.
11319  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11320  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11321  *  \throw If there is a negative value in \a a2.
11322  */
11323 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11324 {
11325   if(!a1 || !a2)
11326     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11327   int nbOfTuple=a1->getNumberOfTuples();
11328   int nbOfTuple2=a2->getNumberOfTuples();
11329   int nbOfComp=a1->getNumberOfComponents();
11330   int nbOfComp2=a2->getNumberOfComponents();
11331   if(nbOfTuple!=nbOfTuple2)
11332     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11333   if(nbOfComp!=1 || nbOfComp2!=1)
11334     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11335   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11336   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11337   int *ptr=ret->getPointer();
11338   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11339     {
11340       if(*ptr2>=0)
11341         {
11342           int tmp=1;
11343           for(int j=0;j<*ptr2;j++)
11344             tmp*=*ptr1;
11345           *ptr=tmp;
11346         }
11347       else
11348         {
11349           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11350           throw INTERP_KERNEL::Exception(oss.str().c_str());
11351         }
11352     }
11353   return ret.retn();
11354 }
11355
11356 /*!
11357  * Apply pow on values of another DataArrayInt to values of \a this one.
11358  *
11359  *  \param [in] other - an array to pow to \a this one.
11360  *  \throw If \a other is NULL.
11361  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11362  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11363  *  \throw If there is a negative value in \a other.
11364  */
11365 void DataArrayInt::powEqual(const DataArrayInt *other)
11366 {
11367   if(!other)
11368     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11369   int nbOfTuple=getNumberOfTuples();
11370   int nbOfTuple2=other->getNumberOfTuples();
11371   int nbOfComp=getNumberOfComponents();
11372   int nbOfComp2=other->getNumberOfComponents();
11373   if(nbOfTuple!=nbOfTuple2)
11374     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11375   if(nbOfComp!=1 || nbOfComp2!=1)
11376     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11377   int *ptr=getPointer();
11378   const int *ptrc=other->begin();
11379   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11380     {
11381       if(*ptrc>=0)
11382         {
11383           int tmp=1;
11384           for(int j=0;j<*ptrc;j++)
11385             tmp*=*ptr;
11386           *ptr=tmp;
11387         }
11388       else
11389         {
11390           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11391           throw INTERP_KERNEL::Exception(oss.str().c_str());
11392         }
11393     }
11394   declareAsNew();
11395 }
11396
11397 /*!
11398  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11399  * This map, if applied to \a start array, would make it sorted. For example, if
11400  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11401  * [5,6,0,3,2,7,1,4].
11402  *  \param [in] start - pointer to the first element of the array for which the
11403  *         permutation map is computed.
11404  *  \param [in] end - pointer specifying the end of the array \a start, so that
11405  *         the last value of \a start is \a end[ -1 ].
11406  *  \return int * - the result permutation array that the caller is to delete as it is no
11407  *         more needed.
11408  *  \throw If there are equal values in the input array.
11409  */
11410 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11411 {
11412   std::size_t sz=std::distance(start,end);
11413   int *ret=(int *)malloc(sz*sizeof(int));
11414   int *work=new int[sz];
11415   std::copy(start,end,work);
11416   std::sort(work,work+sz);
11417   if(std::unique(work,work+sz)!=work+sz)
11418     {
11419       delete [] work;
11420       free(ret);
11421       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11422     }
11423   std::map<int,int> m;
11424   for(int *workPt=work;workPt!=work+sz;workPt++)
11425     m[*workPt]=(int)std::distance(work,workPt);
11426   int *iter2=ret;
11427   for(const int *iter=start;iter!=end;iter++,iter2++)
11428     *iter2=m[*iter];
11429   delete [] work;
11430   return ret;
11431 }
11432
11433 /*!
11434  * Returns a new DataArrayInt containing an arithmetic progression
11435  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11436  * function.
11437  *  \param [in] begin - the start value of the result sequence.
11438  *  \param [in] end - limiting value, so that every value of the result array is less than
11439  *              \a end.
11440  *  \param [in] step - specifies the increment or decrement.
11441  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11442  *          array using decrRef() as it is no more needed.
11443  *  \throw If \a step == 0.
11444  *  \throw If \a end < \a begin && \a step > 0.
11445  *  \throw If \a end > \a begin && \a step < 0.
11446  */
11447 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11448 {
11449   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11450   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11451   ret->alloc(nbOfTuples,1);
11452   int *ptr=ret->getPointer();
11453   if(step>0)
11454     {
11455       for(int i=begin;i<end;i+=step,ptr++)
11456         *ptr=i;
11457     }
11458   else
11459     {
11460       for(int i=begin;i>end;i+=step,ptr++)
11461         *ptr=i;
11462     }
11463   return ret.retn();
11464 }
11465
11466 /*!
11467  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11468  * Server side.
11469  */
11470 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11471 {
11472   tinyInfo.resize(2);
11473   if(isAllocated())
11474     {
11475       tinyInfo[0]=getNumberOfTuples();
11476       tinyInfo[1]=getNumberOfComponents();
11477     }
11478   else
11479     {
11480       tinyInfo[0]=-1;
11481       tinyInfo[1]=-1;
11482     }
11483 }
11484
11485 /*!
11486  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11487  * Server side.
11488  */
11489 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11490 {
11491   if(isAllocated())
11492     {
11493       int nbOfCompo=getNumberOfComponents();
11494       tinyInfo.resize(nbOfCompo+1);
11495       tinyInfo[0]=getName();
11496       for(int i=0;i<nbOfCompo;i++)
11497         tinyInfo[i+1]=getInfoOnComponent(i);
11498     }
11499   else
11500     {
11501       tinyInfo.resize(1);
11502       tinyInfo[0]=getName();
11503     }
11504 }
11505
11506 /*!
11507  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11508  * This method returns if a feeding is needed.
11509  */
11510 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11511 {
11512   int nbOfTuple=tinyInfoI[0];
11513   int nbOfComp=tinyInfoI[1];
11514   if(nbOfTuple!=-1 || nbOfComp!=-1)
11515     {
11516       alloc(nbOfTuple,nbOfComp);
11517       return true;
11518     }
11519   return false;
11520 }
11521
11522 /*!
11523  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11524  * This method returns if a feeding is needed.
11525  */
11526 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11527 {
11528   setName(tinyInfoS[0]);
11529   if(isAllocated())
11530     {
11531       int nbOfCompo=tinyInfoI[1];
11532       for(int i=0;i<nbOfCompo;i++)
11533         setInfoOnComponent(i,tinyInfoS[i+1]);
11534     }
11535 }
11536
11537 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11538 {
11539   if(_da)
11540     {
11541       _da->incrRef();
11542       if(_da->isAllocated())
11543         {
11544           _nb_comp=da->getNumberOfComponents();
11545           _nb_tuple=da->getNumberOfTuples();
11546           _pt=da->getPointer();
11547         }
11548     }
11549 }
11550
11551 DataArrayIntIterator::~DataArrayIntIterator()
11552 {
11553   if(_da)
11554     _da->decrRef();
11555 }
11556
11557 DataArrayIntTuple *DataArrayIntIterator::nextt()
11558 {
11559   if(_tuple_id<_nb_tuple)
11560     {
11561       _tuple_id++;
11562       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11563       _pt+=_nb_comp;
11564       return ret;
11565     }
11566   else
11567     return 0;
11568 }
11569
11570 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11571 {
11572 }
11573
11574 std::string DataArrayIntTuple::repr() const
11575 {
11576   std::ostringstream oss; oss << "(";
11577   for(int i=0;i<_nb_of_compo-1;i++)
11578     oss << _pt[i] << ", ";
11579   oss << _pt[_nb_of_compo-1] << ")";
11580   return oss.str();
11581 }
11582
11583 int DataArrayIntTuple::intValue() const
11584 {
11585   if(_nb_of_compo==1)
11586     return *_pt;
11587   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11588 }
11589
11590 /*!
11591  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11592  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11593  * 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
11594  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11595  */
11596 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11597 {
11598   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11599     {
11600       DataArrayInt *ret=DataArrayInt::New();
11601       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11602       return ret;
11603     }
11604   else
11605     {
11606       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11607       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11608       throw INTERP_KERNEL::Exception(oss.str().c_str());
11609     }
11610 }