Salome HOME
Merge branch 'abn/tests_from_build'
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const std::string& name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const std::string& varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * This method put in info format the result of the merge of \a var and \a unit.
427  * The standard format for that is "var [unit]".
428  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
429  */
430 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
431 {
432   std::ostringstream oss;
433   oss << var << " [" << unit << "]";
434   return oss.str();
435 }
436
437 /*!
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 \c 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  * \sa reprNotTooLong, reprZip
1152  */
1153 std::string DataArrayDouble::repr() const
1154 {
1155   std::ostringstream ret;
1156   reprStream(ret);
1157   return ret.str();
1158 }
1159
1160 std::string DataArrayDouble::reprZip() const
1161 {
1162   std::ostringstream ret;
1163   reprZipStream(ret);
1164   return ret.str();
1165 }
1166
1167 /*!
1168  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
1169  * printed out to avoid to consume too much space in interpretor.
1170  * \sa repr
1171  */
1172 std::string DataArrayDouble::reprNotTooLong() const
1173 {
1174   std::ostringstream ret;
1175   reprNotTooLongStream(ret);
1176   return ret.str();
1177 }
1178
1179 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1180 {
1181   static const char SPACE[4]={' ',' ',' ',' '};
1182   checkAllocated();
1183   std::string idt(indent,' ');
1184   ofs.precision(17);
1185   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1186   //
1187   bool areAllEmpty(true);
1188   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
1189     if(!(*it).empty())
1190       areAllEmpty=false;
1191   if(!areAllEmpty)
1192     for(std::size_t i=0;i<_info_on_compo.size();i++)
1193       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
1194   //
1195   if(byteArr)
1196     {
1197       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1198       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1199       float *pt(tmp);
1200       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1201       for(const double *src=begin();src!=end();src++,pt++)
1202         *pt=float(*src);
1203       const char *data(reinterpret_cast<const char *>((float *)tmp));
1204       std::size_t sz(getNbOfElems()*sizeof(float));
1205       byteArr->insertAtTheEnd(data,data+sz);
1206       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1207     }
1208   else
1209     {
1210       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1211       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1212     }
1213   ofs << std::endl << idt << "</DataArray>\n";
1214 }
1215
1216 void DataArrayDouble::reprStream(std::ostream& stream) const
1217 {
1218   stream << "Name of double array : \"" << _name << "\"\n";
1219   reprWithoutNameStream(stream);
1220 }
1221
1222 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1223 {
1224   stream << "Name of double array : \"" << _name << "\"\n";
1225   reprZipWithoutNameStream(stream);
1226 }
1227
1228 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1229 {
1230   stream << "Name of double array : \"" << _name << "\"\n";
1231   reprNotTooLongWithoutNameStream(stream);
1232 }
1233
1234 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1235 {
1236   DataArray::reprWithoutNameStream(stream);
1237   stream.precision(17);
1238   _mem.repr(getNumberOfComponents(),stream);
1239 }
1240
1241 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1242 {
1243   DataArray::reprWithoutNameStream(stream);
1244   stream.precision(17);
1245   _mem.reprZip(getNumberOfComponents(),stream);
1246 }
1247
1248 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1249 {
1250   DataArray::reprWithoutNameStream(stream);
1251   stream.precision(17);
1252   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1253 }
1254
1255 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1256 {
1257   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1258   const double *data=getConstPointer();
1259   stream.precision(17);
1260   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1261   if(nbTuples*nbComp>=1)
1262     {
1263       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1264       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1265       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1266       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1267     }
1268   else
1269     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1270   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1271 }
1272
1273 /*!
1274  * Method that gives a quick overvien of \a this for python.
1275  */
1276 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1277 {
1278   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1279   stream << "DataArrayDouble C++ instance at " << this << ". ";
1280   if(isAllocated())
1281     {
1282       int nbOfCompo=(int)_info_on_compo.size();
1283       if(nbOfCompo>=1)
1284         {
1285           int nbOfTuples=getNumberOfTuples();
1286           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1287           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1288         }
1289       else
1290         stream << "Number of components : 0.";
1291     }
1292   else
1293     stream << "*** No data allocated ****";
1294 }
1295
1296 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1297 {
1298   const double *data=begin();
1299   int nbOfTuples=getNumberOfTuples();
1300   int nbOfCompo=(int)_info_on_compo.size();
1301   std::ostringstream oss2; oss2 << "[";
1302   oss2.precision(17);
1303   std::string oss2Str(oss2.str());
1304   bool isFinished=true;
1305   for(int i=0;i<nbOfTuples && isFinished;i++)
1306     {
1307       if(nbOfCompo>1)
1308         {
1309           oss2 << "(";
1310           for(int j=0;j<nbOfCompo;j++,data++)
1311             {
1312               oss2 << *data;
1313               if(j!=nbOfCompo-1) oss2 << ", ";
1314             }
1315           oss2 << ")";
1316         }
1317       else
1318         oss2 << *data++;
1319       if(i!=nbOfTuples-1) oss2 << ", ";
1320       std::string oss3Str(oss2.str());
1321       if(oss3Str.length()<maxNbOfByteInRepr)
1322         oss2Str=oss3Str;
1323       else
1324         isFinished=false;
1325     }
1326   stream << oss2Str;
1327   if(!isFinished)
1328     stream << "... ";
1329   stream << "]";
1330 }
1331
1332 /*!
1333  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1334  * mismatch is given.
1335  * 
1336  * \param [in] other the instance to be compared with \a this
1337  * \param [in] prec the precision to compare numeric data of the arrays.
1338  * \param [out] reason In case of inequality returns the reason.
1339  * \sa DataArrayDouble::isEqual
1340  */
1341 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1342 {
1343   if(!areInfoEqualsIfNotWhy(other,reason))
1344     return false;
1345   return _mem.isEqual(other._mem,prec,reason);
1346 }
1347
1348 /*!
1349  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1350  * \ref MEDCouplingArrayBasicsCompare.
1351  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1352  *  \param [in] prec - precision value to compare numeric data of the arrays.
1353  *  \return bool - \a true if the two arrays are equal, \a false else.
1354  */
1355 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1356 {
1357   std::string tmp;
1358   return isEqualIfNotWhy(other,prec,tmp);
1359 }
1360
1361 /*!
1362  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1363  * \ref MEDCouplingArrayBasicsCompare.
1364  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1365  *  \param [in] prec - precision value to compare numeric data of the arrays.
1366  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1367  */
1368 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1369 {
1370   std::string tmp;
1371   return _mem.isEqual(other._mem,prec,tmp);
1372 }
1373
1374 /*!
1375  * Changes number of tuples in the array. If the new number of tuples is smaller
1376  * than the current number the array is truncated, otherwise the array is extended.
1377  *  \param [in] nbOfTuples - new number of tuples. 
1378  *  \throw If \a this is not allocated.
1379  *  \throw If \a nbOfTuples is negative.
1380  */
1381 void DataArrayDouble::reAlloc(int nbOfTuples)
1382 {
1383   if(nbOfTuples<0)
1384     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1385   checkAllocated();
1386   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1387   declareAsNew();
1388 }
1389
1390 /*!
1391  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1392  * array to the new one.
1393  *  \return DataArrayInt * - the new instance of DataArrayInt.
1394  */
1395 DataArrayInt *DataArrayDouble::convertToIntArr() const
1396 {
1397   DataArrayInt *ret=DataArrayInt::New();
1398   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1399   int *dest=ret->getPointer();
1400   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1401   for(const double *src=begin();src!=end();src++,dest++)
1402     *dest=(int)*src;
1403   ret->copyStringInfoFrom(*this);
1404   return ret;
1405 }
1406
1407 /*!
1408  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1409  * arranged in memory. If \a this array holds 2 components of 3 values:
1410  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1411  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1412  *  \warning Do not confuse this method with transpose()!
1413  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1414  *          is to delete using decrRef() as it is no more needed.
1415  *  \throw If \a this is not allocated.
1416  */
1417 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1418 {
1419   if(_mem.isNull())
1420     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1421   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1422   DataArrayDouble *ret=DataArrayDouble::New();
1423   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1424   return ret;
1425 }
1426
1427 /*!
1428  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1429  * arranged in memory. If \a this array holds 2 components of 3 values:
1430  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1431  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1432  *  \warning Do not confuse this method with transpose()!
1433  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1434  *          is to delete using decrRef() as it is no more needed.
1435  *  \throw If \a this is not allocated.
1436  */
1437 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1438 {
1439   if(_mem.isNull())
1440     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1441   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1442   DataArrayDouble *ret=DataArrayDouble::New();
1443   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1444   return ret;
1445 }
1446
1447 /*!
1448  * Permutes values of \a this array as required by \a old2New array. The values are
1449  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1450  * the same as in \c this one.
1451  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1452  * For more info on renumbering see \ref numbering.
1453  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1454  *     giving a new position for i-th old value.
1455  */
1456 void DataArrayDouble::renumberInPlace(const int *old2New)
1457 {
1458   checkAllocated();
1459   int nbTuples=getNumberOfTuples();
1460   int nbOfCompo=getNumberOfComponents();
1461   double *tmp=new double[nbTuples*nbOfCompo];
1462   const double *iptr=getConstPointer();
1463   for(int i=0;i<nbTuples;i++)
1464     {
1465       int v=old2New[i];
1466       if(v>=0 && v<nbTuples)
1467         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1468       else
1469         {
1470           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1471           throw INTERP_KERNEL::Exception(oss.str().c_str());
1472         }
1473     }
1474   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1475   delete [] tmp;
1476   declareAsNew();
1477 }
1478
1479 /*!
1480  * Permutes values of \a this array as required by \a new2Old array. The values are
1481  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1482  * the same as in \c this one.
1483  * For more info on renumbering see \ref numbering.
1484  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1485  *     giving a previous position of i-th new value.
1486  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1487  *          is to delete using decrRef() as it is no more needed.
1488  */
1489 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1490 {
1491   checkAllocated();
1492   int nbTuples=getNumberOfTuples();
1493   int nbOfCompo=getNumberOfComponents();
1494   double *tmp=new double[nbTuples*nbOfCompo];
1495   const double *iptr=getConstPointer();
1496   for(int i=0;i<nbTuples;i++)
1497     {
1498       int v=new2Old[i];
1499       if(v>=0 && v<nbTuples)
1500         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1501       else
1502         {
1503           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1504           throw INTERP_KERNEL::Exception(oss.str().c_str());
1505         }
1506     }
1507   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1508   delete [] tmp;
1509   declareAsNew();
1510 }
1511
1512 /*!
1513  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1514  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1515  * Number of tuples in the result array remains the same as in \c this one.
1516  * If a permutation reduction is needed, renumberAndReduce() should be used.
1517  * For more info on renumbering see \ref numbering.
1518  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1519  *          giving a new position for i-th old value.
1520  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1521  *          is to delete using decrRef() as it is no more needed.
1522  *  \throw If \a this is not allocated.
1523  */
1524 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) 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*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1536   ret->copyStringInfoFrom(*this);
1537   return ret.retn();
1538 }
1539
1540 /*!
1541  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1542  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1543  * tuples in the result array remains the same as in \c this one.
1544  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1545  * For more info on renumbering see \ref numbering.
1546  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1547  *     giving a previous position of i-th new value.
1548  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1549  *          is to delete using decrRef() as it is no more needed.
1550  */
1551 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1552 {
1553   checkAllocated();
1554   int nbTuples=getNumberOfTuples();
1555   int nbOfCompo=getNumberOfComponents();
1556   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1557   ret->alloc(nbTuples,nbOfCompo);
1558   ret->copyStringInfoFrom(*this);
1559   const double *iptr=getConstPointer();
1560   double *optr=ret->getPointer();
1561   for(int i=0;i<nbTuples;i++)
1562     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1563   ret->copyStringInfoFrom(*this);
1564   return ret.retn();
1565 }
1566
1567 /*!
1568  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1569  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1570  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1571  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1572  * \a old2New[ i ] is negative, is missing from the result array.
1573  * For more info on renumbering see \ref numbering.
1574  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1575  *     giving a new position for i-th old tuple and giving negative position for
1576  *     for i-th old tuple that should be omitted.
1577  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1578  *          is to delete using decrRef() as it is no more needed.
1579  */
1580 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1581 {
1582   checkAllocated();
1583   int nbTuples=getNumberOfTuples();
1584   int nbOfCompo=getNumberOfComponents();
1585   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1586   ret->alloc(newNbOfTuple,nbOfCompo);
1587   const double *iptr=getConstPointer();
1588   double *optr=ret->getPointer();
1589   for(int i=0;i<nbTuples;i++)
1590     {
1591       int w=old2New[i];
1592       if(w>=0)
1593         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1594     }
1595   ret->copyStringInfoFrom(*this);
1596   return ret.retn();
1597 }
1598
1599 /*!
1600  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1601  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1602  * \a new2OldBg array.
1603  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1604  * This method is equivalent to renumberAndReduce() except that convention in input is
1605  * \c new2old and \b not \c old2new.
1606  * For more info on renumbering see \ref numbering.
1607  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1608  *              tuple index in \a this array to fill the i-th tuple in the new array.
1609  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1610  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1611  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1612  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1613  *          is to delete using decrRef() as it is no more needed.
1614  */
1615 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1616 {
1617   checkAllocated();
1618   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1619   int nbComp=getNumberOfComponents();
1620   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1621   ret->copyStringInfoFrom(*this);
1622   double *pt=ret->getPointer();
1623   const double *srcPt=getConstPointer();
1624   int i=0;
1625   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1626     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1627   ret->copyStringInfoFrom(*this);
1628   return ret.retn();
1629 }
1630
1631 DataArrayDouble *DataArrayDouble::selectByTupleId(const DataArrayInt & di) const
1632 {
1633   return selectByTupleId(di.getConstPointer(), di.getConstPointer()+di.getNumberOfTuples());
1634 }
1635
1636 /*!
1637  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1638  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1639  * \a new2OldBg array.
1640  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1641  * This method is equivalent to renumberAndReduce() except that convention in input is
1642  * \c new2old and \b not \c old2new.
1643  * This method is equivalent to selectByTupleId() except that it prevents coping data
1644  * from behind the end of \a this array.
1645  * For more info on renumbering see \ref numbering.
1646  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1647  *              tuple index in \a this array to fill the i-th tuple in the new array.
1648  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1649  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1650  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1651  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1652  *          is to delete using decrRef() as it is no more needed.
1653  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1654  */
1655 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1656 {
1657   checkAllocated();
1658   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1659   int nbComp=getNumberOfComponents();
1660   int oldNbOfTuples=getNumberOfTuples();
1661   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1662   ret->copyStringInfoFrom(*this);
1663   double *pt=ret->getPointer();
1664   const double *srcPt=getConstPointer();
1665   int i=0;
1666   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1667     if(*w>=0 && *w<oldNbOfTuples)
1668       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1669     else
1670       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1671   ret->copyStringInfoFrom(*this);
1672   return ret.retn();
1673 }
1674
1675 /*!
1676  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1677  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1678  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1679  * command \c range( \a bg, \a end2, \a step ).
1680  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1681  * not constructed explicitly.
1682  * For more info on renumbering see \ref numbering.
1683  *  \param [in] bg - index of the first tuple to copy from \a this array.
1684  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1685  *  \param [in] step - index increment to get index of the next tuple to copy.
1686  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1687  *          is to delete using decrRef() as it is no more needed.
1688  *  \sa DataArrayDouble::substr.
1689  */
1690 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1691 {
1692   checkAllocated();
1693   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1694   int nbComp=getNumberOfComponents();
1695   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1696   ret->alloc(newNbOfTuples,nbComp);
1697   double *pt=ret->getPointer();
1698   const double *srcPt=getConstPointer()+bg*nbComp;
1699   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1700     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1701   ret->copyStringInfoFrom(*this);
1702   return ret.retn();
1703 }
1704
1705 /*!
1706  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1707  * of tuples specified by \a ranges parameter.
1708  * For more info on renumbering see \ref numbering.
1709  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1710  *              of tuples in [\c begin,\c end) format.
1711  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1712  *          is to delete using decrRef() as it is no more needed.
1713  *  \throw If \a end < \a begin.
1714  *  \throw If \a end > \a this->getNumberOfTuples().
1715  *  \throw If \a this is not allocated.
1716  */
1717 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1718 {
1719   checkAllocated();
1720   int nbOfComp=getNumberOfComponents();
1721   int nbOfTuplesThis=getNumberOfTuples();
1722   if(ranges.empty())
1723     {
1724       DataArrayDouble *ret=DataArrayDouble::New();
1725       ret->alloc(0,nbOfComp);
1726       ret->copyStringInfoFrom(*this);
1727       return ret;
1728     }
1729   int ref=ranges.front().first;
1730   int nbOfTuples=0;
1731   bool isIncreasing=true;
1732   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1733     {
1734       if((*it).first<=(*it).second)
1735         {
1736           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1737             {
1738               nbOfTuples+=(*it).second-(*it).first;
1739               if(isIncreasing)
1740                 isIncreasing=ref<=(*it).first;
1741               ref=(*it).second;
1742             }
1743           else
1744             {
1745               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1746               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1747               throw INTERP_KERNEL::Exception(oss.str().c_str());
1748             }
1749         }
1750       else
1751         {
1752           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1753           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1754           throw INTERP_KERNEL::Exception(oss.str().c_str());
1755         }
1756     }
1757   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1758     return deepCpy();
1759   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1760   ret->alloc(nbOfTuples,nbOfComp);
1761   ret->copyStringInfoFrom(*this);
1762   const double *src=getConstPointer();
1763   double *work=ret->getPointer();
1764   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1765     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1766   return ret.retn();
1767 }
1768
1769 /*!
1770  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1771  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1772  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1773  * This method is a specialization of selectByTupleId2().
1774  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1775  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1776  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1777  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1778  *          is to delete using decrRef() as it is no more needed.
1779  *  \throw If \a tupleIdBg < 0.
1780  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1781     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1782  *  \sa DataArrayDouble::selectByTupleId2
1783  */
1784 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1785 {
1786   checkAllocated();
1787   int nbt=getNumberOfTuples();
1788   if(tupleIdBg<0)
1789     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1790   if(tupleIdBg>nbt)
1791     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1792   int trueEnd=tupleIdEnd;
1793   if(tupleIdEnd!=-1)
1794     {
1795       if(tupleIdEnd>nbt)
1796         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1797     }
1798   else
1799     trueEnd=nbt;
1800   int nbComp=getNumberOfComponents();
1801   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1802   ret->alloc(trueEnd-tupleIdBg,nbComp);
1803   ret->copyStringInfoFrom(*this);
1804   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1805   return ret.retn();
1806 }
1807
1808 /*!
1809  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1810  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1811  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1812  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1813  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1814  * components.  
1815  *  \param [in] newNbOfComp - number of components for the new array to have.
1816  *  \param [in] dftValue - value assigned to new values added to the new array.
1817  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1818  *          is to delete using decrRef() as it is no more needed.
1819  *  \throw If \a this is not allocated.
1820  */
1821 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1822 {
1823   checkAllocated();
1824   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1825   ret->alloc(getNumberOfTuples(),newNbOfComp);
1826   const double *oldc=getConstPointer();
1827   double *nc=ret->getPointer();
1828   int nbOfTuples=getNumberOfTuples();
1829   int oldNbOfComp=getNumberOfComponents();
1830   int dim=std::min(oldNbOfComp,newNbOfComp);
1831   for(int i=0;i<nbOfTuples;i++)
1832     {
1833       int j=0;
1834       for(;j<dim;j++)
1835         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1836       for(;j<newNbOfComp;j++)
1837         nc[newNbOfComp*i+j]=dftValue;
1838     }
1839   ret->setName(getName());
1840   for(int i=0;i<dim;i++)
1841     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1842   ret->setName(getName());
1843   return ret.retn();
1844 }
1845
1846 /*!
1847  * Changes the number of components within \a this array so that its raw data **does
1848  * not** change, instead splitting this data into tuples changes.
1849  *  \warning This method erases all (name and unit) component info set before!
1850  *  \param [in] newNbOfComp - number of components for \a this array to have.
1851  *  \throw If \a this is not allocated
1852  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1853  *  \throw If \a newNbOfCompo is lower than 1.
1854  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1855  *  \warning This method erases all (name and unit) component info set before!
1856  */
1857 void DataArrayDouble::rearrange(int newNbOfCompo)
1858 {
1859   checkAllocated();
1860   if(newNbOfCompo<1)
1861     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1862   std::size_t nbOfElems=getNbOfElems();
1863   if(nbOfElems%newNbOfCompo!=0)
1864     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1865   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1866     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1867   _info_on_compo.clear();
1868   _info_on_compo.resize(newNbOfCompo);
1869   declareAsNew();
1870 }
1871
1872 /*!
1873  * Changes the number of components within \a this array to be equal to its number
1874  * of tuples, and inversely its number of tuples to become equal to its number of 
1875  * components. So that its raw data **does not** change, instead splitting this
1876  * data into tuples changes.
1877  *  \warning This method erases all (name and unit) component info set before!
1878  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1879  *  \throw If \a this is not allocated.
1880  *  \sa rearrange()
1881  */
1882 void DataArrayDouble::transpose()
1883 {
1884   checkAllocated();
1885   int nbOfTuples=getNumberOfTuples();
1886   rearrange(nbOfTuples);
1887 }
1888
1889 /*!
1890  * Returns a copy of \a this array composed of selected components.
1891  * The new DataArrayDouble has the same number of tuples but includes components
1892  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1893  * can be either less, same or more than \a this->getNbOfElems().
1894  *  \param [in] compoIds - sequence of zero based indices of components to include
1895  *              into the new array.
1896  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1897  *          is to delete using decrRef() as it is no more needed.
1898  *  \throw If \a this is not allocated.
1899  *  \throw If a component index (\a i) is not valid: 
1900  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1901  *
1902  *  \if ENABLE_EXAMPLES
1903  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1904  *  \endif
1905  */
1906 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1907 {
1908   checkAllocated();
1909   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1910   std::size_t newNbOfCompo=compoIds.size();
1911   int oldNbOfCompo=getNumberOfComponents();
1912   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1913     if((*it)<0 || (*it)>=oldNbOfCompo)
1914       {
1915         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1916         throw INTERP_KERNEL::Exception(oss.str().c_str());
1917       }
1918   int nbOfTuples=getNumberOfTuples();
1919   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1920   ret->copyPartOfStringInfoFrom(*this,compoIds);
1921   const double *oldc=getConstPointer();
1922   double *nc=ret->getPointer();
1923   for(int i=0;i<nbOfTuples;i++)
1924     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1925       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1926   return ret.retn();
1927 }
1928
1929 /*!
1930  * Appends components of another array to components of \a this one, tuple by tuple.
1931  * So that the number of tuples of \a this array remains the same and the number of 
1932  * components increases.
1933  *  \param [in] other - the DataArrayDouble to append to \a this one.
1934  *  \throw If \a this is not allocated.
1935  *  \throw If \a this and \a other arrays have different number of tuples.
1936  *
1937  *  \if ENABLE_EXAMPLES
1938  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1939  *
1940  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1941  *  \endif
1942  */
1943 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1944 {
1945   checkAllocated();
1946   other->checkAllocated();
1947   int nbOfTuples=getNumberOfTuples();
1948   if(nbOfTuples!=other->getNumberOfTuples())
1949     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1950   int nbOfComp1=getNumberOfComponents();
1951   int nbOfComp2=other->getNumberOfComponents();
1952   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1953   double *w=newArr;
1954   const double *inp1=getConstPointer();
1955   const double *inp2=other->getConstPointer();
1956   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1957     {
1958       w=std::copy(inp1,inp1+nbOfComp1,w);
1959       w=std::copy(inp2,inp2+nbOfComp2,w);
1960     }
1961   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1962   std::vector<int> compIds(nbOfComp2);
1963   for(int i=0;i<nbOfComp2;i++)
1964     compIds[i]=nbOfComp1+i;
1965   copyPartOfStringInfoFrom2(compIds,*other);
1966 }
1967
1968 /*!
1969  * This method checks that all tuples in \a other are in \a this.
1970  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1971  * 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.
1972  *
1973  * \param [in] other - the array having the same number of components than \a this.
1974  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1975  * \sa DataArrayDouble::findCommonTuples
1976  */
1977 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1978 {
1979   if(!other)
1980     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1981   checkAllocated(); other->checkAllocated();
1982   if(getNumberOfComponents()!=other->getNumberOfComponents())
1983     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1984   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1985   DataArrayInt *c=0,*ci=0;
1986   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1987   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1988   int newNbOfTuples=-1;
1989   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1990   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1991   tupleIds=ret1.retn();
1992   return newNbOfTuples==getNumberOfTuples();
1993 }
1994
1995 /*!
1996  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1997  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1998  * distance separating two points is computed with the infinite norm.
1999  *
2000  * Indices of coincident tuples are stored in output arrays.
2001  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
2002  *
2003  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
2004  * MEDCouplingUMesh::mergeNodes().
2005  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
2006  *              considered not coincident.
2007  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2008  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
2009  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
2010  *               \a comm->getNumberOfComponents() == 1. 
2011  *               \a comm->getNumberOfTuples() == \a commIndex->back().
2012  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
2013  *               groups of (indices of) coincident tuples. Its every value is a tuple
2014  *               index where a next group of tuples begins. For example the second
2015  *               group of tuples in \a comm is described by following range of indices:
2016  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
2017  *               gives the number of groups of coincident tuples.
2018  *  \throw If \a this is not allocated.
2019  *  \throw If the number of components is not in [1,2,3,4].
2020  *
2021  *  \if ENABLE_EXAMPLES
2022  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
2023  *
2024  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
2025  *  \endif
2026  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
2027  */
2028 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
2029 {
2030   checkAllocated();
2031   int nbOfCompo=getNumberOfComponents();
2032   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
2033     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
2034
2035   int nbOfTuples=getNumberOfTuples();
2036   //
2037   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
2038   switch(nbOfCompo)
2039   {
2040     case 4:
2041       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2042       break;
2043     case 3:
2044       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2045       break;
2046     case 2:
2047       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2048       break;
2049     case 1:
2050       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2051       break;
2052     default:
2053       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2054   }
2055   comm=c.retn();
2056   commIndex=cI.retn();
2057 }
2058
2059 /*!
2060  * 
2061  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2062  *             \a nbTimes  should be at least equal to 1.
2063  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2064  * \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.
2065  */
2066 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2067 {
2068   checkAllocated();
2069   if(getNumberOfComponents()!=1)
2070     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2071   if(nbTimes<1)
2072     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2073   int nbTuples=getNumberOfTuples();
2074   const double *inPtr=getConstPointer();
2075   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2076   double *retPtr=ret->getPointer();
2077   for(int i=0;i<nbTuples;i++,inPtr++)
2078     {
2079       double val=*inPtr;
2080       for(int j=0;j<nbTimes;j++,retPtr++)
2081         *retPtr=val;
2082     }
2083   ret->copyStringInfoFrom(*this);
2084   return ret.retn();
2085 }
2086
2087 /*!
2088  * This methods returns the minimal distance between the two set of points \a this and \a other.
2089  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2090  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2091  *
2092  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2093  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2094  * \return the minimal distance between the two set of points \a this and \a other.
2095  * \sa DataArrayDouble::findClosestTupleId
2096  */
2097 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2098 {
2099   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2100   int nbOfCompo(getNumberOfComponents());
2101   int otherNbTuples(other->getNumberOfTuples());
2102   const double *thisPt(begin()),*otherPt(other->begin());
2103   const int *part1Pt(part1->begin());
2104   double ret=std::numeric_limits<double>::max();
2105   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2106     {
2107       double tmp(0.);
2108       for(int j=0;j<nbOfCompo;j++)
2109         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2110       if(tmp<ret)
2111         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2112     }
2113   return sqrt(ret);
2114 }
2115
2116 /*!
2117  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2118  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2119  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2120  *
2121  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2122  * \sa DataArrayDouble::minimalDistanceTo
2123  */
2124 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2125 {
2126   if(!other)
2127     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2128   checkAllocated(); other->checkAllocated();
2129   int nbOfCompo=getNumberOfComponents();
2130   if(nbOfCompo!=other->getNumberOfComponents())
2131     {
2132       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2133       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2134       throw INTERP_KERNEL::Exception(oss.str().c_str());
2135     }
2136   int nbOfTuples=other->getNumberOfTuples();
2137   int thisNbOfTuples=getNumberOfTuples();
2138   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2139   double bounds[6];
2140   getMinMaxPerComponent(bounds);
2141   switch(nbOfCompo)
2142   {
2143     case 3:
2144       {
2145         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2146         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2147         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2148         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2149         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2150         break;
2151       }
2152     case 2:
2153       {
2154         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2155         double delta=std::max(xDelta,yDelta);
2156         double characSize=sqrt(delta/(double)thisNbOfTuples);
2157         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2158         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2159         break;
2160       }
2161     case 1:
2162       {
2163         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2164         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2165         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2166         break;
2167       }
2168     default:
2169       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2170   }
2171   return ret.retn();
2172 }
2173
2174 /*!
2175  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2176  * 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
2177  * how many bounding boxes in \a otherBBoxFrmt.
2178  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2179  *
2180  * \param [in] otherBBoxFrmt - It is an array .
2181  * \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.
2182  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2183  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2184  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2185  */
2186 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2187 {
2188   if(!otherBBoxFrmt)
2189     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2190   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2191     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2192   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2193   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2194     {
2195       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2196       throw INTERP_KERNEL::Exception(oss.str().c_str());
2197     }
2198   if(nbOfComp%2!=0)
2199     {
2200       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2201       throw INTERP_KERNEL::Exception(oss.str().c_str());
2202     }
2203   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2204   const double *thisBBPtr(begin());
2205   int *retPtr(ret->getPointer());
2206   switch(nbOfComp/2)
2207   {
2208     case 3:
2209       {
2210         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2211         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2212           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2213         break;
2214       }
2215     case 2:
2216       {
2217         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2218         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2219           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2220         break;
2221       }
2222     case 1:
2223       {
2224         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2225         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2226           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2227         break;
2228       }
2229     default:
2230       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2231   }
2232
2233   return ret.retn();
2234 }
2235
2236 /*!
2237  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2238  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2239  * space. The distance between tuples is computed using norm2. If several tuples are
2240  * not far each from other than \a prec, only one of them remains in the result
2241  * array. The order of tuples in the result array is same as in \a this one except
2242  * that coincident tuples are excluded.
2243  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2244  *              considered not coincident.
2245  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2246  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2247  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2248  *          is to delete using decrRef() as it is no more needed.
2249  *  \throw If \a this is not allocated.
2250  *  \throw If the number of components is not in [1,2,3,4].
2251  *
2252  *  \if ENABLE_EXAMPLES
2253  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2254  *  \endif
2255  */
2256 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2257 {
2258   checkAllocated();
2259   DataArrayInt *c0=0,*cI0=0;
2260   findCommonTuples(prec,limitTupleId,c0,cI0);
2261   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2262   int newNbOfTuples=-1;
2263   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2264   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2265 }
2266
2267 /*!
2268  * Copy all components in a specified order from another DataArrayDouble.
2269  * Both numerical and textual data is copied. The number of tuples in \a this and
2270  * the other array can be different.
2271  *  \param [in] a - the array to copy data from.
2272  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2273  *              to be copied.
2274  *  \throw If \a a is NULL.
2275  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2276  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2277  *
2278  *  \if ENABLE_EXAMPLES
2279  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2280  *  \endif
2281  */
2282 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2283 {
2284   if(!a)
2285     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2286   checkAllocated();
2287   copyPartOfStringInfoFrom2(compoIds,*a);
2288   std::size_t partOfCompoSz=compoIds.size();
2289   int nbOfCompo=getNumberOfComponents();
2290   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2291   const double *ac=a->getConstPointer();
2292   double *nc=getPointer();
2293   for(int i=0;i<nbOfTuples;i++)
2294     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2295       nc[nbOfCompo*i+compoIds[j]]=*ac;
2296 }
2297
2298 /*!
2299  * Copy all values from another DataArrayDouble into specified tuples and components
2300  * of \a this array. Textual data is not copied.
2301  * The tree parameters defining set of indices of tuples and components are similar to
2302  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2303  *  \param [in] a - the array to copy values from.
2304  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2305  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2306  *              are located.
2307  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2308  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2309  *  \param [in] endComp - index of the component before which the components to assign
2310  *              to are located.
2311  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2312  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2313  *              must be equal to the number of columns to assign to, else an
2314  *              exception is thrown; if \a false, then it is only required that \a
2315  *              a->getNbOfElems() equals to number of values to assign to (this condition
2316  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2317  *              values to assign to is given by following Python expression:
2318  *              \a nbTargetValues = 
2319  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2320  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2321  *  \throw If \a a is NULL.
2322  *  \throw If \a a is not allocated.
2323  *  \throw If \a this is not allocated.
2324  *  \throw If parameters specifying tuples and components to assign to do not give a
2325  *            non-empty range of increasing indices.
2326  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2327  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2328  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2329  *
2330  *  \if ENABLE_EXAMPLES
2331  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2332  *  \endif
2333  */
2334 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2335 {
2336   if(!a)
2337     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2338   const char msg[]="DataArrayDouble::setPartOfValues1";
2339   checkAllocated();
2340   a->checkAllocated();
2341   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2342   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2343   int nbComp=getNumberOfComponents();
2344   int nbOfTuples=getNumberOfTuples();
2345   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2346   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2347   bool assignTech=true;
2348   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2349     {
2350       if(strictCompoCompare)
2351         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2352     }
2353   else
2354     {
2355       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2356       assignTech=false;
2357     }
2358   const double *srcPt=a->getConstPointer();
2359   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2360   if(assignTech)
2361     {
2362       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2363         for(int j=0;j<newNbOfComp;j++,srcPt++)
2364           pt[j*stepComp]=*srcPt;
2365     }
2366   else
2367     {
2368       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2369         {
2370           const double *srcPt2=srcPt;
2371           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2372             pt[j*stepComp]=*srcPt2;
2373         }
2374     }
2375 }
2376
2377 /*!
2378  * Assign a given value to values at specified tuples and components of \a this array.
2379  * The tree parameters defining set of indices of tuples and components are similar to
2380  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2381  *  \param [in] a - the value to assign.
2382  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2383  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2384  *              are located.
2385  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2386  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2387  *  \param [in] endComp - index of the component before which the components to assign
2388  *              to are located.
2389  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2390  *  \throw If \a this is not allocated.
2391  *  \throw If parameters specifying tuples and components to assign to, do not give a
2392  *            non-empty range of increasing indices or indices are out of a valid range
2393  *            for \c this array.
2394  *
2395  *  \if ENABLE_EXAMPLES
2396  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2397  *  \endif
2398  */
2399 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2400 {
2401   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2402   checkAllocated();
2403   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2404   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2405   int nbComp=getNumberOfComponents();
2406   int nbOfTuples=getNumberOfTuples();
2407   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2408   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2409   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2410   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2411     for(int j=0;j<newNbOfComp;j++)
2412       pt[j*stepComp]=a;
2413 }
2414
2415 /*!
2416  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2417  * components of \a this array. Textual data is not copied.
2418  * The tuples and components to assign to are defined by C arrays of indices.
2419  * There are two *modes of usage*:
2420  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2421  *   of \a a is assigned to its own location within \a this array. 
2422  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2423  *   components of every specified tuple of \a this array. In this mode it is required
2424  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2425  *
2426  *  \param [in] a - the array to copy values from.
2427  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2428  *              assign values of \a a to.
2429  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2430  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2431  *              \a bgTuples <= \a pi < \a endTuples.
2432  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2433  *              assign values of \a a to.
2434  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2435  *              pointer to a component index <em>(pi)</em> varies as this: 
2436  *              \a bgComp <= \a pi < \a endComp.
2437  *  \param [in] strictCompoCompare - this parameter is checked only if the
2438  *               *mode of usage* is the first; if it is \a true (default), 
2439  *               then \a a->getNumberOfComponents() must be equal 
2440  *               to the number of specified columns, else this is not required.
2441  *  \throw If \a a is NULL.
2442  *  \throw If \a a is not allocated.
2443  *  \throw If \a this is not allocated.
2444  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2445  *         out of a valid range for \a this array.
2446  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2447  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2448  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2449  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2450  *
2451  *  \if ENABLE_EXAMPLES
2452  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2453  *  \endif
2454  */
2455 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2456 {
2457   if(!a)
2458     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2459   const char msg[]="DataArrayDouble::setPartOfValues2";
2460   checkAllocated();
2461   a->checkAllocated();
2462   int nbComp=getNumberOfComponents();
2463   int nbOfTuples=getNumberOfTuples();
2464   for(const int *z=bgComp;z!=endComp;z++)
2465     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2466   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2467   int newNbOfComp=(int)std::distance(bgComp,endComp);
2468   bool assignTech=true;
2469   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2470     {
2471       if(strictCompoCompare)
2472         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2473     }
2474   else
2475     {
2476       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2477       assignTech=false;
2478     }
2479   double *pt=getPointer();
2480   const double *srcPt=a->getConstPointer();
2481   if(assignTech)
2482     {    
2483       for(const int *w=bgTuples;w!=endTuples;w++)
2484         {
2485           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2486           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2487             {    
2488               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2489             }
2490         }
2491     }
2492   else
2493     {
2494       for(const int *w=bgTuples;w!=endTuples;w++)
2495         {
2496           const double *srcPt2=srcPt;
2497           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2498           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2499             {    
2500               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2501             }
2502         }
2503     }
2504 }
2505
2506 /*!
2507  * Assign a given value to values at specified tuples and components of \a this array.
2508  * The tuples and components to assign to are defined by C arrays of indices.
2509  *  \param [in] a - the value to assign.
2510  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2511  *              assign \a a to.
2512  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2513  *              pointer to a tuple index (\a pi) varies as this: 
2514  *              \a bgTuples <= \a pi < \a endTuples.
2515  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2516  *              assign \a a to.
2517  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2518  *              pointer to a component index (\a pi) varies as this: 
2519  *              \a bgComp <= \a pi < \a endComp.
2520  *  \throw If \a this is not allocated.
2521  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2522  *         out of a valid range for \a this array.
2523  *
2524  *  \if ENABLE_EXAMPLES
2525  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2526  *  \endif
2527  */
2528 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2529 {
2530   checkAllocated();
2531   int nbComp=getNumberOfComponents();
2532   int nbOfTuples=getNumberOfTuples();
2533   for(const int *z=bgComp;z!=endComp;z++)
2534     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2535   double *pt=getPointer();
2536   for(const int *w=bgTuples;w!=endTuples;w++)
2537     for(const int *z=bgComp;z!=endComp;z++)
2538       {
2539         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2540         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2541       }
2542 }
2543
2544 /*!
2545  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2546  * components of \a this array. Textual data is not copied.
2547  * The tuples to assign to are defined by a C array of indices.
2548  * The components to assign to are defined by three values similar to parameters of
2549  * the Python function \c range(\c start,\c stop,\c step).
2550  * There are two *modes of usage*:
2551  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2552  *   of \a a is assigned to its own location within \a this array. 
2553  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2554  *   components of every specified tuple of \a this array. In this mode it is required
2555  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2556  *
2557  *  \param [in] a - the array to copy values from.
2558  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2559  *              assign values of \a a to.
2560  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2561  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2562  *              \a bgTuples <= \a pi < \a endTuples.
2563  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2564  *  \param [in] endComp - index of the component before which the components to assign
2565  *              to are located.
2566  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2567  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2568  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2569  *               then \a a->getNumberOfComponents() must be equal 
2570  *               to the number of specified columns, else this is not required.
2571  *  \throw If \a a is NULL.
2572  *  \throw If \a a is not allocated.
2573  *  \throw If \a this is not allocated.
2574  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2575  *         \a this array.
2576  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2577  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2578  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2579  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2580  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2581  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2582  *  \throw If parameters specifying components to assign to, do not give a
2583  *            non-empty range of increasing indices or indices are out of a valid range
2584  *            for \c this array.
2585  *
2586  *  \if ENABLE_EXAMPLES
2587  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2588  *  \endif
2589  */
2590 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2591 {
2592   if(!a)
2593     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2594   const char msg[]="DataArrayDouble::setPartOfValues3";
2595   checkAllocated();
2596   a->checkAllocated();
2597   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2598   int nbComp=getNumberOfComponents();
2599   int nbOfTuples=getNumberOfTuples();
2600   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2601   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2602   bool assignTech=true;
2603   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2604     {
2605       if(strictCompoCompare)
2606         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2607     }
2608   else
2609     {
2610       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2611       assignTech=false;
2612     }
2613   double *pt=getPointer()+bgComp;
2614   const double *srcPt=a->getConstPointer();
2615   if(assignTech)
2616     {
2617       for(const int *w=bgTuples;w!=endTuples;w++)
2618         for(int j=0;j<newNbOfComp;j++,srcPt++)
2619           {
2620             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2621             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2622           }
2623     }
2624   else
2625     {
2626       for(const int *w=bgTuples;w!=endTuples;w++)
2627         {
2628           const double *srcPt2=srcPt;
2629           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2630             {
2631               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2632               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2633             }
2634         }
2635     }
2636 }
2637
2638 /*!
2639  * Assign a given value to values at specified tuples and components of \a this array.
2640  * The tuples to assign to are defined by a C array of indices.
2641  * The components to assign to are defined by three values similar to parameters of
2642  * the Python function \c range(\c start,\c stop,\c step).
2643  *  \param [in] a - the value to assign.
2644  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2645  *              assign \a a to.
2646  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2647  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2648  *              \a bgTuples <= \a pi < \a endTuples.
2649  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2650  *  \param [in] endComp - index of the component before which the components to assign
2651  *              to are located.
2652  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2653  *  \throw If \a this is not allocated.
2654  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2655  *         \a this array.
2656  *  \throw If parameters specifying components to assign to, do not give a
2657  *            non-empty range of increasing indices or indices are out of a valid range
2658  *            for \c this array.
2659  *
2660  *  \if ENABLE_EXAMPLES
2661  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2662  *  \endif
2663  */
2664 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2665 {
2666   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2667   checkAllocated();
2668   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2669   int nbComp=getNumberOfComponents();
2670   int nbOfTuples=getNumberOfTuples();
2671   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2672   double *pt=getPointer()+bgComp;
2673   for(const int *w=bgTuples;w!=endTuples;w++)
2674     for(int j=0;j<newNbOfComp;j++)
2675       {
2676         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2677         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2678       }
2679 }
2680
2681 /*!
2682  * Copy all values from another DataArrayDouble into specified tuples and components
2683  * of \a this array. Textual data is not copied.
2684  * The tree parameters defining set of indices of tuples and components are similar to
2685  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2686  *  \param [in] a - the array to copy values from.
2687  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2688  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2689  *              are located.
2690  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2691  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2692  *              assign \a a to.
2693  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2694  *              pointer to a component index (\a pi) varies as this: 
2695  *              \a bgComp <= \a pi < \a endComp.
2696  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2697  *              must be equal to the number of columns to assign to, else an
2698  *              exception is thrown; if \a false, then it is only required that \a
2699  *              a->getNbOfElems() equals to number of values to assign to (this condition
2700  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2701  *              values to assign to is given by following Python expression:
2702  *              \a nbTargetValues = 
2703  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2704  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2705  *  \throw If \a a is NULL.
2706  *  \throw If \a a is not allocated.
2707  *  \throw If \a this is not allocated.
2708  *  \throw If parameters specifying tuples and components to assign to do not give a
2709  *            non-empty range of increasing indices.
2710  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2711  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2712  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2713  *
2714  */
2715 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2716 {
2717   if(!a)
2718     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2719   const char msg[]="DataArrayDouble::setPartOfValues4";
2720   checkAllocated();
2721   a->checkAllocated();
2722   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2723   int newNbOfComp=(int)std::distance(bgComp,endComp);
2724   int nbComp=getNumberOfComponents();
2725   for(const int *z=bgComp;z!=endComp;z++)
2726     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2727   int nbOfTuples=getNumberOfTuples();
2728   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2729   bool assignTech=true;
2730   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2731     {
2732       if(strictCompoCompare)
2733         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2734     }
2735   else
2736     {
2737       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2738       assignTech=false;
2739     }
2740   const double *srcPt=a->getConstPointer();
2741   double *pt=getPointer()+bgTuples*nbComp;
2742   if(assignTech)
2743     {
2744       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2745         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2746           pt[*z]=*srcPt;
2747     }
2748   else
2749     {
2750       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2751         {
2752           const double *srcPt2=srcPt;
2753           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2754             pt[*z]=*srcPt2;
2755         }
2756     }
2757 }
2758
2759 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2760 {
2761   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2762   checkAllocated();
2763   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2764   int nbComp=getNumberOfComponents();
2765   for(const int *z=bgComp;z!=endComp;z++)
2766     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2767   int nbOfTuples=getNumberOfTuples();
2768   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2769   double *pt=getPointer()+bgTuples*nbComp;
2770   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2771     for(const int *z=bgComp;z!=endComp;z++)
2772       pt[*z]=a;
2773 }
2774
2775 /*!
2776  * Copy some tuples from another DataArrayDouble into specified tuples
2777  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2778  * components.
2779  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2780  * All components of selected tuples are copied.
2781  *  \param [in] a - the array to copy values from.
2782  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2783  *              target tuples of \a this. \a tuplesSelec has two components, and the
2784  *              first component specifies index of the source tuple and the second
2785  *              one specifies index of the target tuple.
2786  *  \throw If \a this is not allocated.
2787  *  \throw If \a a is NULL.
2788  *  \throw If \a a is not allocated.
2789  *  \throw If \a tuplesSelec is NULL.
2790  *  \throw If \a tuplesSelec is not allocated.
2791  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2792  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2793  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2794  *         the corresponding (\a this or \a a) array.
2795  */
2796 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2797 {
2798   if(!a || !tuplesSelec)
2799     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2800   checkAllocated();
2801   a->checkAllocated();
2802   tuplesSelec->checkAllocated();
2803   int nbOfComp=getNumberOfComponents();
2804   if(nbOfComp!=a->getNumberOfComponents())
2805     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2806   if(tuplesSelec->getNumberOfComponents()!=2)
2807     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2808   int thisNt=getNumberOfTuples();
2809   int aNt=a->getNumberOfTuples();
2810   double *valsToSet=getPointer();
2811   const double *valsSrc=a->getConstPointer();
2812   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2813     {
2814       if(tuple[1]>=0 && tuple[1]<aNt)
2815         {
2816           if(tuple[0]>=0 && tuple[0]<thisNt)
2817             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2818           else
2819             {
2820               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2821               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2822               throw INTERP_KERNEL::Exception(oss.str().c_str());
2823             }
2824         }
2825       else
2826         {
2827           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2828           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2829           throw INTERP_KERNEL::Exception(oss.str().c_str());
2830         }
2831     }
2832 }
2833
2834 /*!
2835  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2836  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2837  * components.
2838  * The tuples to assign to are defined by index of the first tuple, and
2839  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2840  * The tuples to copy are defined by values of a DataArrayInt.
2841  * All components of selected tuples are copied.
2842  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2843  *              values to.
2844  *  \param [in] aBase - the array to copy values from.
2845  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2846  *  \throw If \a this is not allocated.
2847  *  \throw If \a aBase is NULL.
2848  *  \throw If \a aBase is not allocated.
2849  *  \throw If \a tuplesSelec is NULL.
2850  *  \throw If \a tuplesSelec is not allocated.
2851  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2852  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2853  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2854  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2855  *         \a aBase array.
2856  */
2857 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2858 {
2859   if(!aBase || !tuplesSelec)
2860     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2861   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2862   if(!a)
2863     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2864   checkAllocated();
2865   a->checkAllocated();
2866   tuplesSelec->checkAllocated();
2867   int nbOfComp=getNumberOfComponents();
2868   if(nbOfComp!=a->getNumberOfComponents())
2869     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2870   if(tuplesSelec->getNumberOfComponents()!=1)
2871     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2872   int thisNt=getNumberOfTuples();
2873   int aNt=a->getNumberOfTuples();
2874   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2875   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2876   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2877     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2878   const double *valsSrc=a->getConstPointer();
2879   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2880     {
2881       if(*tuple>=0 && *tuple<aNt)
2882         {
2883           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2884         }
2885       else
2886         {
2887           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2888           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2889           throw INTERP_KERNEL::Exception(oss.str().c_str());
2890         }
2891     }
2892 }
2893
2894 /*!
2895  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2896  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2897  * components.
2898  * The tuples to copy are defined by three values similar to parameters of
2899  * the Python function \c range(\c start,\c stop,\c step).
2900  * The tuples to assign to are defined by index of the first tuple, and
2901  * their number is defined by number of tuples to copy.
2902  * All components of selected tuples are copied.
2903  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2904  *              values to.
2905  *  \param [in] aBase - the array to copy values from.
2906  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2907  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2908  *              are located.
2909  *  \param [in] step - index increment to get index of the next tuple to copy.
2910  *  \throw If \a this is not allocated.
2911  *  \throw If \a aBase is NULL.
2912  *  \throw If \a aBase is not allocated.
2913  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2914  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2915  *  \throw If parameters specifying tuples to copy, do not give a
2916  *            non-empty range of increasing indices or indices are out of a valid range
2917  *            for the array \a aBase.
2918  */
2919 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2920 {
2921   if(!aBase)
2922     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2923   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2924   if(!a)
2925     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2926   checkAllocated();
2927   a->checkAllocated();
2928   int nbOfComp=getNumberOfComponents();
2929   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2930   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2931   if(nbOfComp!=a->getNumberOfComponents())
2932     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2933   int thisNt=getNumberOfTuples();
2934   int aNt=a->getNumberOfTuples();
2935   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2936   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2937     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2938   if(end2>aNt)
2939     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2940   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2941   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2942     {
2943       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2944     }
2945 }
2946
2947 /*!
2948  * Returns a value located at specified tuple and component.
2949  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2950  * parameters is checked. So this method is safe but expensive if used to go through
2951  * all values of \a this.
2952  *  \param [in] tupleId - index of tuple of interest.
2953  *  \param [in] compoId - index of component of interest.
2954  *  \return double - value located by \a tupleId and \a compoId.
2955  *  \throw If \a this is not allocated.
2956  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2957  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2958  */
2959 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2960 {
2961   checkAllocated();
2962   if(tupleId<0 || tupleId>=getNumberOfTuples())
2963     {
2964       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2965       throw INTERP_KERNEL::Exception(oss.str().c_str());
2966     }
2967   if(compoId<0 || compoId>=getNumberOfComponents())
2968     {
2969       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2970       throw INTERP_KERNEL::Exception(oss.str().c_str());
2971     }
2972   return _mem[tupleId*_info_on_compo.size()+compoId];
2973 }
2974
2975 /*!
2976  * Returns the first value of \a this. 
2977  *  \return double - the last value of \a this array.
2978  *  \throw If \a this is not allocated.
2979  *  \throw If \a this->getNumberOfComponents() != 1.
2980  *  \throw If \a this->getNumberOfTuples() < 1.
2981  */
2982 double DataArrayDouble::front() const
2983 {
2984   checkAllocated();
2985   if(getNumberOfComponents()!=1)
2986     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2987   int nbOfTuples=getNumberOfTuples();
2988   if(nbOfTuples<1)
2989     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2990   return *(getConstPointer());
2991 }
2992
2993 /*!
2994  * Returns the last value of \a this. 
2995  *  \return double - the last value of \a this array.
2996  *  \throw If \a this is not allocated.
2997  *  \throw If \a this->getNumberOfComponents() != 1.
2998  *  \throw If \a this->getNumberOfTuples() < 1.
2999  */
3000 double DataArrayDouble::back() const
3001 {
3002   checkAllocated();
3003   if(getNumberOfComponents()!=1)
3004     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
3005   int nbOfTuples=getNumberOfTuples();
3006   if(nbOfTuples<1)
3007     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
3008   return *(getConstPointer()+nbOfTuples-1);
3009 }
3010
3011 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
3012 {
3013   if(newArray!=arrayToSet)
3014     {
3015       if(arrayToSet)
3016         arrayToSet->decrRef();
3017       arrayToSet=newArray;
3018       if(arrayToSet)
3019         arrayToSet->incrRef();
3020     }
3021 }
3022
3023 /*!
3024  * Sets a C array to be used as raw data of \a this. The previously set info
3025  *  of components is retained and re-sized. 
3026  * For more info see \ref MEDCouplingArraySteps1.
3027  *  \param [in] array - the C array to be used as raw data of \a this.
3028  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
3029  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
3030  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
3031  *                     \c free(\c array ) will be called.
3032  *  \param [in] nbOfTuple - new number of tuples in \a this.
3033  *  \param [in] nbOfCompo - new number of components in \a this.
3034  */
3035 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
3036 {
3037   _info_on_compo.resize(nbOfCompo);
3038   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
3039   declareAsNew();
3040 }
3041
3042 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3043 {
3044   _info_on_compo.resize(nbOfCompo);
3045   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3046   declareAsNew();
3047 }
3048
3049 /*!
3050  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3051  * is thrown.
3052  * \throw If zero is found in \a this array.
3053  */
3054 void DataArrayDouble::checkNoNullValues() const
3055 {
3056   const double *tmp=getConstPointer();
3057   std::size_t nbOfElems=getNbOfElems();
3058   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3059   if(where!=tmp+nbOfElems)
3060     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3061 }
3062
3063 /*!
3064  * Computes minimal and maximal value in each component. An output array is filled
3065  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3066  * enough memory before calling this method.
3067  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3068  *               It is filled as follows:<br>
3069  *               \a bounds[0] = \c min_of_component_0 <br>
3070  *               \a bounds[1] = \c max_of_component_0 <br>
3071  *               \a bounds[2] = \c min_of_component_1 <br>
3072  *               \a bounds[3] = \c max_of_component_1 <br>
3073  *               ...
3074  */
3075 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3076 {
3077   checkAllocated();
3078   int dim=getNumberOfComponents();
3079   for (int idim=0; idim<dim; idim++)
3080     {
3081       bounds[idim*2]=std::numeric_limits<double>::max();
3082       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3083     } 
3084   const double *ptr=getConstPointer();
3085   int nbOfTuples=getNumberOfTuples();
3086   for(int i=0;i<nbOfTuples;i++)
3087     {
3088       for(int idim=0;idim<dim;idim++)
3089         {
3090           if(bounds[idim*2]>ptr[i*dim+idim])
3091             {
3092               bounds[idim*2]=ptr[i*dim+idim];
3093             }
3094           if(bounds[idim*2+1]<ptr[i*dim+idim])
3095             {
3096               bounds[idim*2+1]=ptr[i*dim+idim];
3097             }
3098         }
3099     }
3100 }
3101
3102 /*!
3103  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3104  * to store both the min and max per component of each tuples. 
3105  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3106  *
3107  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3108  *
3109  * \throw If \a this is not allocated yet.
3110  */
3111 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3112 {
3113   checkAllocated();
3114   const double *dataPtr=getConstPointer();
3115   int nbOfCompo=getNumberOfComponents();
3116   int nbTuples=getNumberOfTuples();
3117   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3118   bbox->alloc(nbTuples,2*nbOfCompo);
3119   double *bboxPtr=bbox->getPointer();
3120   for(int i=0;i<nbTuples;i++)
3121     {
3122       for(int j=0;j<nbOfCompo;j++)
3123         {
3124           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3125           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3126         }
3127     }
3128   return bbox.retn();
3129 }
3130
3131 /*!
3132  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3133  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3134  * 
3135  * \param [in] other a DataArrayDouble having same number of components than \a this.
3136  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3137  * \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.
3138  *             \a cI allows to extract information in \a c.
3139  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3140  *
3141  * \throw In case of:
3142  *  - \a this is not allocated
3143  *  - \a other is not allocated or null
3144  *  - \a this and \a other do not have the same number of components
3145  *  - if number of components of \a this is not in [1,2,3]
3146  *
3147  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3148  */
3149 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3150 {
3151   if(!other)
3152     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3153   checkAllocated();
3154   other->checkAllocated();
3155   int nbOfCompo=getNumberOfComponents();
3156   int otherNbOfCompo=other->getNumberOfComponents();
3157   if(nbOfCompo!=otherNbOfCompo)
3158     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3159   int nbOfTuplesOther=other->getNumberOfTuples();
3160   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3161   switch(nbOfCompo)
3162   {
3163     case 3:
3164       {
3165         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3166         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3167         break;
3168       }
3169     case 2:
3170       {
3171         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3172         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3173         break;
3174       }
3175     case 1:
3176       {
3177         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3178         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3179         break;
3180       }
3181     default:
3182       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3183   }
3184   c=cArr.retn(); cI=cIArr.retn();
3185 }
3186
3187 /*!
3188  * 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
3189  * around origin of 'radius' 1.
3190  * 
3191  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3192  */
3193 void DataArrayDouble::recenterForMaxPrecision(double eps)
3194 {
3195   checkAllocated();
3196   int dim=getNumberOfComponents();
3197   std::vector<double> bounds(2*dim);
3198   getMinMaxPerComponent(&bounds[0]);
3199   for(int i=0;i<dim;i++)
3200     {
3201       double delta=bounds[2*i+1]-bounds[2*i];
3202       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3203       if(delta>eps)
3204         applyLin(1./delta,-offset/delta,i);
3205       else
3206         applyLin(1.,-offset,i);
3207     }
3208 }
3209
3210 /*!
3211  * Returns the maximal value and its location within \a this one-dimensional array.
3212  *  \param [out] tupleId - index of the tuple holding the maximal value.
3213  *  \return double - the maximal value among all values of \a this array.
3214  *  \throw If \a this->getNumberOfComponents() != 1
3215  *  \throw If \a this->getNumberOfTuples() < 1
3216  */
3217 double DataArrayDouble::getMaxValue(int& tupleId) const
3218 {
3219   checkAllocated();
3220   if(getNumberOfComponents()!=1)
3221     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 !");
3222   int nbOfTuples=getNumberOfTuples();
3223   if(nbOfTuples<=0)
3224     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3225   const double *vals=getConstPointer();
3226   const double *loc=std::max_element(vals,vals+nbOfTuples);
3227   tupleId=(int)std::distance(vals,loc);
3228   return *loc;
3229 }
3230
3231 /*!
3232  * Returns the maximal value within \a this array that is allowed to have more than
3233  *  one component.
3234  *  \return double - the maximal value among all values of \a this array.
3235  *  \throw If \a this is not allocated.
3236  */
3237 double DataArrayDouble::getMaxValueInArray() const
3238 {
3239   checkAllocated();
3240   const double *loc=std::max_element(begin(),end());
3241   return *loc;
3242 }
3243
3244 /*!
3245  * Returns the maximal value and all its locations within \a this one-dimensional array.
3246  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3247  *               tuples holding the maximal value. The caller is to delete it using
3248  *               decrRef() as it is no more needed.
3249  *  \return double - the maximal value among all values of \a this array.
3250  *  \throw If \a this->getNumberOfComponents() != 1
3251  *  \throw If \a this->getNumberOfTuples() < 1
3252  */
3253 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3254 {
3255   int tmp;
3256   tupleIds=0;
3257   double ret=getMaxValue(tmp);
3258   tupleIds=getIdsInRange(ret,ret);
3259   return ret;
3260 }
3261
3262 /*!
3263  * Returns the minimal value and its location within \a this one-dimensional array.
3264  *  \param [out] tupleId - index of the tuple holding the minimal value.
3265  *  \return double - the minimal value among all values of \a this array.
3266  *  \throw If \a this->getNumberOfComponents() != 1
3267  *  \throw If \a this->getNumberOfTuples() < 1
3268  */
3269 double DataArrayDouble::getMinValue(int& tupleId) const
3270 {
3271   checkAllocated();
3272   if(getNumberOfComponents()!=1)
3273     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3274   int nbOfTuples=getNumberOfTuples();
3275   if(nbOfTuples<=0)
3276     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3277   const double *vals=getConstPointer();
3278   const double *loc=std::min_element(vals,vals+nbOfTuples);
3279   tupleId=(int)std::distance(vals,loc);
3280   return *loc;
3281 }
3282
3283 /*!
3284  * Returns the minimal value within \a this array that is allowed to have more than
3285  *  one component.
3286  *  \return double - the minimal value among all values of \a this array.
3287  *  \throw If \a this is not allocated.
3288  */
3289 double DataArrayDouble::getMinValueInArray() const
3290 {
3291   checkAllocated();
3292   const double *loc=std::min_element(begin(),end());
3293   return *loc;
3294 }
3295
3296 /*!
3297  * Returns the minimal value and all its locations within \a this one-dimensional array.
3298  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3299  *               tuples holding the minimal value. The caller is to delete it using
3300  *               decrRef() as it is no more needed.
3301  *  \return double - the minimal value among all values of \a this array.
3302  *  \throw If \a this->getNumberOfComponents() != 1
3303  *  \throw If \a this->getNumberOfTuples() < 1
3304  */
3305 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3306 {
3307   int tmp;
3308   tupleIds=0;
3309   double ret=getMinValue(tmp);
3310   tupleIds=getIdsInRange(ret,ret);
3311   return ret;
3312 }
3313
3314 /*!
3315  * 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.
3316  * This method only works for single component array.
3317  *
3318  * \return a value in [ 0, \c this->getNumberOfTuples() )
3319  *
3320  * \throw If \a this is not allocated
3321  *
3322  */
3323 int DataArrayDouble::count(double value, double eps) const
3324 {
3325   int ret=0;
3326   checkAllocated();
3327   if(getNumberOfComponents()!=1)
3328     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3329   const double *vals=begin();
3330   int nbOfTuples=getNumberOfTuples();
3331   for(int i=0;i<nbOfTuples;i++,vals++)
3332     if(fabs(*vals-value)<=eps)
3333       ret++;
3334   return ret;
3335 }
3336
3337 /*!
3338  * Returns the average value of \a this one-dimensional array.
3339  *  \return double - the average value over all values of \a this array.
3340  *  \throw If \a this->getNumberOfComponents() != 1
3341  *  \throw If \a this->getNumberOfTuples() < 1
3342  */
3343 double DataArrayDouble::getAverageValue() const
3344 {
3345   if(getNumberOfComponents()!=1)
3346     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3347   int nbOfTuples=getNumberOfTuples();
3348   if(nbOfTuples<=0)
3349     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3350   const double *vals=getConstPointer();
3351   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3352   return ret/nbOfTuples;
3353 }
3354
3355 /*!
3356  * Returns the Euclidean norm of the vector defined by \a this array.
3357  *  \return double - the value of the Euclidean norm, i.e.
3358  *          the square root of the inner product of vector.
3359  *  \throw If \a this is not allocated.
3360  */
3361 double DataArrayDouble::norm2() const
3362 {
3363   checkAllocated();
3364   double ret=0.;
3365   std::size_t nbOfElems=getNbOfElems();
3366   const double *pt=getConstPointer();
3367   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3368     ret+=(*pt)*(*pt);
3369   return sqrt(ret);
3370 }
3371
3372 /*!
3373  * Returns the maximum norm of the vector defined by \a this array.
3374  * This method works even if the number of components is diferent from one.
3375  * If the number of elements in \a this is 0, -1. is returned.
3376  *  \return double - the value of the maximum norm, i.e.
3377  *          the maximal absolute value among values of \a this array (whatever its number of components).
3378  *  \throw If \a this is not allocated.
3379  */
3380 double DataArrayDouble::normMax() const
3381 {
3382   checkAllocated();
3383   double ret(-1.);
3384   std::size_t nbOfElems(getNbOfElems());
3385   const double *pt(getConstPointer());
3386   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3387     {
3388       double val(std::abs(*pt));
3389       if(val>ret)
3390         ret=val;
3391     }
3392   return ret;
3393 }
3394
3395 /*!
3396  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3397  * This method works even if the number of components is diferent from one.
3398  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3399  *  \return double - the value of the minimum norm, i.e.
3400  *          the minimal absolute value among values of \a this array (whatever its number of components).
3401  *  \throw If \a this is not allocated.
3402  */
3403 double DataArrayDouble::normMin() const
3404 {
3405   checkAllocated();
3406   double ret(std::numeric_limits<double>::max());
3407   std::size_t nbOfElems(getNbOfElems());
3408   const double *pt(getConstPointer());
3409   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3410     {
3411       double val(std::abs(*pt));
3412       if(val<ret)
3413         ret=val;
3414     }
3415   return ret;
3416 }
3417
3418 /*!
3419  * Accumulates values of each component of \a this array.
3420  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3421  *         by the caller, that is filled by this method with sum value for each
3422  *         component.
3423  *  \throw If \a this is not allocated.
3424  */
3425 void DataArrayDouble::accumulate(double *res) const
3426 {
3427   checkAllocated();
3428   const double *ptr=getConstPointer();
3429   int nbTuple=getNumberOfTuples();
3430   int nbComps=getNumberOfComponents();
3431   std::fill(res,res+nbComps,0.);
3432   for(int i=0;i<nbTuple;i++)
3433     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3434 }
3435
3436 /*!
3437  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3438  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3439  *
3440  *
3441  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3442  * \a tupleEnd. If not an exception will be thrown.
3443  *
3444  * \param [in] tupleBg start pointer (included) of input external tuple
3445  * \param [in] tupleEnd end pointer (not included) of input external tuple
3446  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3447  * \return the min distance.
3448  * \sa MEDCouplingUMesh::distanceToPoint
3449  */
3450 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3451 {
3452   checkAllocated();
3453   int nbTuple=getNumberOfTuples();
3454   int nbComps=getNumberOfComponents();
3455   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3456     { 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()); }
3457   if(nbTuple==0)
3458     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3459   double ret0=std::numeric_limits<double>::max();
3460   tupleId=-1;
3461   const double *work=getConstPointer();
3462   for(int i=0;i<nbTuple;i++)
3463     {
3464       double val=0.;
3465       for(int j=0;j<nbComps;j++,work++) 
3466         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3467       if(val>=ret0)
3468         continue;
3469       else
3470         { ret0=val; tupleId=i; }
3471     }
3472   return sqrt(ret0);
3473 }
3474
3475 /*!
3476  * Accumulate values of the given component of \a this array.
3477  *  \param [in] compId - the index of the component of interest.
3478  *  \return double - a sum value of \a compId-th component.
3479  *  \throw If \a this is not allocated.
3480  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3481  *         not respected.
3482  */
3483 double DataArrayDouble::accumulate(int compId) const
3484 {
3485   checkAllocated();
3486   const double *ptr=getConstPointer();
3487   int nbTuple=getNumberOfTuples();
3488   int nbComps=getNumberOfComponents();
3489   if(compId<0 || compId>=nbComps)
3490     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3491   double ret=0.;
3492   for(int i=0;i<nbTuple;i++)
3493     ret+=ptr[i*nbComps+compId];
3494   return ret;
3495 }
3496
3497 /*!
3498  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3499  * The returned array will have same number of components than \a this and number of tuples equal to
3500  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3501  *
3502  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3503  * 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.
3504  *
3505  * \param [in] bgOfIndex - begin (included) of the input index array.
3506  * \param [in] endOfIndex - end (excluded) of the input index array.
3507  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3508  * 
3509  * \throw If bgOfIndex or end is NULL.
3510  * \throw If input index array is not ascendingly sorted.
3511  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3512  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3513  */
3514 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3515 {
3516   if(!bgOfIndex || !endOfIndex)
3517     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3518   checkAllocated();
3519   int nbCompo=getNumberOfComponents();
3520   int nbOfTuples=getNumberOfTuples();
3521   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3522   if(sz<1)
3523     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3524   sz--;
3525   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3526   const int *w=bgOfIndex;
3527   if(*w<0 || *w>=nbOfTuples)
3528     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3529   const double *srcPt=begin()+(*w)*nbCompo;
3530   double *tmp=ret->getPointer();
3531   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3532     {
3533       std::fill(tmp,tmp+nbCompo,0.);
3534       if(w[1]>=w[0])
3535         {
3536           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3537             {
3538               if(j>=0 && j<nbOfTuples)
3539                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3540               else
3541                 {
3542                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3543                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3544                 }
3545             }
3546         }
3547       else
3548         {
3549           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3550           throw INTERP_KERNEL::Exception(oss.str().c_str());
3551         }
3552     }
3553   ret->copyStringInfoFrom(*this);
3554   return ret.retn();
3555 }
3556
3557 /*!
3558  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3559  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3560  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3561  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3562  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3563  *          is to delete this array using decrRef() as it is no more needed. The array
3564  *          does not contain any textual info on components.
3565  *  \throw If \a this->getNumberOfComponents() != 2.
3566  */
3567 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3568 {
3569   checkAllocated();
3570   int nbOfComp(getNumberOfComponents());
3571   if(nbOfComp!=2)
3572     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3573   int nbOfTuple(getNumberOfTuples());
3574   DataArrayDouble *ret(DataArrayDouble::New());
3575   ret->alloc(nbOfTuple,2);
3576   double *w(ret->getPointer());
3577   const double *wIn(getConstPointer());
3578   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3579     {
3580       w[0]=wIn[0]*cos(wIn[1]);
3581       w[1]=wIn[0]*sin(wIn[1]);
3582     }
3583   return ret;
3584 }
3585
3586 /*!
3587  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3588  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3589  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3590  * 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::fromCylToCart() const
3598 {
3599   checkAllocated();
3600   int nbOfComp(getNumberOfComponents());
3601   if(nbOfComp!=3)
3602     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : 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[1]);
3611       w[1]=wIn[0]*sin(wIn[1]);
3612       w[2]=wIn[2];
3613     }
3614   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3615   return ret;
3616 }
3617
3618 /*!
3619  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3620  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3621  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3622  * point in the Cylindrical CS.
3623  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3624  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3625  *          on the third component is copied from \a this array. The caller
3626  *          is to delete this array using decrRef() as it is no more needed.
3627  *  \throw If \a this->getNumberOfComponents() != 3.
3628  */
3629 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3630 {
3631   checkAllocated();
3632   int nbOfComp(getNumberOfComponents());
3633   if(nbOfComp!=3)
3634     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3635   int nbOfTuple(getNumberOfTuples());
3636   DataArrayDouble *ret(DataArrayDouble::New());
3637   ret->alloc(getNumberOfTuples(),3);
3638   double *w(ret->getPointer());
3639   const double *wIn(getConstPointer());
3640   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3641     {
3642       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3643       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3644       w[2]=wIn[0]*cos(wIn[1]);
3645     }
3646   return ret;
3647 }
3648
3649 /*!
3650  * This method returns a new array containing the same number of tuples than \a this. To do this, this method needs \a at parameter to specify the convention of \a this.
3651  * All the tuples of the returned array will be in cartesian sense. So if \a at equals to AX_CART the returned array is basically a deep copy of \a this.
3652  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
3653  *
3654  * \param [in] atOfThis - The axis type of \a this.
3655  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
3656  */
3657 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
3658 {
3659   checkAllocated();
3660   int nbOfComp(getNumberOfComponents());
3661   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret;
3662   switch(atOfThis)
3663     {
3664     case AX_CART:
3665       ret=deepCpy();
3666     case AX_CYL:
3667       if(nbOfComp==3)
3668         {
3669           ret=fromCylToCart();
3670           break;
3671         }
3672       if(nbOfComp==2)
3673         {
3674           ret=fromPolarToCart();
3675           break;
3676         }
3677       else
3678         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3679     case AX_SPHER:
3680       if(nbOfComp==3)
3681         {
3682           ret=fromSpherToCart();
3683           break;
3684         }
3685       if(nbOfComp==2)
3686         {
3687           ret=fromPolarToCart();
3688           break;
3689         }
3690       else
3691         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3692     default:
3693       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
3694     }
3695   ret->copyStringInfoFrom(*this);
3696   return ret.retn();
3697 }
3698
3699 /*!
3700  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3701  * array contating 6 components.
3702  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3703  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3704  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3705  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3706  *  \throw If \a this->getNumberOfComponents() != 6.
3707  */
3708 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3709 {
3710   checkAllocated();
3711   int nbOfComp(getNumberOfComponents());
3712   if(nbOfComp!=6)
3713     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3714   DataArrayDouble *ret=DataArrayDouble::New();
3715   int nbOfTuple=getNumberOfTuples();
3716   ret->alloc(nbOfTuple,1);
3717   const double *src=getConstPointer();
3718   double *dest=ret->getPointer();
3719   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3720     *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];
3721   return ret;
3722 }
3723
3724 /*!
3725  * Computes the determinant of every square matrix defined by the tuple of \a this
3726  * array, which contains either 4, 6 or 9 components. The case of 6 components
3727  * corresponds to that of the upper triangular matrix.
3728  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3729  *          is the determinant of matrix of the corresponding tuple of \a this array.
3730  *          The caller is to delete this result array using decrRef() as it is no more
3731  *          needed. 
3732  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3733  */
3734 DataArrayDouble *DataArrayDouble::determinant() const
3735 {
3736   checkAllocated();
3737   DataArrayDouble *ret=DataArrayDouble::New();
3738   int nbOfTuple=getNumberOfTuples();
3739   ret->alloc(nbOfTuple,1);
3740   const double *src=getConstPointer();
3741   double *dest=ret->getPointer();
3742   switch(getNumberOfComponents())
3743   {
3744     case 6:
3745       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3746         *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];
3747       return ret;
3748     case 4:
3749       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3750         *dest=src[0]*src[3]-src[1]*src[2];
3751       return ret;
3752     case 9:
3753       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3754         *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];
3755       return ret;
3756     default:
3757       ret->decrRef();
3758       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3759   }
3760 }
3761
3762 /*!
3763  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3764  * \a this array, which contains 6 components.
3765  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3766  *          components, whose each tuple contains the eigenvalues of the matrix of
3767  *          corresponding tuple of \a this array. 
3768  *          The caller is to delete this result array using decrRef() as it is no more
3769  *          needed. 
3770  *  \throw If \a this->getNumberOfComponents() != 6.
3771  */
3772 DataArrayDouble *DataArrayDouble::eigenValues() const
3773 {
3774   checkAllocated();
3775   int nbOfComp=getNumberOfComponents();
3776   if(nbOfComp!=6)
3777     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3778   DataArrayDouble *ret=DataArrayDouble::New();
3779   int nbOfTuple=getNumberOfTuples();
3780   ret->alloc(nbOfTuple,3);
3781   const double *src=getConstPointer();
3782   double *dest=ret->getPointer();
3783   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3784     INTERP_KERNEL::computeEigenValues6(src,dest);
3785   return ret;
3786 }
3787
3788 /*!
3789  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3790  * \a this array, which contains 6 components.
3791  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3792  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3793  *          corresponding tuple of \a this array.
3794  *          The caller is to delete this result array using decrRef() as it is no more
3795  *          needed.
3796  *  \throw If \a this->getNumberOfComponents() != 6.
3797  */
3798 DataArrayDouble *DataArrayDouble::eigenVectors() const
3799 {
3800   checkAllocated();
3801   int nbOfComp=getNumberOfComponents();
3802   if(nbOfComp!=6)
3803     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3804   DataArrayDouble *ret=DataArrayDouble::New();
3805   int nbOfTuple=getNumberOfTuples();
3806   ret->alloc(nbOfTuple,9);
3807   const double *src=getConstPointer();
3808   double *dest=ret->getPointer();
3809   for(int i=0;i<nbOfTuple;i++,src+=6)
3810     {
3811       double tmp[3];
3812       INTERP_KERNEL::computeEigenValues6(src,tmp);
3813       for(int j=0;j<3;j++,dest+=3)
3814         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3815     }
3816   return ret;
3817 }
3818
3819 /*!
3820  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3821  * array, which contains either 4, 6 or 9 components. The case of 6 components
3822  * corresponds to that of the upper triangular matrix.
3823  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3824  *          same number of components as \a this one, whose each tuple is the inverse
3825  *          matrix of the matrix of corresponding tuple of \a this array. 
3826  *          The caller is to delete this result array using decrRef() as it is no more
3827  *          needed. 
3828  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3829  */
3830 DataArrayDouble *DataArrayDouble::inverse() const
3831 {
3832   checkAllocated();
3833   int nbOfComp=getNumberOfComponents();
3834   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3835     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3836   DataArrayDouble *ret=DataArrayDouble::New();
3837   int nbOfTuple=getNumberOfTuples();
3838   ret->alloc(nbOfTuple,nbOfComp);
3839   const double *src=getConstPointer();
3840   double *dest=ret->getPointer();
3841   if(nbOfComp==6)
3842     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3843       {
3844         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];
3845         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3846         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3847         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3848         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3849         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3850         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3851       }
3852   else if(nbOfComp==4)
3853     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3854       {
3855         double det=src[0]*src[3]-src[1]*src[2];
3856         dest[0]=src[3]/det;
3857         dest[1]=-src[1]/det;
3858         dest[2]=-src[2]/det;
3859         dest[3]=src[0]/det;
3860       }
3861   else
3862     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3863       {
3864         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];
3865         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3866         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3867         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3868         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3869         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3870         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3871         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3872         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3873         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3874       }
3875   return ret;
3876 }
3877
3878 /*!
3879  * Computes the trace of every matrix defined by the tuple of \a this
3880  * array, which contains either 4, 6 or 9 components. The case of 6 components
3881  * corresponds to that of the upper triangular matrix.
3882  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3883  *          1 component, whose each tuple is the trace of
3884  *          the matrix of corresponding tuple of \a this array. 
3885  *          The caller is to delete this result array using decrRef() as it is no more
3886  *          needed. 
3887  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3888  */
3889 DataArrayDouble *DataArrayDouble::trace() const
3890 {
3891   checkAllocated();
3892   int nbOfComp=getNumberOfComponents();
3893   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3894     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3895   DataArrayDouble *ret=DataArrayDouble::New();
3896   int nbOfTuple=getNumberOfTuples();
3897   ret->alloc(nbOfTuple,1);
3898   const double *src=getConstPointer();
3899   double *dest=ret->getPointer();
3900   if(nbOfComp==6)
3901     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3902       *dest=src[0]+src[1]+src[2];
3903   else if(nbOfComp==4)
3904     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3905       *dest=src[0]+src[3];
3906   else
3907     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3908       *dest=src[0]+src[4]+src[8];
3909   return ret;
3910 }
3911
3912 /*!
3913  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3914  * \a this array, which contains 6 components.
3915  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3916  *          same number of components and tuples as \a this array.
3917  *          The caller is to delete this result array using decrRef() as it is no more
3918  *          needed.
3919  *  \throw If \a this->getNumberOfComponents() != 6.
3920  */
3921 DataArrayDouble *DataArrayDouble::deviator() const
3922 {
3923   checkAllocated();
3924   int nbOfComp=getNumberOfComponents();
3925   if(nbOfComp!=6)
3926     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3927   DataArrayDouble *ret=DataArrayDouble::New();
3928   int nbOfTuple=getNumberOfTuples();
3929   ret->alloc(nbOfTuple,6);
3930   const double *src=getConstPointer();
3931   double *dest=ret->getPointer();
3932   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3933     {
3934       double tr=(src[0]+src[1]+src[2])/3.;
3935       dest[0]=src[0]-tr;
3936       dest[1]=src[1]-tr;
3937       dest[2]=src[2]-tr;
3938       dest[3]=src[3];
3939       dest[4]=src[4];
3940       dest[5]=src[5];
3941     }
3942   return ret;
3943 }
3944
3945 /*!
3946  * Computes the magnitude of every vector defined by the tuple of
3947  * \a this array.
3948  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3949  *          same number of tuples as \a this array and one component.
3950  *          The caller is to delete this result array using decrRef() as it is no more
3951  *          needed.
3952  *  \throw If \a this is not allocated.
3953  */
3954 DataArrayDouble *DataArrayDouble::magnitude() const
3955 {
3956   checkAllocated();
3957   int nbOfComp=getNumberOfComponents();
3958   DataArrayDouble *ret=DataArrayDouble::New();
3959   int nbOfTuple=getNumberOfTuples();
3960   ret->alloc(nbOfTuple,1);
3961   const double *src=getConstPointer();
3962   double *dest=ret->getPointer();
3963   for(int i=0;i<nbOfTuple;i++,dest++)
3964     {
3965       double sum=0.;
3966       for(int j=0;j<nbOfComp;j++,src++)
3967         sum+=(*src)*(*src);
3968       *dest=sqrt(sum);
3969     }
3970   return ret;
3971 }
3972
3973 /*!
3974  * Computes for each tuple the sum of number of components values in the tuple and return it.
3975  * 
3976  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3977  *          same number of tuples as \a this array and one component.
3978  *          The caller is to delete this result array using decrRef() as it is no more
3979  *          needed.
3980  *  \throw If \a this is not allocated.
3981  */
3982 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3983 {
3984   checkAllocated();
3985   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3986   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3987   ret->alloc(nbOfTuple,1);
3988   const double *src(getConstPointer());
3989   double *dest(ret->getPointer());
3990   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3991     *dest=std::accumulate(src,src+nbOfComp,0.);
3992   return ret.retn();
3993 }
3994
3995 /*!
3996  * Computes the maximal value within every tuple of \a this array.
3997  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3998  *          same number of tuples as \a this array and one component.
3999  *          The caller is to delete this result array using decrRef() as it is no more
4000  *          needed.
4001  *  \throw If \a this is not allocated.
4002  *  \sa DataArrayDouble::maxPerTupleWithCompoId
4003  */
4004 DataArrayDouble *DataArrayDouble::maxPerTuple() const
4005 {
4006   checkAllocated();
4007   int nbOfComp=getNumberOfComponents();
4008   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4009   int nbOfTuple=getNumberOfTuples();
4010   ret->alloc(nbOfTuple,1);
4011   const double *src=getConstPointer();
4012   double *dest=ret->getPointer();
4013   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4014     *dest=*std::max_element(src,src+nbOfComp);
4015   return ret.retn();
4016 }
4017
4018 /*!
4019  * Computes the maximal value within every tuple of \a this array and it returns the first component
4020  * id for each tuple that corresponds to the maximal value within the tuple.
4021  * 
4022  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
4023  *          same number of tuples and only one component.
4024  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4025  *          same number of tuples as \a this array and one component.
4026  *          The caller is to delete this result array using decrRef() as it is no more
4027  *          needed.
4028  *  \throw If \a this is not allocated.
4029  *  \sa DataArrayDouble::maxPerTuple
4030  */
4031 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
4032 {
4033   checkAllocated();
4034   int nbOfComp=getNumberOfComponents();
4035   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
4036   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
4037   int nbOfTuple=getNumberOfTuples();
4038   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
4039   const double *src=getConstPointer();
4040   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
4041   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
4042     {
4043       const double *loc=std::max_element(src,src+nbOfComp);
4044       *dest=*loc;
4045       *dest1=(int)std::distance(src,loc);
4046     }
4047   compoIdOfMaxPerTuple=ret1.retn();
4048   return ret0.retn();
4049 }
4050
4051 /*!
4052  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
4053  * \n This returned array contains the euclidian distance for each tuple in \a this. 
4054  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
4055  * \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)
4056  *
4057  * \warning use this method with care because it can leads to big amount of consumed memory !
4058  * 
4059  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4060  *
4061  * \throw If \a this is not allocated.
4062  *
4063  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
4064  */
4065 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
4066 {
4067   checkAllocated();
4068   int nbOfComp=getNumberOfComponents();
4069   int nbOfTuples=getNumberOfTuples();
4070   const double *inData=getConstPointer();
4071   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4072   ret->alloc(nbOfTuples*nbOfTuples,1);
4073   double *outData=ret->getPointer();
4074   for(int i=0;i<nbOfTuples;i++)
4075     {
4076       outData[i*nbOfTuples+i]=0.;
4077       for(int j=i+1;j<nbOfTuples;j++)
4078         {
4079           double dist=0.;
4080           for(int k=0;k<nbOfComp;k++)
4081             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4082           dist=sqrt(dist);
4083           outData[i*nbOfTuples+j]=dist;
4084           outData[j*nbOfTuples+i]=dist;
4085         }
4086     }
4087   return ret.retn();
4088 }
4089
4090 /*!
4091  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4092  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4093  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4094  * \n Output rectangular matrix is sorted along rows.
4095  * \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)
4096  *
4097  * \warning use this method with care because it can leads to big amount of consumed memory !
4098  * 
4099  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4100  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4101  *
4102  * \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.
4103  *
4104  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4105  */
4106 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4107 {
4108   if(!other)
4109     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4110   checkAllocated();
4111   other->checkAllocated();
4112   int nbOfComp=getNumberOfComponents();
4113   int otherNbOfComp=other->getNumberOfComponents();
4114   if(nbOfComp!=otherNbOfComp)
4115     {
4116       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4117       throw INTERP_KERNEL::Exception(oss.str().c_str());
4118     }
4119   int nbOfTuples=getNumberOfTuples();
4120   int otherNbOfTuples=other->getNumberOfTuples();
4121   const double *inData=getConstPointer();
4122   const double *inDataOther=other->getConstPointer();
4123   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4124   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4125   double *outData=ret->getPointer();
4126   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4127     {
4128       for(int j=0;j<nbOfTuples;j++)
4129         {
4130           double dist=0.;
4131           for(int k=0;k<nbOfComp;k++)
4132             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4133           dist=sqrt(dist);
4134           outData[i*nbOfTuples+j]=dist;
4135         }
4136     }
4137   return ret.retn();
4138 }
4139
4140 /*!
4141  * Sorts value within every tuple of \a this array.
4142  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4143  *              in descending order.
4144  *  \throw If \a this is not allocated.
4145  */
4146 void DataArrayDouble::sortPerTuple(bool asc)
4147 {
4148   checkAllocated();
4149   double *pt=getPointer();
4150   int nbOfTuple=getNumberOfTuples();
4151   int nbOfComp=getNumberOfComponents();
4152   if(asc)
4153     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4154       std::sort(pt,pt+nbOfComp);
4155   else
4156     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4157       std::sort(pt,pt+nbOfComp,std::greater<double>());
4158   declareAsNew();
4159 }
4160
4161 /*!
4162  * Converts every value of \a this array to its absolute value.
4163  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4164  * should be called instead.
4165  *
4166  * \throw If \a this is not allocated.
4167  * \sa DataArrayDouble::computeAbs
4168  */
4169 void DataArrayDouble::abs()
4170 {
4171   checkAllocated();
4172   double *ptr(getPointer());
4173   std::size_t nbOfElems(getNbOfElems());
4174   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4175   declareAsNew();
4176 }
4177
4178 /*!
4179  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4180  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4181  *
4182  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4183  *         same number of tuples and component as \a this array.
4184  *         The caller is to delete this result array using decrRef() as it is no more
4185  *         needed.
4186  * \throw If \a this is not allocated.
4187  * \sa DataArrayDouble::abs
4188  */
4189 DataArrayDouble *DataArrayDouble::computeAbs() const
4190 {
4191   checkAllocated();
4192   DataArrayDouble *newArr(DataArrayDouble::New());
4193   int nbOfTuples(getNumberOfTuples());
4194   int nbOfComp(getNumberOfComponents());
4195   newArr->alloc(nbOfTuples,nbOfComp);
4196   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4197   newArr->copyStringInfoFrom(*this);
4198   return newArr;
4199 }
4200
4201 /*!
4202  * Apply a linear function to a given component of \a this array, so that
4203  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4204  *  \param [in] a - the first coefficient of the function.
4205  *  \param [in] b - the second coefficient of the function.
4206  *  \param [in] compoId - the index of component to modify.
4207  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4208  */
4209 void DataArrayDouble::applyLin(double a, double b, int compoId)
4210 {
4211   checkAllocated();
4212   double *ptr(getPointer()+compoId);
4213   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4214   if(compoId<0 || compoId>=nbOfComp)
4215     {
4216       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4217       throw INTERP_KERNEL::Exception(oss.str().c_str());
4218     }
4219   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4220     *ptr=a*(*ptr)+b;
4221   declareAsNew();
4222 }
4223
4224 /*!
4225  * Apply a linear function to all elements of \a this array, so that
4226  * an element _x_ becomes \f$ a * x + b \f$.
4227  *  \param [in] a - the first coefficient of the function.
4228  *  \param [in] b - the second coefficient of the function.
4229  *  \throw If \a this is not allocated.
4230  */
4231 void DataArrayDouble::applyLin(double a, double b)
4232 {
4233   checkAllocated();
4234   double *ptr=getPointer();
4235   std::size_t nbOfElems=getNbOfElems();
4236   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4237     *ptr=a*(*ptr)+b;
4238   declareAsNew();
4239 }
4240
4241 /*!
4242  * Modify all elements of \a this array, so that
4243  * an element _x_ becomes \f$ numerator / x \f$.
4244  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4245  *           array, all elements processed before detection of the zero element remain
4246  *           modified.
4247  *  \param [in] numerator - the numerator used to modify array elements.
4248  *  \throw If \a this is not allocated.
4249  *  \throw If there is an element equal to 0.0 in \a this array.
4250  */
4251 void DataArrayDouble::applyInv(double numerator)
4252 {
4253   checkAllocated();
4254   double *ptr=getPointer();
4255   std::size_t nbOfElems=getNbOfElems();
4256   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4257     {
4258       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4259         {
4260           *ptr=numerator/(*ptr);
4261         }
4262       else
4263         {
4264           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4265           oss << " !";
4266           throw INTERP_KERNEL::Exception(oss.str().c_str());
4267         }
4268     }
4269   declareAsNew();
4270 }
4271
4272 /*!
4273  * Returns a full copy of \a this array except that sign of all elements is reversed.
4274  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4275  *          same number of tuples and component as \a this array.
4276  *          The caller is to delete this result array using decrRef() as it is no more
4277  *          needed.
4278  *  \throw If \a this is not allocated.
4279  */
4280 DataArrayDouble *DataArrayDouble::negate() const
4281 {
4282   checkAllocated();
4283   DataArrayDouble *newArr=DataArrayDouble::New();
4284   int nbOfTuples=getNumberOfTuples();
4285   int nbOfComp=getNumberOfComponents();
4286   newArr->alloc(nbOfTuples,nbOfComp);
4287   const double *cptr=getConstPointer();
4288   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4289   newArr->copyStringInfoFrom(*this);
4290   return newArr;
4291 }
4292
4293 /*!
4294  * Modify all elements of \a this array, so that
4295  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4296  * all values in \a this have to be >= 0 if val is \b not integer.
4297  *  \param [in] val - the value used to apply pow on all array elements.
4298  *  \throw If \a this is not allocated.
4299  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4300  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4301  *           modified.
4302  */
4303 void DataArrayDouble::applyPow(double val)
4304 {
4305   checkAllocated();
4306   double *ptr=getPointer();
4307   std::size_t nbOfElems=getNbOfElems();
4308   int val2=(int)val;
4309   bool isInt=((double)val2)==val;
4310   if(!isInt)
4311     {
4312       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4313         {
4314           if(*ptr>=0)
4315             *ptr=pow(*ptr,val);
4316           else
4317             {
4318               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4319               throw INTERP_KERNEL::Exception(oss.str().c_str());
4320             }
4321         }
4322     }
4323   else
4324     {
4325       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4326         *ptr=pow(*ptr,val2);
4327     }
4328   declareAsNew();
4329 }
4330
4331 /*!
4332  * Modify all elements of \a this array, so that
4333  * an element _x_ becomes \f$ val ^ x \f$.
4334  *  \param [in] val - the value used to apply pow on all array elements.
4335  *  \throw If \a this is not allocated.
4336  *  \throw If \a val < 0.
4337  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4338  *           array, all elements processed before detection of the zero element remain
4339  *           modified.
4340  */
4341 void DataArrayDouble::applyRPow(double val)
4342 {
4343   checkAllocated();
4344   if(val<0.)
4345     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4346   double *ptr=getPointer();
4347   std::size_t nbOfElems=getNbOfElems();
4348   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4349     *ptr=pow(val,*ptr);
4350   declareAsNew();
4351 }
4352
4353 /*!
4354  * Returns a new DataArrayDouble created from \a this one by applying \a
4355  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4356  * For more info see \ref MEDCouplingArrayApplyFunc
4357  *  \param [in] nbOfComp - number of components in the result array.
4358  *  \param [in] func - the \a FunctionToEvaluate declared as 
4359  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4360  *              where \a pos points to the first component of a tuple of \a this array
4361  *              and \a res points to the first component of a tuple of the result array.
4362  *              Note that length (number of components) of \a pos can differ from
4363  *              that of \a res.
4364  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4365  *          same number of tuples as \a this array.
4366  *          The caller is to delete this result array using decrRef() as it is no more
4367  *          needed.
4368  *  \throw If \a this is not allocated.
4369  *  \throw If \a func returns \a false.
4370  */
4371 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4372 {
4373   checkAllocated();
4374   DataArrayDouble *newArr=DataArrayDouble::New();
4375   int nbOfTuples=getNumberOfTuples();
4376   int oldNbOfComp=getNumberOfComponents();
4377   newArr->alloc(nbOfTuples,nbOfComp);
4378   const double *ptr=getConstPointer();
4379   double *ptrToFill=newArr->getPointer();
4380   for(int i=0;i<nbOfTuples;i++)
4381     {
4382       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4383         {
4384           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4385           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4386           oss << ") : Evaluation of function failed !";
4387           newArr->decrRef();
4388           throw INTERP_KERNEL::Exception(oss.str().c_str());
4389         }
4390     }
4391   return newArr;
4392 }
4393
4394 /*!
4395  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4396  * tuple of \a this array. Textual data is not copied.
4397  * For more info see \ref MEDCouplingArrayApplyFunc1.
4398  *  \param [in] nbOfComp - number of components in the result array.
4399  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4400  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4401  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4402  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4403  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4404  *          same number of tuples as \a this array and \a nbOfComp components.
4405  *          The caller is to delete this result array using decrRef() as it is no more
4406  *          needed.
4407  *  \throw If \a this is not allocated.
4408  *  \throw If computing \a func fails.
4409  */
4410 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4411 {
4412   INTERP_KERNEL::ExprParser expr(func);
4413   expr.parse();
4414   std::set<std::string> vars;
4415   expr.getTrueSetOfVars(vars);
4416   std::vector<std::string> varsV(vars.begin(),vars.end());
4417   return applyFunc3(nbOfComp,varsV,func,isSafe);
4418 }
4419
4420 /*!
4421  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4422  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4423  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4424  *
4425  * For more info see \ref MEDCouplingArrayApplyFunc0.
4426  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4427  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4428  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4429  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4430  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4431  *          same number of tuples and components as \a this array.
4432  *          The caller is to delete this result array using decrRef() as it is no more
4433  *          needed.
4434  *  \sa applyFuncOnThis
4435  *  \throw If \a this is not allocated.
4436  *  \throw If computing \a func fails.
4437  */
4438 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4439 {
4440   int nbOfComp(getNumberOfComponents());
4441   if(nbOfComp<=0)
4442     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4443   checkAllocated();
4444   int nbOfTuples(getNumberOfTuples());
4445   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4446   newArr->alloc(nbOfTuples,nbOfComp);
4447   INTERP_KERNEL::ExprParser expr(func);
4448   expr.parse();
4449   std::set<std::string> vars;
4450   expr.getTrueSetOfVars(vars);
4451   if((int)vars.size()>1)
4452     {
4453       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 : ";
4454       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4455       throw INTERP_KERNEL::Exception(oss.str().c_str());
4456     }
4457   if(vars.empty())
4458     {
4459       expr.prepareFastEvaluator();
4460       newArr->rearrange(1);
4461       newArr->fillWithValue(expr.evaluateDouble());
4462       newArr->rearrange(nbOfComp);
4463       return newArr.retn();
4464     }
4465   std::vector<std::string> vars2(vars.begin(),vars.end());
4466   double buff,*ptrToFill(newArr->getPointer());
4467   const double *ptr(begin());
4468   std::vector<double> stck;
4469   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4470   expr.prepareFastEvaluator();
4471   if(!isSafe)
4472     {
4473       for(int i=0;i<nbOfTuples;i++)
4474         {
4475           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4476             {
4477               buff=*ptr;
4478               expr.evaluateDoubleInternal(stck);
4479               *ptrToFill=stck.back();
4480               stck.pop_back();
4481             }
4482         }
4483     }
4484   else
4485     {
4486       for(int i=0;i<nbOfTuples;i++)
4487         {
4488           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4489             {
4490               buff=*ptr;
4491               try
4492               {
4493                   expr.evaluateDoubleInternalSafe(stck);
4494               }
4495               catch(INTERP_KERNEL::Exception& e)
4496               {
4497                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4498                   oss << buff;
4499                   oss << ") : Evaluation of function failed !" << e.what();
4500                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4501               }
4502               *ptrToFill=stck.back();
4503               stck.pop_back();
4504             }
4505         }
4506     }
4507   return newArr.retn();
4508 }
4509
4510 /*!
4511  * This method is a non const method that modify the array in \a this.
4512  * This method only works on one component array. It means that function \a func must
4513  * contain at most one variable.
4514  * This method is a specialization of applyFunc method with one parameter on one component array.
4515  *
4516  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4517  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4518  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4519  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4520  *
4521  * \sa applyFunc
4522  */
4523 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4524 {
4525   int nbOfComp(getNumberOfComponents());
4526   if(nbOfComp<=0)
4527     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4528   checkAllocated();
4529   int nbOfTuples(getNumberOfTuples());
4530   INTERP_KERNEL::ExprParser expr(func);
4531   expr.parse();
4532   std::set<std::string> vars;
4533   expr.getTrueSetOfVars(vars);
4534   if((int)vars.size()>1)
4535     {
4536       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 : ";
4537       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4538       throw INTERP_KERNEL::Exception(oss.str().c_str());
4539     }
4540   if(vars.empty())
4541     {
4542       expr.prepareFastEvaluator();
4543       std::vector<std::string> compInfo(getInfoOnComponents());
4544       rearrange(1);
4545       fillWithValue(expr.evaluateDouble());
4546       rearrange(nbOfComp);
4547       setInfoOnComponents(compInfo);
4548       return ;
4549     }
4550   std::vector<std::string> vars2(vars.begin(),vars.end());
4551   double buff,*ptrToFill(getPointer());
4552   const double *ptr(begin());
4553   std::vector<double> stck;
4554   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4555   expr.prepareFastEvaluator();
4556   if(!isSafe)
4557     {
4558       for(int i=0;i<nbOfTuples;i++)
4559         {
4560           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4561             {
4562               buff=*ptr;
4563               expr.evaluateDoubleInternal(stck);
4564               *ptrToFill=stck.back();
4565               stck.pop_back();
4566             }
4567         }
4568     }
4569   else
4570     {
4571       for(int i=0;i<nbOfTuples;i++)
4572         {
4573           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4574             {
4575               buff=*ptr;
4576               try
4577               {
4578                   expr.evaluateDoubleInternalSafe(stck);
4579               }
4580               catch(INTERP_KERNEL::Exception& e)
4581               {
4582                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4583                   oss << buff;
4584                   oss << ") : Evaluation of function failed !" << e.what();
4585                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4586               }
4587               *ptrToFill=stck.back();
4588               stck.pop_back();
4589             }
4590         }
4591     }
4592 }
4593
4594 /*!
4595  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4596  * tuple of \a this array. Textual data is not copied.
4597  * For more info see \ref MEDCouplingArrayApplyFunc2.
4598  *  \param [in] nbOfComp - number of components in the result array.
4599  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4600  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4601  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4602  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4603  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4604  *          same number of tuples as \a this array.
4605  *          The caller is to delete this result array using decrRef() as it is no more
4606  *          needed.
4607  *  \throw If \a this is not allocated.
4608  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4609  *  \throw If computing \a func fails.
4610  */
4611 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const
4612 {
4613   return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe);
4614 }
4615
4616 /*!
4617  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4618  * tuple of \a this array. Textual data is not copied.
4619  * For more info see \ref MEDCouplingArrayApplyFunc3.
4620  *  \param [in] nbOfComp - number of components in the result array.
4621  *  \param [in] varsOrder - sequence of vars defining their order.
4622  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4623  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4624  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4625  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4626  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4627  *          same number of tuples as \a this array.
4628  *          The caller is to delete this result array using decrRef() as it is no more
4629  *          needed.
4630  *  \throw If \a this is not allocated.
4631  *  \throw If \a func contains vars not in \a varsOrder.
4632  *  \throw If computing \a func fails.
4633  */
4634 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4635 {
4636   if(nbOfComp<=0)
4637     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !");
4638   std::vector<std::string> varsOrder2(varsOrder);
4639   int oldNbOfComp(getNumberOfComponents());
4640   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4641     varsOrder2.push_back(std::string());
4642   checkAllocated();
4643   int nbOfTuples(getNumberOfTuples());
4644   INTERP_KERNEL::ExprParser expr(func);
4645   expr.parse();
4646   std::set<std::string> vars;
4647   expr.getTrueSetOfVars(vars);
4648   if((int)vars.size()>oldNbOfComp)
4649     {
4650       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4651       oss << vars.size() << " variables : ";
4652       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4653       throw INTERP_KERNEL::Exception(oss.str().c_str());
4654     }
4655   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4656   newArr->alloc(nbOfTuples,nbOfComp);
4657   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4658   double *buffPtr(buff),*ptrToFill;
4659   std::vector<double> stck;
4660   for(int iComp=0;iComp<nbOfComp;iComp++)
4661     {
4662       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4663       expr.prepareFastEvaluator();
4664       const double *ptr(getConstPointer());
4665       ptrToFill=newArr->getPointer()+iComp;
4666       if(!isSafe)
4667         {
4668           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4669             {
4670               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4671               expr.evaluateDoubleInternal(stck);
4672               *ptrToFill=stck.back();
4673               stck.pop_back();
4674             }
4675         }
4676       else
4677         {
4678           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4679             {
4680               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4681               try
4682               {
4683                   expr.evaluateDoubleInternalSafe(stck);
4684                   *ptrToFill=stck.back();
4685                   stck.pop_back();
4686               }
4687               catch(INTERP_KERNEL::Exception& e)
4688               {
4689                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4690                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4691                   oss << ") : Evaluation of function failed !" << e.what();
4692                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4693               }
4694             }
4695         }
4696     }
4697   return newArr.retn();
4698 }
4699
4700 void DataArrayDouble::applyFuncFast32(const std::string& func)
4701 {
4702   checkAllocated();
4703   INTERP_KERNEL::ExprParser expr(func);
4704   expr.parse();
4705   char *funcStr=expr.compileX86();
4706   MYFUNCPTR funcPtr;
4707   *((void **)&funcPtr)=funcStr;//he he...
4708   //
4709   double *ptr=getPointer();
4710   int nbOfComp=getNumberOfComponents();
4711   int nbOfTuples=getNumberOfTuples();
4712   int nbOfElems=nbOfTuples*nbOfComp;
4713   for(int i=0;i<nbOfElems;i++,ptr++)
4714     *ptr=funcPtr(*ptr);
4715   declareAsNew();
4716 }
4717
4718 void DataArrayDouble::applyFuncFast64(const std::string& func)
4719 {
4720   checkAllocated();
4721   INTERP_KERNEL::ExprParser expr(func);
4722   expr.parse();
4723   char *funcStr=expr.compileX86_64();
4724   MYFUNCPTR funcPtr;
4725   *((void **)&funcPtr)=funcStr;//he he...
4726   //
4727   double *ptr=getPointer();
4728   int nbOfComp=getNumberOfComponents();
4729   int nbOfTuples=getNumberOfTuples();
4730   int nbOfElems=nbOfTuples*nbOfComp;
4731   for(int i=0;i<nbOfElems;i++,ptr++)
4732     *ptr=funcPtr(*ptr);
4733   declareAsNew();
4734 }
4735
4736 DataArrayDoubleIterator *DataArrayDouble::iterator()
4737 {
4738   return new DataArrayDoubleIterator(this);
4739 }
4740
4741 /*!
4742  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4743  * array whose values are within a given range. Textual data is not copied.
4744  *  \param [in] vmin - a lowest acceptable value (included).
4745  *  \param [in] vmax - a greatest acceptable value (included).
4746  *  \return DataArrayInt * - the new instance of DataArrayInt.
4747  *          The caller is to delete this result array using decrRef() as it is no more
4748  *          needed.
4749  *  \throw If \a this->getNumberOfComponents() != 1.
4750  *
4751  *  \sa DataArrayDouble::getIdsNotInRange
4752  *
4753  *  \if ENABLE_EXAMPLES
4754  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4755  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4756  *  \endif
4757  */
4758 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4759 {
4760   checkAllocated();
4761   if(getNumberOfComponents()!=1)
4762     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4763   const double *cptr(begin());
4764   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4765   int nbOfTuples(getNumberOfTuples());
4766   for(int i=0;i<nbOfTuples;i++,cptr++)
4767     if(*cptr>=vmin && *cptr<=vmax)
4768       ret->pushBackSilent(i);
4769   return ret.retn();
4770 }
4771
4772 /*!
4773  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4774  * array whose values are not within a given range. Textual data is not copied.
4775  *  \param [in] vmin - a lowest not acceptable value (excluded).
4776  *  \param [in] vmax - a greatest not acceptable value (excluded).
4777  *  \return DataArrayInt * - the new instance of DataArrayInt.
4778  *          The caller is to delete this result array using decrRef() as it is no more
4779  *          needed.
4780  *  \throw If \a this->getNumberOfComponents() != 1.
4781  *
4782  *  \sa DataArrayDouble::getIdsInRange
4783  */
4784 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4785 {
4786   checkAllocated();
4787   if(getNumberOfComponents()!=1)
4788     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4789   const double *cptr(begin());
4790   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4791   int nbOfTuples(getNumberOfTuples());
4792   for(int i=0;i<nbOfTuples;i++,cptr++)
4793     if(*cptr<vmin || *cptr>vmax)
4794       ret->pushBackSilent(i);
4795   return ret.retn();
4796 }
4797
4798 /*!
4799  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4800  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4801  * the number of component in the result array is same as that of each of given arrays.
4802  * Info on components is copied from the first of the given arrays. Number of components
4803  * in the given arrays must be  the same.
4804  *  \param [in] a1 - an array to include in the result array.
4805  *  \param [in] a2 - another array to include in the result array.
4806  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4807  *          The caller is to delete this result array using decrRef() as it is no more
4808  *          needed.
4809  *  \throw If both \a a1 and \a a2 are NULL.
4810  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4811  */
4812 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4813 {
4814   std::vector<const DataArrayDouble *> tmp(2);
4815   tmp[0]=a1; tmp[1]=a2;
4816   return Aggregate(tmp);
4817 }
4818
4819 /*!
4820  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4821  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4822  * the number of component in the result array is same as that of each of given arrays.
4823  * Info on components is copied from the first of the given arrays. Number of components
4824  * in the given arrays must be  the same.
4825  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4826  * not the object itself.
4827  *  \param [in] arr - a sequence of arrays to include in the result array.
4828  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4829  *          The caller is to delete this result array using decrRef() as it is no more
4830  *          needed.
4831  *  \throw If all arrays within \a arr are NULL.
4832  *  \throw If getNumberOfComponents() of arrays within \a arr.
4833  */
4834 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4835 {
4836   std::vector<const DataArrayDouble *> a;
4837   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4838     if(*it4)
4839       a.push_back(*it4);
4840   if(a.empty())
4841     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4842   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4843   int nbOfComp=(*it)->getNumberOfComponents();
4844   int nbt=(*it++)->getNumberOfTuples();
4845   for(int i=1;it!=a.end();it++,i++)
4846     {
4847       if((*it)->getNumberOfComponents()!=nbOfComp)
4848         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4849       nbt+=(*it)->getNumberOfTuples();
4850     }
4851   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4852   ret->alloc(nbt,nbOfComp);
4853   double *pt=ret->getPointer();
4854   for(it=a.begin();it!=a.end();it++)
4855     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4856   ret->copyStringInfoFrom(*(a[0]));
4857   return ret.retn();
4858 }
4859
4860 /*!
4861  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4862  * of components in the result array is a sum of the number of components of given arrays
4863  * and (2) the number of tuples in the result array is same as that of each of given
4864  * arrays. In other words the i-th tuple of result array includes all components of
4865  * i-th tuples of all given arrays.
4866  * Number of tuples in the given arrays must be  the same.
4867  *  \param [in] a1 - an array to include in the result array.
4868  *  \param [in] a2 - another array to include in the result array.
4869  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4870  *          The caller is to delete this result array using decrRef() as it is no more
4871  *          needed.
4872  *  \throw If both \a a1 and \a a2 are NULL.
4873  *  \throw If any given array is not allocated.
4874  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4875  */
4876 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4877 {
4878   std::vector<const DataArrayDouble *> arr(2);
4879   arr[0]=a1; arr[1]=a2;
4880   return Meld(arr);
4881 }
4882
4883 /*!
4884  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4885  * of components in the result array is a sum of the number of components of given arrays
4886  * and (2) the number of tuples in the result array is same as that of each of given
4887  * arrays. In other words the i-th tuple of result array includes all components of
4888  * i-th tuples of all given arrays.
4889  * Number of tuples in the given arrays must be  the same.
4890  *  \param [in] arr - a sequence of arrays to include in the result array.
4891  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4892  *          The caller is to delete this result array using decrRef() as it is no more
4893  *          needed.
4894  *  \throw If all arrays within \a arr are NULL.
4895  *  \throw If any given array is not allocated.
4896  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4897  */
4898 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4899 {
4900   std::vector<const DataArrayDouble *> a;
4901   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4902     if(*it4)
4903       a.push_back(*it4);
4904   if(a.empty())
4905     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4906   std::vector<const DataArrayDouble *>::const_iterator it;
4907   for(it=a.begin();it!=a.end();it++)
4908     (*it)->checkAllocated();
4909   it=a.begin();
4910   int nbOfTuples=(*it)->getNumberOfTuples();
4911   std::vector<int> nbc(a.size());
4912   std::vector<const double *> pts(a.size());
4913   nbc[0]=(*it)->getNumberOfComponents();
4914   pts[0]=(*it++)->getConstPointer();
4915   for(int i=1;it!=a.end();it++,i++)
4916     {
4917       if(nbOfTuples!=(*it)->getNumberOfTuples())
4918         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4919       nbc[i]=(*it)->getNumberOfComponents();
4920       pts[i]=(*it)->getConstPointer();
4921     }
4922   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4923   DataArrayDouble *ret=DataArrayDouble::New();
4924   ret->alloc(nbOfTuples,totalNbOfComp);
4925   double *retPtr=ret->getPointer();
4926   for(int i=0;i<nbOfTuples;i++)
4927     for(int j=0;j<(int)a.size();j++)
4928       {
4929         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4930         pts[j]+=nbc[j];
4931       }
4932   int k=0;
4933   for(int i=0;i<(int)a.size();i++)
4934     for(int j=0;j<nbc[i];j++,k++)
4935       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4936   return ret;
4937 }
4938
4939 /*!
4940  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4941  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4942  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4943  * Info on components and name is copied from the first of the given arrays.
4944  * Number of tuples and components in the given arrays must be the same.
4945  *  \param [in] a1 - a given array.
4946  *  \param [in] a2 - another given array.
4947  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4948  *          The caller is to delete this result array using decrRef() as it is no more
4949  *          needed.
4950  *  \throw If either \a a1 or \a a2 is NULL.
4951  *  \throw If any given array is not allocated.
4952  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4953  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4954  */
4955 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4956 {
4957   if(!a1 || !a2)
4958     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4959   a1->checkAllocated();
4960   a2->checkAllocated();
4961   int nbOfComp=a1->getNumberOfComponents();
4962   if(nbOfComp!=a2->getNumberOfComponents())
4963     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4964   int nbOfTuple=a1->getNumberOfTuples();
4965   if(nbOfTuple!=a2->getNumberOfTuples())
4966     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4967   DataArrayDouble *ret=DataArrayDouble::New();
4968   ret->alloc(nbOfTuple,1);
4969   double *retPtr=ret->getPointer();
4970   const double *a1Ptr=a1->getConstPointer();
4971   const double *a2Ptr=a2->getConstPointer();
4972   for(int i=0;i<nbOfTuple;i++)
4973     {
4974       double sum=0.;
4975       for(int j=0;j<nbOfComp;j++)
4976         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4977       retPtr[i]=sum;
4978     }
4979   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4980   ret->setName(a1->getName());
4981   return ret;
4982 }
4983
4984 /*!
4985  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4986  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4987  * product of two vectors defined by the i-th tuples of given arrays.
4988  * Info on components is copied from the first of the given arrays.
4989  * Number of tuples in the given arrays must be the same.
4990  * Number of components in the given arrays must be 3.
4991  *  \param [in] a1 - a given array.
4992  *  \param [in] a2 - another given array.
4993  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4994  *          The caller is to delete this result array using decrRef() as it is no more
4995  *          needed.
4996  *  \throw If either \a a1 or \a a2 is NULL.
4997  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4998  *  \throw If \a a1->getNumberOfComponents() != 3
4999  *  \throw If \a a2->getNumberOfComponents() != 3
5000  */
5001 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
5002 {
5003   if(!a1 || !a2)
5004     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
5005   int nbOfComp=a1->getNumberOfComponents();
5006   if(nbOfComp!=a2->getNumberOfComponents())
5007     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
5008   if(nbOfComp!=3)
5009     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
5010   int nbOfTuple=a1->getNumberOfTuples();
5011   if(nbOfTuple!=a2->getNumberOfTuples())
5012     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
5013   DataArrayDouble *ret=DataArrayDouble::New();
5014   ret->alloc(nbOfTuple,3);
5015   double *retPtr=ret->getPointer();
5016   const double *a1Ptr=a1->getConstPointer();
5017   const double *a2Ptr=a2->getConstPointer();
5018   for(int i=0;i<nbOfTuple;i++)
5019     {
5020       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
5021       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
5022       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
5023     }
5024   ret->copyStringInfoFrom(*a1);
5025   return ret;
5026 }
5027
5028 /*!
5029  * Returns a new DataArrayDouble containing maximal values of two given arrays.
5030  * Info on components is copied from the first of the given arrays.
5031  * Number of tuples and components in the given arrays must be the same.
5032  *  \param [in] a1 - an array to compare values with another one.
5033  *  \param [in] a2 - another array to compare values with the first one.
5034  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5035  *          The caller is to delete this result array using decrRef() as it is no more
5036  *          needed.
5037  *  \throw If either \a a1 or \a a2 is NULL.
5038  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5039  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5040  */
5041 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
5042 {
5043   if(!a1 || !a2)
5044     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
5045   int nbOfComp=a1->getNumberOfComponents();
5046   if(nbOfComp!=a2->getNumberOfComponents())
5047     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
5048   int nbOfTuple=a1->getNumberOfTuples();
5049   if(nbOfTuple!=a2->getNumberOfTuples())
5050     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
5051   DataArrayDouble *ret=DataArrayDouble::New();
5052   ret->alloc(nbOfTuple,nbOfComp);
5053   double *retPtr=ret->getPointer();
5054   const double *a1Ptr=a1->getConstPointer();
5055   const double *a2Ptr=a2->getConstPointer();
5056   int nbElem=nbOfTuple*nbOfComp;
5057   for(int i=0;i<nbElem;i++)
5058     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
5059   ret->copyStringInfoFrom(*a1);
5060   return ret;
5061 }
5062
5063 /*!
5064  * Returns a new DataArrayDouble containing minimal values of two given arrays.
5065  * Info on components is copied from the first of the given arrays.
5066  * Number of tuples and components in the given arrays must be the same.
5067  *  \param [in] a1 - an array to compare values with another one.
5068  *  \param [in] a2 - another array to compare values with the first one.
5069  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5070  *          The caller is to delete this result array using decrRef() as it is no more
5071  *          needed.
5072  *  \throw If either \a a1 or \a a2 is NULL.
5073  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5074  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5075  */
5076 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
5077 {
5078   if(!a1 || !a2)
5079     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
5080   int nbOfComp=a1->getNumberOfComponents();
5081   if(nbOfComp!=a2->getNumberOfComponents())
5082     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5083   int nbOfTuple=a1->getNumberOfTuples();
5084   if(nbOfTuple!=a2->getNumberOfTuples())
5085     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5086   DataArrayDouble *ret=DataArrayDouble::New();
5087   ret->alloc(nbOfTuple,nbOfComp);
5088   double *retPtr=ret->getPointer();
5089   const double *a1Ptr=a1->getConstPointer();
5090   const double *a2Ptr=a2->getConstPointer();
5091   int nbElem=nbOfTuple*nbOfComp;
5092   for(int i=0;i<nbElem;i++)
5093     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5094   ret->copyStringInfoFrom(*a1);
5095   return ret;
5096 }
5097
5098 /*!
5099  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5100  * valid cases.
5101  * 1.  The arrays have same number of tuples and components. Then each value of
5102  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5103  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5104  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5105  *   component. Then
5106  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5107  * 3.  The arrays have same number of components and one array, say _a2_, has one
5108  *   tuple. Then
5109  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5110  *
5111  * Info on components is copied either from the first array (in the first case) or from
5112  * the array with maximal number of elements (getNbOfElems()).
5113  *  \param [in] a1 - an array to sum up.
5114  *  \param [in] a2 - another array to sum up.
5115  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5116  *          The caller is to delete this result array using decrRef() as it is no more
5117  *          needed.
5118  *  \throw If either \a a1 or \a a2 is NULL.
5119  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5120  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5121  *         none of them has number of tuples or components equal to 1.
5122  */
5123 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5124 {
5125   if(!a1 || !a2)
5126     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5127   int nbOfTuple=a1->getNumberOfTuples();
5128   int nbOfTuple2=a2->getNumberOfTuples();
5129   int nbOfComp=a1->getNumberOfComponents();
5130   int nbOfComp2=a2->getNumberOfComponents();
5131   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5132   if(nbOfTuple==nbOfTuple2)
5133     {
5134       if(nbOfComp==nbOfComp2)
5135         {
5136           ret=DataArrayDouble::New();
5137           ret->alloc(nbOfTuple,nbOfComp);
5138           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5139           ret->copyStringInfoFrom(*a1);
5140         }
5141       else
5142         {
5143           int nbOfCompMin,nbOfCompMax;
5144           const DataArrayDouble *aMin, *aMax;
5145           if(nbOfComp>nbOfComp2)
5146             {
5147               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5148               aMin=a2; aMax=a1;
5149             }
5150           else
5151             {
5152               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5153               aMin=a1; aMax=a2;
5154             }
5155           if(nbOfCompMin==1)
5156             {
5157               ret=DataArrayDouble::New();
5158               ret->alloc(nbOfTuple,nbOfCompMax);
5159               const double *aMinPtr=aMin->getConstPointer();
5160               const double *aMaxPtr=aMax->getConstPointer();
5161               double *res=ret->getPointer();
5162               for(int i=0;i<nbOfTuple;i++)
5163                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5164               ret->copyStringInfoFrom(*aMax);
5165             }
5166           else
5167             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5168         }
5169     }
5170   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5171     {
5172       if(nbOfComp==nbOfComp2)
5173         {
5174           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5175           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5176           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5177           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5178           ret=DataArrayDouble::New();
5179           ret->alloc(nbOfTupleMax,nbOfComp);
5180           double *res=ret->getPointer();
5181           for(int i=0;i<nbOfTupleMax;i++)
5182             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5183           ret->copyStringInfoFrom(*aMax);
5184         }
5185       else
5186         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5187     }
5188   else
5189     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5190   return ret.retn();
5191 }
5192
5193 /*!
5194  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5195  * valid cases.
5196  * 1.  The arrays have same number of tuples and components. Then each value of
5197  *   \a other array is added to the corresponding value of \a this array, i.e.:
5198  *   _a_ [ i, j ] += _other_ [ i, j ].
5199  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5200  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5201  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5202  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5203  *
5204  *  \param [in] other - an array to add to \a this one.
5205  *  \throw If \a other is NULL.
5206  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5207  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5208  *         \a other has number of both tuples and components not equal to 1.
5209  */
5210 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5211 {
5212   if(!other)
5213     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5214   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5215   checkAllocated();
5216   other->checkAllocated();
5217   int nbOfTuple=getNumberOfTuples();
5218   int nbOfTuple2=other->getNumberOfTuples();
5219   int nbOfComp=getNumberOfComponents();
5220   int nbOfComp2=other->getNumberOfComponents();
5221   if(nbOfTuple==nbOfTuple2)
5222     {
5223       if(nbOfComp==nbOfComp2)
5224         {
5225           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5226         }
5227       else if(nbOfComp2==1)
5228         {
5229           double *ptr=getPointer();
5230           const double *ptrc=other->getConstPointer();
5231           for(int i=0;i<nbOfTuple;i++)
5232             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5233         }
5234       else
5235         throw INTERP_KERNEL::Exception(msg);
5236     }
5237   else if(nbOfTuple2==1)
5238     {
5239       if(nbOfComp2==nbOfComp)
5240         {
5241           double *ptr=getPointer();
5242           const double *ptrc=other->getConstPointer();
5243           for(int i=0;i<nbOfTuple;i++)
5244             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5245         }
5246       else
5247         throw INTERP_KERNEL::Exception(msg);
5248     }
5249   else
5250     throw INTERP_KERNEL::Exception(msg);
5251   declareAsNew();
5252 }
5253
5254 /*!
5255  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5256  * valid cases.
5257  * 1.  The arrays have same number of tuples and components. Then each value of
5258  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5259  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5260  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5261  *   component. Then
5262  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5263  * 3.  The arrays have same number of components and one array, say _a2_, has one
5264  *   tuple. Then
5265  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5266  *
5267  * Info on components is copied either from the first array (in the first case) or from
5268  * the array with maximal number of elements (getNbOfElems()).
5269  *  \param [in] a1 - an array to subtract from.
5270  *  \param [in] a2 - an array to subtract.
5271  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5272  *          The caller is to delete this result array using decrRef() as it is no more
5273  *          needed.
5274  *  \throw If either \a a1 or \a a2 is NULL.
5275  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5276  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5277  *         none of them has number of tuples or components equal to 1.
5278  */
5279 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5280 {
5281   if(!a1 || !a2)
5282     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5283   int nbOfTuple1=a1->getNumberOfTuples();
5284   int nbOfTuple2=a2->getNumberOfTuples();
5285   int nbOfComp1=a1->getNumberOfComponents();
5286   int nbOfComp2=a2->getNumberOfComponents();
5287   if(nbOfTuple2==nbOfTuple1)
5288     {
5289       if(nbOfComp1==nbOfComp2)
5290         {
5291           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5292           ret->alloc(nbOfTuple2,nbOfComp1);
5293           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5294           ret->copyStringInfoFrom(*a1);
5295           return ret.retn();
5296         }
5297       else if(nbOfComp2==1)
5298         {
5299           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5300           ret->alloc(nbOfTuple1,nbOfComp1);
5301           const double *a2Ptr=a2->getConstPointer();
5302           const double *a1Ptr=a1->getConstPointer();
5303           double *res=ret->getPointer();
5304           for(int i=0;i<nbOfTuple1;i++)
5305             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5306           ret->copyStringInfoFrom(*a1);
5307           return ret.retn();
5308         }
5309       else
5310         {
5311           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5312           return 0;
5313         }
5314     }
5315   else if(nbOfTuple2==1)
5316     {
5317       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5318       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5319       ret->alloc(nbOfTuple1,nbOfComp1);
5320       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5321       double *pt=ret->getPointer();
5322       for(int i=0;i<nbOfTuple1;i++)
5323         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5324       ret->copyStringInfoFrom(*a1);
5325       return ret.retn();
5326     }
5327   else
5328     {
5329       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5330       return 0;
5331     }
5332 }
5333
5334 /*!
5335  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5336  * valid cases.
5337  * 1.  The arrays have same number of tuples and components. Then each value of
5338  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5339  *   _a_ [ i, j ] -= _other_ [ i, j ].
5340  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5341  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5342  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5343  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5344  *
5345  *  \param [in] other - an array to subtract from \a this one.
5346  *  \throw If \a other is NULL.
5347  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5348  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5349  *         \a other has number of both tuples and components not equal to 1.
5350  */
5351 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5352 {
5353   if(!other)
5354     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5355   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5356   checkAllocated();
5357   other->checkAllocated();
5358   int nbOfTuple=getNumberOfTuples();
5359   int nbOfTuple2=other->getNumberOfTuples();
5360   int nbOfComp=getNumberOfComponents();
5361   int nbOfComp2=other->getNumberOfComponents();
5362   if(nbOfTuple==nbOfTuple2)
5363     {
5364       if(nbOfComp==nbOfComp2)
5365         {
5366           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5367         }
5368       else if(nbOfComp2==1)
5369         {
5370           double *ptr=getPointer();
5371           const double *ptrc=other->getConstPointer();
5372           for(int i=0;i<nbOfTuple;i++)
5373             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5374         }
5375       else
5376         throw INTERP_KERNEL::Exception(msg);
5377     }
5378   else if(nbOfTuple2==1)
5379     {
5380       if(nbOfComp2==nbOfComp)
5381         {
5382           double *ptr=getPointer();
5383           const double *ptrc=other->getConstPointer();
5384           for(int i=0;i<nbOfTuple;i++)
5385             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5386         }
5387       else
5388         throw INTERP_KERNEL::Exception(msg);
5389     }
5390   else
5391     throw INTERP_KERNEL::Exception(msg);
5392   declareAsNew();
5393 }
5394
5395 /*!
5396  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5397  * valid cases.
5398  * 1.  The arrays have same number of tuples and components. Then each value of
5399  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5400  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5401  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5402  *   component. Then
5403  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5404  * 3.  The arrays have same number of components and one array, say _a2_, has one
5405  *   tuple. Then
5406  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5407  *
5408  * Info on components is copied either from the first array (in the first case) or from
5409  * the array with maximal number of elements (getNbOfElems()).
5410  *  \param [in] a1 - a factor array.
5411  *  \param [in] a2 - another factor array.
5412  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5413  *          The caller is to delete this result array using decrRef() as it is no more
5414  *          needed.
5415  *  \throw If either \a a1 or \a a2 is NULL.
5416  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5417  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5418  *         none of them has number of tuples or components equal to 1.
5419  */
5420 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5421 {
5422   if(!a1 || !a2)
5423     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5424   int nbOfTuple=a1->getNumberOfTuples();
5425   int nbOfTuple2=a2->getNumberOfTuples();
5426   int nbOfComp=a1->getNumberOfComponents();
5427   int nbOfComp2=a2->getNumberOfComponents();
5428   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5429   if(nbOfTuple==nbOfTuple2)
5430     {
5431       if(nbOfComp==nbOfComp2)
5432         {
5433           ret=DataArrayDouble::New();
5434           ret->alloc(nbOfTuple,nbOfComp);
5435           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5436           ret->copyStringInfoFrom(*a1);
5437         }
5438       else
5439         {
5440           int nbOfCompMin,nbOfCompMax;
5441           const DataArrayDouble *aMin, *aMax;
5442           if(nbOfComp>nbOfComp2)
5443             {
5444               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5445               aMin=a2; aMax=a1;
5446             }
5447           else
5448             {
5449               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5450               aMin=a1; aMax=a2;
5451             }
5452           if(nbOfCompMin==1)
5453             {
5454               ret=DataArrayDouble::New();
5455               ret->alloc(nbOfTuple,nbOfCompMax);
5456               const double *aMinPtr=aMin->getConstPointer();
5457               const double *aMaxPtr=aMax->getConstPointer();
5458               double *res=ret->getPointer();
5459               for(int i=0;i<nbOfTuple;i++)
5460                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5461               ret->copyStringInfoFrom(*aMax);
5462             }
5463           else
5464             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5465         }
5466     }
5467   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5468     {
5469       if(nbOfComp==nbOfComp2)
5470         {
5471           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5472           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5473           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5474           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5475           ret=DataArrayDouble::New();
5476           ret->alloc(nbOfTupleMax,nbOfComp);
5477           double *res=ret->getPointer();
5478           for(int i=0;i<nbOfTupleMax;i++)
5479             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5480           ret->copyStringInfoFrom(*aMax);
5481         }
5482       else
5483         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5484     }
5485   else
5486     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5487   return ret.retn();
5488 }
5489
5490 /*!
5491  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5492  * valid cases.
5493  * 1.  The arrays have same number of tuples and components. Then each value of
5494  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5495  *   _this_ [ i, j ] *= _other_ [ i, j ].
5496  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5497  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5498  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5499  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5500  *
5501  *  \param [in] other - an array to multiply to \a this one.
5502  *  \throw If \a other is NULL.
5503  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5504  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5505  *         \a other has number of both tuples and components not equal to 1.
5506  */
5507 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5508 {
5509   if(!other)
5510     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5511   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5512   checkAllocated();
5513   other->checkAllocated();
5514   int nbOfTuple=getNumberOfTuples();
5515   int nbOfTuple2=other->getNumberOfTuples();
5516   int nbOfComp=getNumberOfComponents();
5517   int nbOfComp2=other->getNumberOfComponents();
5518   if(nbOfTuple==nbOfTuple2)
5519     {
5520       if(nbOfComp==nbOfComp2)
5521         {
5522           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5523         }
5524       else if(nbOfComp2==1)
5525         {
5526           double *ptr=getPointer();
5527           const double *ptrc=other->getConstPointer();
5528           for(int i=0;i<nbOfTuple;i++)
5529             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5530         }
5531       else
5532         throw INTERP_KERNEL::Exception(msg);
5533     }
5534   else if(nbOfTuple2==1)
5535     {
5536       if(nbOfComp2==nbOfComp)
5537         {
5538           double *ptr=getPointer();
5539           const double *ptrc=other->getConstPointer();
5540           for(int i=0;i<nbOfTuple;i++)
5541             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5542         }
5543       else
5544         throw INTERP_KERNEL::Exception(msg);
5545     }
5546   else
5547     throw INTERP_KERNEL::Exception(msg);
5548   declareAsNew();
5549 }
5550
5551 /*!
5552  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5553  * valid cases.
5554  * 1.  The arrays have same number of tuples and components. Then each value of
5555  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5556  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5557  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5558  *   component. Then
5559  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5560  * 3.  The arrays have same number of components and one array, say _a2_, has one
5561  *   tuple. Then
5562  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5563  *
5564  * Info on components is copied either from the first array (in the first case) or from
5565  * the array with maximal number of elements (getNbOfElems()).
5566  *  \warning No check of division by zero is performed!
5567  *  \param [in] a1 - a numerator array.
5568  *  \param [in] a2 - a denominator array.
5569  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5570  *          The caller is to delete this result array using decrRef() as it is no more
5571  *          needed.
5572  *  \throw If either \a a1 or \a a2 is NULL.
5573  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5574  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5575  *         none of them has number of tuples or components equal to 1.
5576  */
5577 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5578 {
5579   if(!a1 || !a2)
5580     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5581   int nbOfTuple1=a1->getNumberOfTuples();
5582   int nbOfTuple2=a2->getNumberOfTuples();
5583   int nbOfComp1=a1->getNumberOfComponents();
5584   int nbOfComp2=a2->getNumberOfComponents();
5585   if(nbOfTuple2==nbOfTuple1)
5586     {
5587       if(nbOfComp1==nbOfComp2)
5588         {
5589           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5590           ret->alloc(nbOfTuple2,nbOfComp1);
5591           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5592           ret->copyStringInfoFrom(*a1);
5593           return ret.retn();
5594         }
5595       else if(nbOfComp2==1)
5596         {
5597           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5598           ret->alloc(nbOfTuple1,nbOfComp1);
5599           const double *a2Ptr=a2->getConstPointer();
5600           const double *a1Ptr=a1->getConstPointer();
5601           double *res=ret->getPointer();
5602           for(int i=0;i<nbOfTuple1;i++)
5603             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5604           ret->copyStringInfoFrom(*a1);
5605           return ret.retn();
5606         }
5607       else
5608         {
5609           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5610           return 0;
5611         }
5612     }
5613   else if(nbOfTuple2==1)
5614     {
5615       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5616       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5617       ret->alloc(nbOfTuple1,nbOfComp1);
5618       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5619       double *pt=ret->getPointer();
5620       for(int i=0;i<nbOfTuple1;i++)
5621         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5622       ret->copyStringInfoFrom(*a1);
5623       return ret.retn();
5624     }
5625   else
5626     {
5627       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5628       return 0;
5629     }
5630 }
5631
5632 /*!
5633  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5634  * valid cases.
5635  * 1.  The arrays have same number of tuples and components. Then each value of
5636  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5637  *   _a_ [ i, j ] /= _other_ [ i, j ].
5638  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5639  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5640  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5641  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5642  *
5643  *  \warning No check of division by zero is performed!
5644  *  \param [in] other - an array to divide \a this one by.
5645  *  \throw If \a other is NULL.
5646  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5647  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5648  *         \a other has number of both tuples and components not equal to 1.
5649  */
5650 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5651 {
5652   if(!other)
5653     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5654   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5655   checkAllocated();
5656   other->checkAllocated();
5657   int nbOfTuple=getNumberOfTuples();
5658   int nbOfTuple2=other->getNumberOfTuples();
5659   int nbOfComp=getNumberOfComponents();
5660   int nbOfComp2=other->getNumberOfComponents();
5661   if(nbOfTuple==nbOfTuple2)
5662     {
5663       if(nbOfComp==nbOfComp2)
5664         {
5665           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5666         }
5667       else if(nbOfComp2==1)
5668         {
5669           double *ptr=getPointer();
5670           const double *ptrc=other->getConstPointer();
5671           for(int i=0;i<nbOfTuple;i++)
5672             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5673         }
5674       else
5675         throw INTERP_KERNEL::Exception(msg);
5676     }
5677   else if(nbOfTuple2==1)
5678     {
5679       if(nbOfComp2==nbOfComp)
5680         {
5681           double *ptr=getPointer();
5682           const double *ptrc=other->getConstPointer();
5683           for(int i=0;i<nbOfTuple;i++)
5684             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5685         }
5686       else
5687         throw INTERP_KERNEL::Exception(msg);
5688     }
5689   else
5690     throw INTERP_KERNEL::Exception(msg);
5691   declareAsNew();
5692 }
5693
5694 /*!
5695  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5696  * valid cases.
5697  *
5698  *  \param [in] a1 - an array to pow up.
5699  *  \param [in] a2 - another array to sum up.
5700  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5701  *          The caller is to delete this result array using decrRef() as it is no more
5702  *          needed.
5703  *  \throw If either \a a1 or \a a2 is NULL.
5704  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5705  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5706  *  \throw If there is a negative value in \a a1.
5707  */
5708 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5709 {
5710   if(!a1 || !a2)
5711     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5712   int nbOfTuple=a1->getNumberOfTuples();
5713   int nbOfTuple2=a2->getNumberOfTuples();
5714   int nbOfComp=a1->getNumberOfComponents();
5715   int nbOfComp2=a2->getNumberOfComponents();
5716   if(nbOfTuple!=nbOfTuple2)
5717     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5718   if(nbOfComp!=1 || nbOfComp2!=1)
5719     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5720   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5721   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5722   double *ptr=ret->getPointer();
5723   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5724     {
5725       if(*ptr1>=0)
5726         {
5727           *ptr=pow(*ptr1,*ptr2);
5728         }
5729       else
5730         {
5731           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5732           throw INTERP_KERNEL::Exception(oss.str().c_str());
5733         }
5734     }
5735   return ret.retn();
5736 }
5737
5738 /*!
5739  * Apply pow on values of another DataArrayDouble to values of \a this one.
5740  *
5741  *  \param [in] other - an array to pow to \a this one.
5742  *  \throw If \a other is NULL.
5743  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5744  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5745  *  \throw If there is a negative value in \a this.
5746  */
5747 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5748 {
5749   if(!other)
5750     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5751   int nbOfTuple=getNumberOfTuples();
5752   int nbOfTuple2=other->getNumberOfTuples();
5753   int nbOfComp=getNumberOfComponents();
5754   int nbOfComp2=other->getNumberOfComponents();
5755   if(nbOfTuple!=nbOfTuple2)
5756     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5757   if(nbOfComp!=1 || nbOfComp2!=1)
5758     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5759   double *ptr=getPointer();
5760   const double *ptrc=other->begin();
5761   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5762     {
5763       if(*ptr>=0)
5764         *ptr=pow(*ptr,*ptrc);
5765       else
5766         {
5767           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5768           throw INTERP_KERNEL::Exception(oss.str().c_str());
5769         }
5770     }
5771   declareAsNew();
5772 }
5773
5774 /*!
5775  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5776  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5777  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5778  *
5779  * \throw if \a this is not allocated.
5780  * \throw if \a this has not exactly one component.
5781  */
5782 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5783 {
5784   checkAllocated();
5785   if(getNumberOfComponents()!=1)
5786     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5787   int nbt(getNumberOfTuples());
5788   std::vector<bool> ret(nbt);
5789   const double *pt(begin());
5790   for(int i=0;i<nbt;i++)
5791     {
5792       if(fabs(pt[i])<eps)
5793         ret[i]=false;
5794       else if(fabs(pt[i]-1.)<eps)
5795         ret[i]=true;
5796       else
5797         {
5798           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5799           throw INTERP_KERNEL::Exception(oss.str().c_str());
5800         }
5801     }
5802   return ret;
5803 }
5804
5805 /*!
5806  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5807  * Server side.
5808  */
5809 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5810 {
5811   tinyInfo.resize(2);
5812   if(isAllocated())
5813     {
5814       tinyInfo[0]=getNumberOfTuples();
5815       tinyInfo[1]=getNumberOfComponents();
5816     }
5817   else
5818     {
5819       tinyInfo[0]=-1;
5820       tinyInfo[1]=-1;
5821     }
5822 }
5823
5824 /*!
5825  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5826  * Server side.
5827  */
5828 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5829 {
5830   if(isAllocated())
5831     {
5832       int nbOfCompo=getNumberOfComponents();
5833       tinyInfo.resize(nbOfCompo+1);
5834       tinyInfo[0]=getName();
5835       for(int i=0;i<nbOfCompo;i++)
5836         tinyInfo[i+1]=getInfoOnComponent(i);
5837     }
5838   else
5839     {
5840       tinyInfo.resize(1);
5841       tinyInfo[0]=getName();
5842     }
5843 }
5844
5845 /*!
5846  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5847  * This method returns if a feeding is needed.
5848  */
5849 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5850 {
5851   int nbOfTuple=tinyInfoI[0];
5852   int nbOfComp=tinyInfoI[1];
5853   if(nbOfTuple!=-1 || nbOfComp!=-1)
5854     {
5855       alloc(nbOfTuple,nbOfComp);
5856       return true;
5857     }
5858   return false;
5859 }
5860
5861 /*!
5862  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5863  */
5864 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5865 {
5866   setName(tinyInfoS[0]);
5867   if(isAllocated())
5868     {
5869       int nbOfCompo=getNumberOfComponents();
5870       for(int i=0;i<nbOfCompo;i++)
5871         setInfoOnComponent(i,tinyInfoS[i+1]);
5872     }
5873 }
5874
5875 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5876 {
5877   if(_da)
5878     {
5879       _da->incrRef();
5880       if(_da->isAllocated())
5881         {
5882           _nb_comp=da->getNumberOfComponents();
5883           _nb_tuple=da->getNumberOfTuples();
5884           _pt=da->getPointer();
5885         }
5886     }
5887 }
5888
5889 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5890 {
5891   if(_da)
5892     _da->decrRef();
5893 }
5894
5895 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5896 {
5897   if(_tuple_id<_nb_tuple)
5898     {
5899       _tuple_id++;
5900       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5901       _pt+=_nb_comp;
5902       return ret;
5903     }
5904   else
5905     return 0;
5906 }
5907
5908 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5909 {
5910 }
5911
5912
5913 std::string DataArrayDoubleTuple::repr() const
5914 {
5915   std::ostringstream oss; oss.precision(17); oss << "(";
5916   for(int i=0;i<_nb_of_compo-1;i++)
5917     oss << _pt[i] << ", ";
5918   oss << _pt[_nb_of_compo-1] << ")";
5919   return oss.str();
5920 }
5921
5922 double DataArrayDoubleTuple::doubleValue() const
5923 {
5924   if(_nb_of_compo==1)
5925     return *_pt;
5926   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5927 }
5928
5929 /*!
5930  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5931  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5932  * 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
5933  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5934  */
5935 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5936 {
5937   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5938     {
5939       DataArrayDouble *ret=DataArrayDouble::New();
5940       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5941       return ret;
5942     }
5943   else
5944     {
5945       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5946       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5947       throw INTERP_KERNEL::Exception(oss.str().c_str());
5948     }
5949 }
5950
5951 /*!
5952  * Returns a new instance of DataArrayInt. The caller is to delete this array
5953  * using decrRef() as it is no more needed. 
5954  */
5955 DataArrayInt *DataArrayInt::New()
5956 {
5957   return new DataArrayInt;
5958 }
5959
5960 /*!
5961  * Checks if raw data is allocated. Read more on the raw data
5962  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5963  *  \return bool - \a true if the raw data is allocated, \a false else.
5964  */
5965 bool DataArrayInt::isAllocated() const
5966 {
5967   return getConstPointer()!=0;
5968 }
5969
5970 /*!
5971  * Checks if raw data is allocated and throws an exception if it is not the case.
5972  *  \throw If the raw data is not allocated.
5973  */
5974 void DataArrayInt::checkAllocated() const
5975 {
5976   if(!isAllocated())
5977     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5978 }
5979
5980 /*!
5981  * This method desallocated \a this without modification of informations relative to the components.
5982  * After call of this method, DataArrayInt::isAllocated will return false.
5983  * If \a this is already not allocated, \a this is let unchanged.
5984  */
5985 void DataArrayInt::desallocate()
5986 {
5987   _mem.destroy();
5988 }
5989
5990 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5991 {
5992   std::size_t sz(_mem.getNbOfElemAllocated());
5993   sz*=sizeof(int);
5994   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5995 }
5996
5997 /*!
5998  * Returns the only one value in \a this, if and only if number of elements
5999  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
6000  *  \return double - the sole value stored in \a this array.
6001  *  \throw If at least one of conditions stated above is not fulfilled.
6002  */
6003 int DataArrayInt::intValue() const
6004 {
6005   if(isAllocated())
6006     {
6007       if(getNbOfElems()==1)
6008         {
6009           return *getConstPointer();
6010         }
6011       else
6012         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
6013     }
6014   else
6015     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
6016 }
6017
6018 /*!
6019  * Returns an integer value characterizing \a this array, which is useful for a quick
6020  * comparison of many instances of DataArrayInt.
6021  *  \return int - the hash value.
6022  *  \throw If \a this is not allocated.
6023  */
6024 int DataArrayInt::getHashCode() const
6025 {
6026   checkAllocated();
6027   std::size_t nbOfElems=getNbOfElems();
6028   int ret=nbOfElems*65536;
6029   int delta=3;
6030   if(nbOfElems>48)
6031     delta=nbOfElems/8;
6032   int ret0=0;
6033   const int *pt=begin();
6034   for(std::size_t i=0;i<nbOfElems;i+=delta)
6035     ret0+=pt[i] & 0x1FFF;
6036   return ret+ret0;
6037 }
6038
6039 /*!
6040  * Checks the number of tuples.
6041  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
6042  *  \throw If \a this is not allocated.
6043  */
6044 bool DataArrayInt::empty() const
6045 {
6046   checkAllocated();
6047   return getNumberOfTuples()==0;
6048 }
6049
6050 /*!
6051  * Returns a full copy of \a this. For more info on copying data arrays see
6052  * \ref MEDCouplingArrayBasicsCopyDeep.
6053  *  \return DataArrayInt * - a new instance of DataArrayInt.
6054  */
6055 DataArrayInt *DataArrayInt::deepCpy() const
6056 {
6057   return new DataArrayInt(*this);
6058 }
6059
6060 /*!
6061  * Returns either a \a deep or \a shallow copy of this array. For more info see
6062  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
6063  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
6064  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
6065  *          == \a true) or \a this instance (if \a dCpy == \a false).
6066  */
6067 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
6068 {
6069   if(dCpy)
6070     return deepCpy();
6071   else
6072     {
6073       incrRef();
6074       return const_cast<DataArrayInt *>(this);
6075     }
6076 }
6077
6078 /*!
6079  * Copies all the data from another DataArrayInt. For more info see
6080  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
6081  *  \param [in] other - another instance of DataArrayInt to copy data from.
6082  *  \throw If the \a other is not allocated.
6083  */
6084 void DataArrayInt::cpyFrom(const DataArrayInt& other)
6085 {
6086   other.checkAllocated();
6087   int nbOfTuples=other.getNumberOfTuples();
6088   int nbOfComp=other.getNumberOfComponents();
6089   allocIfNecessary(nbOfTuples,nbOfComp);
6090   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6091   int *pt=getPointer();
6092   const int *ptI=other.getConstPointer();
6093   for(std::size_t i=0;i<nbOfElems;i++)
6094     pt[i]=ptI[i];
6095   copyStringInfoFrom(other);
6096 }
6097
6098 /*!
6099  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6100  * 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.
6101  * If \a this has not already been allocated, number of components is set to one.
6102  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6103  * 
6104  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6105  */
6106 void DataArrayInt::reserve(std::size_t nbOfElems)
6107 {
6108   int nbCompo=getNumberOfComponents();
6109   if(nbCompo==1)
6110     {
6111       _mem.reserve(nbOfElems);
6112     }
6113   else if(nbCompo==0)
6114     {
6115       _mem.reserve(nbOfElems);
6116       _info_on_compo.resize(1);
6117     }
6118   else
6119     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6120 }
6121
6122 /*!
6123  * 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
6124  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6125  *
6126  * \param [in] val the value to be added in \a this
6127  * \throw If \a this has already been allocated with number of components different from one.
6128  * \sa DataArrayInt::pushBackValsSilent
6129  */
6130 void DataArrayInt::pushBackSilent(int val)
6131 {
6132   int nbCompo=getNumberOfComponents();
6133   if(nbCompo==1)
6134     _mem.pushBack(val);
6135   else if(nbCompo==0)
6136     {
6137       _info_on_compo.resize(1);
6138       _mem.pushBack(val);
6139     }
6140   else
6141     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6142 }
6143
6144 /*!
6145  * 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
6146  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6147  *
6148  *  \param [in] valsBg - an array of values to push at the end of \c this.
6149  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6150  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6151  * \throw If \a this has already been allocated with number of components different from one.
6152  * \sa DataArrayInt::pushBackSilent
6153  */
6154 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6155 {
6156   int nbCompo=getNumberOfComponents();
6157   if(nbCompo==1)
6158     _mem.insertAtTheEnd(valsBg,valsEnd);
6159   else if(nbCompo==0)
6160     {
6161       _info_on_compo.resize(1);
6162       _mem.insertAtTheEnd(valsBg,valsEnd);
6163     }
6164   else
6165     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6166 }
6167
6168 /*!
6169  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6170  * \throw If \a this is already empty.
6171  * \throw If \a this has number of components different from one.
6172  */
6173 int DataArrayInt::popBackSilent()
6174 {
6175   if(getNumberOfComponents()==1)
6176     return _mem.popBack();
6177   else
6178     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6179 }
6180
6181 /*!
6182  * 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.
6183  *
6184  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6185  */
6186 void DataArrayInt::pack() const
6187 {
6188   _mem.pack();
6189 }
6190
6191 /*!
6192  * Allocates the raw data in memory. If exactly as same memory as needed already
6193  * allocated, it is not re-allocated.
6194  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6195  *  \param [in] nbOfCompo - number of components of data to allocate.
6196  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6197  */
6198 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6199 {
6200   if(isAllocated())
6201     {
6202       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6203         alloc(nbOfTuple,nbOfCompo);
6204     }
6205   else
6206     alloc(nbOfTuple,nbOfCompo);
6207 }
6208
6209 /*!
6210  * Allocates the raw data in memory. If the memory was already allocated, then it is
6211  * freed and re-allocated. See an example of this method use
6212  * \ref MEDCouplingArraySteps1WC "here".
6213  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6214  *  \param [in] nbOfCompo - number of components of data to allocate.
6215  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6216  */
6217 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6218 {
6219   if(nbOfTuple<0 || nbOfCompo<0)
6220     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6221   _info_on_compo.resize(nbOfCompo);
6222   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6223   declareAsNew();
6224 }
6225
6226 /*!
6227  * Assign zero to all values in \a this array. To know more on filling arrays see
6228  * \ref MEDCouplingArrayFill.
6229  * \throw If \a this is not allocated.
6230  */
6231 void DataArrayInt::fillWithZero()
6232 {
6233   checkAllocated();
6234   _mem.fillWithValue(0);
6235   declareAsNew();
6236 }
6237
6238 /*!
6239  * Assign \a val to all values in \a this array. To know more on filling arrays see
6240  * \ref MEDCouplingArrayFill.
6241  *  \param [in] val - the value to fill with.
6242  *  \throw If \a this is not allocated.
6243  */
6244 void DataArrayInt::fillWithValue(int val)
6245 {
6246   checkAllocated();
6247   _mem.fillWithValue(val);
6248   declareAsNew();
6249 }
6250
6251 /*!
6252  * Set all values in \a this array so that the i-th element equals to \a init + i
6253  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6254  *  \param [in] init - value to assign to the first element of array.
6255  *  \throw If \a this->getNumberOfComponents() != 1
6256  *  \throw If \a this is not allocated.
6257  */
6258 void DataArrayInt::iota(int init)
6259 {
6260   checkAllocated();
6261   if(getNumberOfComponents()!=1)
6262     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6263   int *ptr=getPointer();
6264   int ntuples=getNumberOfTuples();
6265   for(int i=0;i<ntuples;i++)
6266     ptr[i]=init+i;
6267   declareAsNew();
6268 }
6269
6270 /*!
6271  * Returns a textual and human readable representation of \a this instance of
6272  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6273  * \return std::string - text describing \a this DataArrayInt.
6274  * 
6275  * \sa reprNotTooLong, reprZip
6276  */
6277 std::string DataArrayInt::repr() const
6278 {
6279   std::ostringstream ret;
6280   reprStream(ret);
6281   return ret.str();
6282 }
6283
6284 std::string DataArrayInt::reprZip() const
6285 {
6286   std::ostringstream ret;
6287   reprZipStream(ret);
6288   return ret.str();
6289 }
6290
6291 /*!
6292  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
6293  * printed out to avoid to consume too much space in interpretor.
6294  * \sa repr
6295  */
6296 std::string DataArrayInt::reprNotTooLong() const
6297 {
6298   std::ostringstream ret;
6299   reprNotTooLongStream(ret);
6300   return ret.str();
6301 }
6302
6303 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6304 {
6305   static const char SPACE[4]={' ',' ',' ',' '};
6306   checkAllocated();
6307   std::string idt(indent,' ');
6308   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6309   if(byteArr)
6310     {
6311       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6312       if(std::string(type)=="Int32")
6313         {
6314           const char *data(reinterpret_cast<const char *>(begin()));
6315           std::size_t sz(getNbOfElems()*sizeof(int));
6316           byteArr->insertAtTheEnd(data,data+sz);
6317           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6318         }
6319       else if(std::string(type)=="Int8")
6320         {
6321           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6322           std::copy(begin(),end(),(char *)tmp);
6323           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6324           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6325         }
6326       else if(std::string(type)=="UInt8")
6327         {
6328           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6329           std::copy(begin(),end(),(unsigned char *)tmp);
6330           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6331           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6332         }
6333       else
6334         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6335     }
6336   else
6337     {
6338       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6339       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6340     }
6341   ofs << std::endl << idt << "</DataArray>\n";
6342 }
6343
6344 void DataArrayInt::reprStream(std::ostream& stream) const
6345 {
6346   stream << "Name of int array : \"" << _name << "\"\n";
6347   reprWithoutNameStream(stream);
6348 }
6349
6350 void DataArrayInt::reprZipStream(std::ostream& stream) const
6351 {
6352   stream << "Name of int array : \"" << _name << "\"\n";
6353   reprZipWithoutNameStream(stream);
6354 }
6355
6356 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
6357 {
6358   stream << "Name of int array : \"" << _name << "\"\n";
6359   reprNotTooLongWithoutNameStream(stream);
6360 }
6361
6362 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6363 {
6364   DataArray::reprWithoutNameStream(stream);
6365   _mem.repr(getNumberOfComponents(),stream);
6366 }
6367
6368 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6369 {
6370   DataArray::reprWithoutNameStream(stream);
6371   _mem.reprZip(getNumberOfComponents(),stream);
6372 }
6373
6374 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
6375 {
6376   DataArray::reprWithoutNameStream(stream);
6377   stream.precision(17);
6378   _mem.reprNotTooLong(getNumberOfComponents(),stream);
6379 }
6380
6381 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6382 {
6383   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6384   const int *data=getConstPointer();
6385   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6386   if(nbTuples*nbComp>=1)
6387     {
6388       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6389       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6390       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6391       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6392     }
6393   else
6394     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6395   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6396 }
6397
6398 /*!
6399  * Method that gives a quick overvien of \a this for python.
6400  */
6401 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6402 {
6403   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6404   stream << "DataArrayInt C++ instance at " << this << ". ";
6405   if(isAllocated())
6406     {
6407       int nbOfCompo=(int)_info_on_compo.size();
6408       if(nbOfCompo>=1)
6409         {
6410           int nbOfTuples=getNumberOfTuples();
6411           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6412           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6413         }
6414       else
6415         stream << "Number of components : 0.";
6416     }
6417   else
6418     stream << "*** No data allocated ****";
6419 }
6420
6421 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6422 {
6423   const int *data=begin();
6424   int nbOfTuples=getNumberOfTuples();
6425   int nbOfCompo=(int)_info_on_compo.size();
6426   std::ostringstream oss2; oss2 << "[";
6427   std::string oss2Str(oss2.str());
6428   bool isFinished=true;
6429   for(int i=0;i<nbOfTuples && isFinished;i++)
6430     {
6431       if(nbOfCompo>1)
6432         {
6433           oss2 << "(";
6434           for(int j=0;j<nbOfCompo;j++,data++)
6435             {
6436               oss2 << *data;
6437               if(j!=nbOfCompo-1) oss2 << ", ";
6438             }
6439           oss2 << ")";
6440         }
6441       else
6442         oss2 << *data++;
6443       if(i!=nbOfTuples-1) oss2 << ", ";
6444       std::string oss3Str(oss2.str());
6445       if(oss3Str.length()<maxNbOfByteInRepr)
6446         oss2Str=oss3Str;
6447       else
6448         isFinished=false;
6449     }
6450   stream << oss2Str;
6451   if(!isFinished)
6452     stream << "... ";
6453   stream << "]";
6454 }
6455
6456 /*!
6457  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6458  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6459  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6460  *         to \a this array.
6461  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6462  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6463  *  \throw If \a this->getNumberOfComponents() != 1
6464  *  \throw If any value of \a this can't be used as a valid index for 
6465  *         [\a indArrBg, \a indArrEnd).
6466  *
6467  *  \sa replaceOneValByInThis
6468  */
6469 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6470 {
6471   checkAllocated();
6472   if(getNumberOfComponents()!=1)
6473     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6474   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6475   for(int i=0;i<nbOfTuples;i++,pt++)
6476     {
6477       if(*pt>=0 && *pt<nbElemsIn)
6478         *pt=indArrBg[*pt];
6479       else
6480         {
6481           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6482           throw INTERP_KERNEL::Exception(oss.str().c_str());
6483         }
6484     }
6485   declareAsNew();
6486 }
6487
6488 /*!
6489  * Modifies in place \a this one-dimensional array like this : each id in \a this so that this[id] equal to \a valToBeReplaced will be replaced at the same place by \a replacedBy.
6490  *
6491  * \param [in] valToBeReplaced - the value in \a this to be replaced.
6492  * \param [in] replacedBy - the value taken by each tuple previously equal to \a valToBeReplaced.
6493  *
6494  * \sa DataArrayInt::transformWithIndArr
6495  */
6496 void DataArrayInt::replaceOneValByInThis(int valToBeReplaced, int replacedBy)
6497 {
6498   checkAllocated();
6499   if(getNumberOfComponents()!=1)
6500     throw INTERP_KERNEL::Exception("Call replaceOneValByInThis method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6501   if(valToBeReplaced==replacedBy)
6502     return ;
6503   int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6504   for(int i=0;i<nbOfTuples;i++,pt++)
6505     {
6506       if(*pt==valToBeReplaced)
6507         *pt=replacedBy;
6508     }
6509 }
6510
6511 /*!
6512  * Computes distribution of values of \a this one-dimensional array between given value
6513  * ranges (casts). This method is typically useful for entity number spliting by types,
6514  * for example. 
6515  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6516  *           check of this is be done. If not, the result is not warranted. 
6517  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6518  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6519  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6520  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6521  *         should be more than every value in \a this array.
6522  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6523  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6524  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6525  *         (same number of tuples and components), the caller is to delete 
6526  *         using decrRef() as it is no more needed.
6527  *         This array contains indices of ranges for every value of \a this array. I.e.
6528  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6529  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6530  *         this in which cast it holds.
6531  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6532  *         array, the caller is to delete using decrRef() as it is no more needed.
6533  *         This array contains ranks of values of \a this array within ranges
6534  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6535  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6536  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6537  *         for each tuple its rank inside its cast. The rank is computed as difference
6538  *         between the value and the lowest value of range.
6539  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6540  *         ranges (casts) to which at least one value of \a this array belongs.
6541  *         Or, in other words, this param contains the casts that \a this contains.
6542  *         The caller is to delete this array using decrRef() as it is no more needed.
6543  *
6544  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6545  *            the output of this method will be : 
6546  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6547  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6548  * - \a castsPresent  : [0,1]
6549  *
6550  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6551  * range #1 and its rank within this range is 2; etc.
6552  *
6553  *  \throw If \a this->getNumberOfComponents() != 1.
6554  *  \throw If \a arrEnd - arrBg < 2.
6555  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6556  */
6557 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6558                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6559 {
6560   checkAllocated();
6561   if(getNumberOfComponents()!=1)
6562     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6563   int nbOfTuples=getNumberOfTuples();
6564   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6565   if(nbOfCast<2)
6566     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6567   nbOfCast--;
6568   const int *work=getConstPointer();
6569   typedef std::reverse_iterator<const int *> rintstart;
6570   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6571   rintstart end2(arrBg);
6572   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6573   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6574   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6575   ret1->alloc(nbOfTuples,1);
6576   ret2->alloc(nbOfTuples,1);
6577   int *ret1Ptr=ret1->getPointer();
6578   int *ret2Ptr=ret2->getPointer();
6579   std::set<std::size_t> castsDetected;
6580   for(int i=0;i<nbOfTuples;i++)
6581     {
6582       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6583       std::size_t pos=std::distance(bg,res);
6584       std::size_t pos2=nbOfCast-pos;
6585       if(pos2<nbOfCast)
6586         {
6587           ret1Ptr[i]=(int)pos2;
6588           ret2Ptr[i]=work[i]-arrBg[pos2];
6589           castsDetected.insert(pos2);
6590         }
6591       else
6592         {
6593           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6594           throw INTERP_KERNEL::Exception(oss.str().c_str());
6595         }
6596     }
6597   ret3->alloc((int)castsDetected.size(),1);
6598   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6599   castArr=ret1.retn();
6600   rankInsideCast=ret2.retn();
6601   castsPresent=ret3.retn();
6602 }
6603
6604 /*!
6605  * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ).
6606  * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ).
6607  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6608  *
6609  * \param [out] strt - the start of the range (included) if true is returned.
6610  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6611  * \param [out] stteepp - the step of the range if true is returned.
6612  * \return the verdict of the check.
6613  *
6614  * \sa DataArray::GetNumberOfItemGivenBES
6615  */
6616 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6617 {
6618   checkAllocated();
6619   if(getNumberOfComponents()!=1)
6620     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6621   int nbTuples(getNumberOfTuples());
6622   if(nbTuples==0)
6623     { strt=0; sttoopp=0; stteepp=1; return true; }
6624   const int *pt(begin());
6625   strt=*pt; 
6626   if(nbTuples==1)
6627     { sttoopp=strt+1; stteepp=1; return true; }
6628   strt=*pt; sttoopp=pt[nbTuples-1];
6629   if(strt==sttoopp)
6630     return false;
6631   if(sttoopp>strt)
6632     {
6633       sttoopp++;
6634       int a(sttoopp-1-strt),tmp(strt);
6635       if(a%(nbTuples-1)!=0)
6636         return false;
6637       stteepp=a/(nbTuples-1);
6638       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6639         if(pt[i]!=tmp)
6640           return false;
6641       return true;
6642     }
6643   else
6644     {
6645       sttoopp--;
6646       int a(strt-sttoopp-1),tmp(strt);
6647       if(a%(nbTuples-1)!=0)
6648         return false;
6649       stteepp=-(a/(nbTuples-1));
6650       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6651         if(pt[i]!=tmp)
6652           return false;
6653       return true;
6654     }
6655 }
6656
6657 /*!
6658  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6659  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6660  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6661  * new value in place \a indArr[ \a v ] is i.
6662  *  \param [in] indArrBg - the array holding indices within the result array to assign
6663  *         indices of values of \a this array pointing to values of \a indArrBg.
6664  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6665  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6666  *  \return DataArrayInt * - the new instance of DataArrayInt.
6667  *          The caller is to delete this result array using decrRef() as it is no more
6668  *          needed.
6669  *  \throw If \a this->getNumberOfComponents() != 1.
6670  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6671  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6672  */
6673 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6674 {
6675   checkAllocated();
6676   if(getNumberOfComponents()!=1)
6677     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6678   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6679   int nbOfTuples=getNumberOfTuples();
6680   const int *pt=getConstPointer();
6681   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6682   ret->alloc(nbOfTuples,1);
6683   ret->fillWithValue(-1);
6684   int *tmp=ret->getPointer();
6685   for(int i=0;i<nbOfTuples;i++,pt++)
6686     {
6687       if(*pt>=0 && *pt<nbElemsIn)
6688         {
6689           int pos=indArrBg[*pt];
6690           if(pos>=0 && pos<nbOfTuples)
6691             tmp[pos]=i;
6692           else
6693             {
6694               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6695               throw INTERP_KERNEL::Exception(oss.str().c_str());
6696             }
6697         }
6698       else
6699         {
6700           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6701           throw INTERP_KERNEL::Exception(oss.str().c_str());
6702         }
6703     }
6704   return ret.retn();
6705 }
6706
6707 /*!
6708  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6709  * from values of \a this array, which is supposed to contain a renumbering map in 
6710  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6711  * To know how to use the renumbering maps see \ref numbering.
6712  *  \param [in] newNbOfElem - the number of tuples in the result array.
6713  *  \return DataArrayInt * - the new instance of DataArrayInt.
6714  *          The caller is to delete this result array using decrRef() as it is no more
6715  *          needed.
6716  * 
6717  *  \if ENABLE_EXAMPLES
6718  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6719  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6720  *  \endif
6721  */
6722 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6723 {
6724   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6725   ret->alloc(newNbOfElem,1);
6726   int nbOfOldNodes=getNumberOfTuples();
6727   const int *old2New=getConstPointer();
6728   int *pt=ret->getPointer();
6729   for(int i=0;i!=nbOfOldNodes;i++)
6730     {
6731       int newp(old2New[i]);
6732       if(newp!=-1)
6733         {
6734           if(newp>=0 && newp<newNbOfElem)
6735             pt[newp]=i;
6736           else
6737             {
6738               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6739               throw INTERP_KERNEL::Exception(oss.str().c_str());
6740             }
6741         }
6742     }
6743   return ret.retn();
6744 }
6745
6746 /*!
6747  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6748  * 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]
6749  */
6750 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6751 {
6752   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6753   ret->alloc(newNbOfElem,1);
6754   int nbOfOldNodes=getNumberOfTuples();
6755   const int *old2New=getConstPointer();
6756   int *pt=ret->getPointer();
6757   for(int i=nbOfOldNodes-1;i>=0;i--)
6758     {
6759       int newp(old2New[i]);
6760       if(newp!=-1)
6761         {
6762           if(newp>=0 && newp<newNbOfElem)
6763             pt[newp]=i;
6764           else
6765             {
6766               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6767               throw INTERP_KERNEL::Exception(oss.str().c_str());
6768             }
6769         }
6770     }
6771   return ret.retn();
6772 }
6773
6774 /*!
6775  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6776  * from values of \a this array, which is supposed to contain a renumbering map in 
6777  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6778  * To know how to use the renumbering maps see \ref numbering.
6779  *  \param [in] newNbOfElem - the number of tuples in the result array.
6780  *  \return DataArrayInt * - the new instance of DataArrayInt.
6781  *          The caller is to delete this result array using decrRef() as it is no more
6782  *          needed.
6783  * 
6784  *  \if ENABLE_EXAMPLES
6785  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6786  *
6787  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6788  *  \endif
6789  */
6790 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6791 {
6792   checkAllocated();
6793   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6794   ret->alloc(oldNbOfElem,1);
6795   const int *new2Old=getConstPointer();
6796   int *pt=ret->getPointer();
6797   std::fill(pt,pt+oldNbOfElem,-1);
6798   int nbOfNewElems=getNumberOfTuples();
6799   for(int i=0;i<nbOfNewElems;i++)
6800     {
6801       int v(new2Old[i]);
6802       if(v>=0 && v<oldNbOfElem)
6803         pt[v]=i;
6804       else
6805         {
6806           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6807           throw INTERP_KERNEL::Exception(oss.str().c_str());
6808         }
6809     }
6810   return ret.retn();
6811 }
6812
6813 /*!
6814  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6815  * mismatch is given.
6816  * 
6817  * \param [in] other the instance to be compared with \a this
6818  * \param [out] reason In case of inequality returns the reason.
6819  * \sa DataArrayInt::isEqual
6820  */
6821 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6822 {
6823   if(!areInfoEqualsIfNotWhy(other,reason))
6824     return false;
6825   return _mem.isEqual(other._mem,0,reason);
6826 }
6827
6828 /*!
6829  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6830  * \ref MEDCouplingArrayBasicsCompare.
6831  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6832  *  \return bool - \a true if the two arrays are equal, \a false else.
6833  */
6834 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6835 {
6836   std::string tmp;
6837   return isEqualIfNotWhy(other,tmp);
6838 }
6839
6840 /*!
6841  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6842  * \ref MEDCouplingArrayBasicsCompare.
6843  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6844  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6845  */
6846 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6847 {
6848   std::string tmp;
6849   return _mem.isEqual(other._mem,0,tmp);
6850 }
6851
6852 /*!
6853  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6854  * performed on sorted value sequences.
6855  * For more info see\ref MEDCouplingArrayBasicsCompare.
6856  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6857  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6858  */
6859 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6860 {
6861   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6862   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6863   a->sort();
6864   b->sort();
6865   return a->isEqualWithoutConsideringStr(*b);
6866 }
6867
6868 /*!
6869  * This method compares content of input vector \a v and \a this.
6870  * 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.
6871  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6872  *
6873  * \param [in] v - the vector of 'flags' to be compared with \a this.
6874  *
6875  * \throw If \a this is not sorted ascendingly.
6876  * \throw If \a this has not exactly one component.
6877  * \throw If \a this is not allocated.
6878  */
6879 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6880 {
6881   checkAllocated();
6882   if(getNumberOfComponents()!=1)
6883     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6884   const int *w(begin()),*end2(end());
6885   int refVal=-std::numeric_limits<int>::max();
6886   int i=0;
6887   std::vector<bool>::const_iterator it(v.begin());
6888   for(;it!=v.end();it++,i++)
6889     {
6890       if(*it)
6891         {
6892           if(w!=end2)
6893             {
6894               if(*w++==i)
6895                 {
6896                   if(i>refVal)
6897                     refVal=i;
6898                   else
6899                     {
6900                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6901                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6902                     }
6903                 }
6904               else
6905                 return false;
6906             }
6907           else
6908             return false;
6909         }
6910     }
6911   return w==end2;
6912 }
6913
6914 /*!
6915  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
6916  * put True to the corresponding entry in \a vec.
6917  * \a vec is expected to be with the same size than the number of tuples of \a this.
6918  */
6919 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6920 {
6921   checkAllocated();
6922   if(getNumberOfComponents()!=1)
6923     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6924   int nbOfTuples(getNumberOfTuples());
6925   if(nbOfTuples!=(int)vec.size())
6926     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6927   const int *pt(begin());
6928   for(int i=0;i<nbOfTuples;i++)
6929     if(pt[i]==val)
6930       vec[i]=true;
6931 }
6932
6933 /*!
6934  * Sorts values of the array.
6935  *  \param [in] asc - \a true means ascending order, \a false, descending.
6936  *  \throw If \a this is not allocated.
6937  *  \throw If \a this->getNumberOfComponents() != 1.
6938  */
6939 void DataArrayInt::sort(bool asc)
6940 {
6941   checkAllocated();
6942   if(getNumberOfComponents()!=1)
6943     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6944   _mem.sort(asc);
6945   declareAsNew();
6946 }
6947
6948 /*!
6949  * Computes for each tuple the sum of number of components values in the tuple and return it.
6950  * 
6951  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6952  *          same number of tuples as \a this array and one component.
6953  *          The caller is to delete this result array using decrRef() as it is no more
6954  *          needed.
6955  *  \throw If \a this is not allocated.
6956  */
6957 DataArrayInt *DataArrayInt::sumPerTuple() const
6958 {
6959   checkAllocated();
6960   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6961   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6962   ret->alloc(nbOfTuple,1);
6963   const int *src(getConstPointer());
6964   int *dest(ret->getPointer());
6965   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6966     *dest=std::accumulate(src,src+nbOfComp,0);
6967   return ret.retn();
6968 }
6969
6970 /*!
6971  * Reverse the array values.
6972  *  \throw If \a this->getNumberOfComponents() < 1.
6973  *  \throw If \a this is not allocated.
6974  */
6975 void DataArrayInt::reverse()
6976 {
6977   checkAllocated();
6978   _mem.reverse(getNumberOfComponents());
6979   declareAsNew();
6980 }
6981
6982 /*!
6983  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6984  * If not an exception is thrown.
6985  *  \param [in] increasing - if \a true, the array values should be increasing.
6986  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6987  *         increasing arg.
6988  *  \throw If \a this->getNumberOfComponents() != 1.
6989  *  \throw If \a this is not allocated.
6990  */
6991 void DataArrayInt::checkMonotonic(bool increasing) const
6992 {
6993   if(!isMonotonic(increasing))
6994     {
6995       if (increasing)
6996         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6997       else
6998         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6999     }
7000 }
7001
7002 /*!
7003  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
7004  *  \param [in] increasing - if \a true, array values should be increasing.
7005  *  \return bool - \a true if values change in accordance with \a increasing arg.
7006  *  \throw If \a this->getNumberOfComponents() != 1.
7007  *  \throw If \a this is not allocated.
7008  */
7009 bool DataArrayInt::isMonotonic(bool increasing) const
7010 {
7011   checkAllocated();
7012   if(getNumberOfComponents()!=1)
7013     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
7014   int nbOfElements=getNumberOfTuples();
7015   const int *ptr=getConstPointer();
7016   if(nbOfElements==0)
7017     return true;
7018   int ref=ptr[0];
7019   if(increasing)
7020     {
7021       for(int i=1;i<nbOfElements;i++)
7022         {
7023           if(ptr[i]>=ref)
7024             ref=ptr[i];
7025           else
7026             return false;
7027         }
7028     }
7029   else
7030     {
7031       for(int i=1;i<nbOfElements;i++)
7032         {
7033           if(ptr[i]<=ref)
7034             ref=ptr[i];
7035           else
7036             return false;
7037         }
7038     }
7039   return true;
7040 }
7041
7042 /*!
7043  * This method check that array consistently INCREASING or DECREASING in value.
7044  */
7045 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
7046 {
7047   checkAllocated();
7048   if(getNumberOfComponents()!=1)
7049     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
7050   int nbOfElements=getNumberOfTuples();
7051   const int *ptr=getConstPointer();
7052   if(nbOfElements==0)
7053     return true;
7054   int ref=ptr[0];
7055   if(increasing)
7056     {
7057       for(int i=1;i<nbOfElements;i++)
7058         {
7059           if(ptr[i]>ref)
7060             ref=ptr[i];
7061           else
7062             return false;
7063         }
7064     }
7065   else
7066     {
7067       for(int i=1;i<nbOfElements;i++)
7068         {
7069           if(ptr[i]<ref)
7070             ref=ptr[i];
7071           else
7072             return false;
7073         }
7074     }
7075   return true;
7076 }
7077
7078 /*!
7079  * This method check that array consistently INCREASING or DECREASING in value.
7080  */
7081 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
7082 {
7083   if(!isStrictlyMonotonic(increasing))
7084     {
7085       if (increasing)
7086         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
7087       else
7088         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
7089     }
7090 }
7091
7092 /*!
7093  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
7094  * one-dimensional arrays that must be of the same length. The result array describes
7095  * correspondence between \a this and \a other arrays, so that 
7096  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
7097  * not possible because some element in \a other is not in \a this, an exception is thrown.
7098  *  \param [in] other - an array to compute permutation to.
7099  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
7100  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
7101  * no more needed.
7102  *  \throw If \a this->getNumberOfComponents() != 1.
7103  *  \throw If \a other->getNumberOfComponents() != 1.
7104  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
7105  *  \throw If \a other includes a value which is not in \a this array.
7106  * 
7107  *  \if ENABLE_EXAMPLES
7108  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
7109  *
7110  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
7111  *  \endif
7112  */
7113 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
7114 {
7115   checkAllocated();
7116   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
7117     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
7118   int nbTuple=getNumberOfTuples();
7119   other.checkAllocated();
7120   if(nbTuple!=other.getNumberOfTuples())
7121     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
7122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7123   ret->alloc(nbTuple,1);
7124   ret->fillWithValue(-1);
7125   const int *pt=getConstPointer();
7126   std::map<int,int> mm;
7127   for(int i=0;i<nbTuple;i++)
7128     mm[pt[i]]=i;
7129   pt=other.getConstPointer();
7130   int *retToFill=ret->getPointer();
7131   for(int i=0;i<nbTuple;i++)
7132     {
7133       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7134       if(it==mm.end())
7135         {
7136           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7137           throw INTERP_KERNEL::Exception(oss.str().c_str());
7138         }
7139       retToFill[i]=(*it).second;
7140     }
7141   return ret.retn();
7142 }
7143
7144 /*!
7145  * Sets a C array to be used as raw data of \a this. The previously set info
7146  *  of components is retained and re-sized. 
7147  * For more info see \ref MEDCouplingArraySteps1.
7148  *  \param [in] array - the C array to be used as raw data of \a this.
7149  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7150  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
7151  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
7152  *                     \c free(\c array ) will be called.
7153  *  \param [in] nbOfTuple - new number of tuples in \a this.
7154  *  \param [in] nbOfCompo - new number of components in \a this.
7155  */
7156 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7157 {
7158   _info_on_compo.resize(nbOfCompo);
7159   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7160   declareAsNew();
7161 }
7162
7163 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7164 {
7165   _info_on_compo.resize(nbOfCompo);
7166   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7167   declareAsNew();
7168 }
7169
7170 /*!
7171  * Returns a new DataArrayInt holding the same values as \a this array but differently
7172  * arranged in memory. If \a this array holds 2 components of 3 values:
7173  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7174  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7175  *  \warning Do not confuse this method with transpose()!
7176  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7177  *          is to delete using decrRef() as it is no more needed.
7178  *  \throw If \a this is not allocated.
7179  */
7180 DataArrayInt *DataArrayInt::fromNoInterlace() const
7181 {
7182   checkAllocated();
7183   if(_mem.isNull())
7184     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7185   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7186   DataArrayInt *ret=DataArrayInt::New();
7187   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7188   return ret;
7189 }
7190
7191 /*!
7192  * Returns a new DataArrayInt holding the same values as \a this array but differently
7193  * arranged in memory. If \a this array holds 2 components of 3 values:
7194  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7195  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7196  *  \warning Do not confuse this method with transpose()!
7197  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7198  *          is to delete using decrRef() as it is no more needed.
7199  *  \throw If \a this is not allocated.
7200  */
7201 DataArrayInt *DataArrayInt::toNoInterlace() const
7202 {
7203   checkAllocated();
7204   if(_mem.isNull())
7205     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7206   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7207   DataArrayInt *ret=DataArrayInt::New();
7208   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7209   return ret;
7210 }
7211
7212 /*!
7213  * Permutes values of \a this array as required by \a old2New array. The values are
7214  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7215  * the same as in \c this one.
7216  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7217  * For more info on renumbering see \ref numbering.
7218  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7219  *     giving a new position for i-th old value.
7220  */
7221 void DataArrayInt::renumberInPlace(const int *old2New)
7222 {
7223   checkAllocated();
7224   int nbTuples=getNumberOfTuples();
7225   int nbOfCompo=getNumberOfComponents();
7226   int *tmp=new int[nbTuples*nbOfCompo];
7227   const int *iptr=getConstPointer();
7228   for(int i=0;i<nbTuples;i++)
7229     {
7230       int v=old2New[i];
7231       if(v>=0 && v<nbTuples)
7232         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7233       else
7234         {
7235           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7236           throw INTERP_KERNEL::Exception(oss.str().c_str());
7237         }
7238     }
7239   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7240   delete [] tmp;
7241   declareAsNew();
7242 }
7243
7244 /*!
7245  * Permutes values of \a this array as required by \a new2Old array. The values are
7246  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7247  * the same as in \c this one.
7248  * For more info on renumbering see \ref numbering.
7249  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7250  *     giving a previous position of i-th new value.
7251  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7252  *          is to delete using decrRef() as it is no more needed.
7253  */
7254 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7255 {
7256   checkAllocated();
7257   int nbTuples=getNumberOfTuples();
7258   int nbOfCompo=getNumberOfComponents();
7259   int *tmp=new int[nbTuples*nbOfCompo];
7260   const int *iptr=getConstPointer();
7261   for(int i=0;i<nbTuples;i++)
7262     {
7263       int v=new2Old[i];
7264       if(v>=0 && v<nbTuples)
7265         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7266       else
7267         {
7268           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7269           throw INTERP_KERNEL::Exception(oss.str().c_str());
7270         }
7271     }
7272   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7273   delete [] tmp;
7274   declareAsNew();
7275 }
7276
7277 /*!
7278  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7279  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7280  * Number of tuples in the result array remains the same as in \c this one.
7281  * If a permutation reduction is needed, renumberAndReduce() should be used.
7282  * For more info on renumbering see \ref numbering.
7283  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7284  *          giving a new position for i-th old value.
7285  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7286  *          is to delete using decrRef() as it is no more needed.
7287  *  \throw If \a this is not allocated.
7288  */
7289 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7290 {
7291   checkAllocated();
7292   int nbTuples=getNumberOfTuples();
7293   int nbOfCompo=getNumberOfComponents();
7294   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7295   ret->alloc(nbTuples,nbOfCompo);
7296   ret->copyStringInfoFrom(*this);
7297   const int *iptr=getConstPointer();
7298   int *optr=ret->getPointer();
7299   for(int i=0;i<nbTuples;i++)
7300     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7301   ret->copyStringInfoFrom(*this);
7302   return ret.retn();
7303 }
7304
7305 /*!
7306  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7307  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7308  * tuples in the result array remains the same as in \c this one.
7309  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7310  * For more info on renumbering see \ref numbering.
7311  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7312  *     giving a previous position of i-th new value.
7313  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7314  *          is to delete using decrRef() as it is no more needed.
7315  */
7316 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7317 {
7318   checkAllocated();
7319   int nbTuples=getNumberOfTuples();
7320   int nbOfCompo=getNumberOfComponents();
7321   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7322   ret->alloc(nbTuples,nbOfCompo);
7323   ret->copyStringInfoFrom(*this);
7324   const int *iptr=getConstPointer();
7325   int *optr=ret->getPointer();
7326   for(int i=0;i<nbTuples;i++)
7327     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7328   ret->copyStringInfoFrom(*this);
7329   return ret.retn();
7330 }
7331
7332 /*!
7333  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7334  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7335  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7336  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7337  * \a old2New[ i ] is negative, is missing from the result array.
7338  * For more info on renumbering see \ref numbering.
7339  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7340  *     giving a new position for i-th old tuple and giving negative position for
7341  *     for i-th old tuple that should be omitted.
7342  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7343  *          is to delete using decrRef() as it is no more needed.
7344  */
7345 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7346 {
7347   checkAllocated();
7348   int nbTuples=getNumberOfTuples();
7349   int nbOfCompo=getNumberOfComponents();
7350   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7351   ret->alloc(newNbOfTuple,nbOfCompo);
7352   const int *iptr=getConstPointer();
7353   int *optr=ret->getPointer();
7354   for(int i=0;i<nbTuples;i++)
7355     {
7356       int w=old2New[i];
7357       if(w>=0)
7358         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7359     }
7360   ret->copyStringInfoFrom(*this);
7361   return ret.retn();
7362 }
7363
7364 /*!
7365  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7366  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7367  * \a new2OldBg array.
7368  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7369  * This method is equivalent to renumberAndReduce() except that convention in input is
7370  * \c new2old and \b not \c old2new.
7371  * For more info on renumbering see \ref numbering.
7372  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7373  *              tuple index in \a this array to fill the i-th tuple in the new array.
7374  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7375  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7376  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7377  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7378  *          is to delete using decrRef() as it is no more needed.
7379  */
7380 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7381 {
7382   checkAllocated();
7383   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7384   int nbComp=getNumberOfComponents();
7385   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7386   ret->copyStringInfoFrom(*this);
7387   int *pt=ret->getPointer();
7388   const int *srcPt=getConstPointer();
7389   int i=0;
7390   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7391     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7392   ret->copyStringInfoFrom(*this);
7393   return ret.retn();
7394 }
7395
7396 /*!
7397  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7398  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7399  * \a new2OldBg array.
7400  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7401  * This method is equivalent to renumberAndReduce() except that convention in input is
7402  * \c new2old and \b not \c old2new.
7403  * This method is equivalent to selectByTupleId() except that it prevents coping data
7404  * from behind the end of \a this array.
7405  * For more info on renumbering see \ref numbering.
7406  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7407  *              tuple index in \a this array to fill the i-th tuple in the new array.
7408  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7409  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7410  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7411  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7412  *          is to delete using decrRef() as it is no more needed.
7413  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7414  */
7415 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7416 {
7417   checkAllocated();
7418   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7419   int nbComp=getNumberOfComponents();
7420   int oldNbOfTuples=getNumberOfTuples();
7421   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7422   ret->copyStringInfoFrom(*this);
7423   int *pt=ret->getPointer();
7424   const int *srcPt=getConstPointer();
7425   int i=0;
7426   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7427     if(*w>=0 && *w<oldNbOfTuples)
7428       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7429     else
7430       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7431   ret->copyStringInfoFrom(*this);
7432   return ret.retn();
7433 }
7434
7435 /*!
7436  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7437  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7438  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7439  * command \c range( \a bg, \a end2, \a step ).
7440  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7441  * not constructed explicitly.
7442  * For more info on renumbering see \ref numbering.
7443  *  \param [in] bg - index of the first tuple to copy from \a this array.
7444  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7445  *  \param [in] step - index increment to get index of the next tuple to copy.
7446  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7447  *          is to delete using decrRef() as it is no more needed.
7448  *  \sa DataArrayInt::substr.
7449  */
7450 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7451 {
7452   checkAllocated();
7453   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7454   int nbComp=getNumberOfComponents();
7455   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7456   ret->alloc(newNbOfTuples,nbComp);
7457   int *pt=ret->getPointer();
7458   const int *srcPt=getConstPointer()+bg*nbComp;
7459   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7460     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7461   ret->copyStringInfoFrom(*this);
7462   return ret.retn();
7463 }
7464
7465 /*!
7466  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7467  * of tuples specified by \a ranges parameter.
7468  * For more info on renumbering see \ref numbering.
7469  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7470  *              of tuples in [\c begin,\c end) format.
7471  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7472  *          is to delete using decrRef() as it is no more needed.
7473  *  \throw If \a end < \a begin.
7474  *  \throw If \a end > \a this->getNumberOfTuples().
7475  *  \throw If \a this is not allocated.
7476  */
7477 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7478 {
7479   checkAllocated();
7480   int nbOfComp=getNumberOfComponents();
7481   int nbOfTuplesThis=getNumberOfTuples();
7482   if(ranges.empty())
7483     {
7484       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7485       ret->alloc(0,nbOfComp);
7486       ret->copyStringInfoFrom(*this);
7487       return ret.retn();
7488     }
7489   int ref=ranges.front().first;
7490   int nbOfTuples=0;
7491   bool isIncreasing=true;
7492   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7493     {
7494       if((*it).first<=(*it).second)
7495         {
7496           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7497             {
7498               nbOfTuples+=(*it).second-(*it).first;
7499               if(isIncreasing)
7500                 isIncreasing=ref<=(*it).first;
7501               ref=(*it).second;
7502             }
7503           else
7504             {
7505               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7506               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7507               throw INTERP_KERNEL::Exception(oss.str().c_str());
7508             }
7509         }
7510       else
7511         {
7512           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7513           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7514           throw INTERP_KERNEL::Exception(oss.str().c_str());
7515         }
7516     }
7517   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7518     return deepCpy();
7519   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7520   ret->alloc(nbOfTuples,nbOfComp);
7521   ret->copyStringInfoFrom(*this);
7522   const int *src=getConstPointer();
7523   int *work=ret->getPointer();
7524   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7525     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7526   return ret.retn();
7527 }
7528
7529 /*!
7530  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7531  * This map, if applied to \a this array, would make it sorted. For example, if
7532  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7533  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7534  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7535  * This method is useful for renumbering (in MED file for example). For more info
7536  * on renumbering see \ref numbering.
7537  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7538  *          array using decrRef() as it is no more needed.
7539  *  \throw If \a this is not allocated.
7540  *  \throw If \a this->getNumberOfComponents() != 1.
7541  *  \throw If there are equal values in \a this array.
7542  */
7543 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7544 {
7545   checkAllocated();
7546   if(getNumberOfComponents()!=1)
7547     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7548   int nbTuples=getNumberOfTuples();
7549   const int *pt=getConstPointer();
7550   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7551   DataArrayInt *ret=DataArrayInt::New();
7552   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7553   return ret;
7554 }
7555
7556 /*!
7557  * 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
7558  * input array \a ids2.
7559  * \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.
7560  * 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
7561  * inversely.
7562  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7563  *
7564  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7565  *          array using decrRef() as it is no more needed.
7566  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7567  * 
7568  */
7569 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7570 {
7571   if(!ids1 || !ids2)
7572     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7573   if(!ids1->isAllocated() || !ids2->isAllocated())
7574     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7575   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7576     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7577   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7578     {
7579       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 !";
7580       throw INTERP_KERNEL::Exception(oss.str().c_str());
7581     }
7582   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7583   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7584   p1->sort(true); p2->sort(true);
7585   if(!p1->isEqualWithoutConsideringStr(*p2))
7586     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7587   p1=ids1->checkAndPreparePermutation();
7588   p2=ids2->checkAndPreparePermutation();
7589   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7590   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7591   return p2.retn();
7592 }
7593
7594 /*!
7595  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7596  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7597  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7598  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7599  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7600  * The first of out arrays returns indices of elements of \a this array, grouped by their
7601  * place in the set \a B. The second out array is the index of the first one; it shows how
7602  * many elements of \a A are mapped into each element of \a B. <br>
7603  * For more info on
7604  * mapping and its usage in renumbering see \ref numbering. <br>
7605  * \b Example:
7606  * - \a this: [0,3,2,3,2,2,1,2]
7607  * - \a targetNb: 4
7608  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7609  * - \a arrI: [0,1,2,6,8]
7610  *
7611  * This result means: <br>
7612  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7613  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7614  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7615  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7616  * \a arrI[ 2+1 ]]); <br> etc.
7617  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7618  *         than the maximal value of \a A.
7619  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7620  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7621  *         this array using decrRef() as it is no more needed.
7622  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7623  *         elements of \a this. The caller is to delete this array using decrRef() as it
7624  *         is no more needed.
7625  *  \throw If \a this is not allocated.
7626  *  \throw If \a this->getNumberOfComponents() != 1.
7627  *  \throw If any value in \a this is more or equal to \a targetNb.
7628  */
7629 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7630 {
7631   checkAllocated();
7632   if(getNumberOfComponents()!=1)
7633     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7634   int nbOfTuples=getNumberOfTuples();
7635   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7636   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7637   retI->alloc(targetNb+1,1);
7638   const int *input=getConstPointer();
7639   std::vector< std::vector<int> > tmp(targetNb);
7640   for(int i=0;i<nbOfTuples;i++)
7641     {
7642       int tmp2=input[i];
7643       if(tmp2>=0 && tmp2<targetNb)
7644         tmp[tmp2].push_back(i);
7645       else
7646         {
7647           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7648           throw INTERP_KERNEL::Exception(oss.str().c_str());
7649         }
7650     }
7651   int *retIPtr=retI->getPointer();
7652   *retIPtr=0;
7653   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7654     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7655   if(nbOfTuples!=retI->getIJ(targetNb,0))
7656     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7657   ret->alloc(nbOfTuples,1);
7658   int *retPtr=ret->getPointer();
7659   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7660     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7661   arr=ret.retn();
7662   arrI=retI.retn();
7663 }
7664
7665
7666 /*!
7667  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7668  * from a zip representation of a surjective format (returned e.g. by
7669  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7670  * for example). The result array minimizes the permutation. <br>
7671  * For more info on renumbering see \ref numbering. <br>
7672  * \b Example: <br>
7673  * - \a nbOfOldTuples: 10 
7674  * - \a arr          : [0,3, 5,7,9]
7675  * - \a arrIBg       : [0,2,5]
7676  * - \a newNbOfTuples: 7
7677  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7678  *
7679  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7680  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7681  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7682  *         (indices of) equal values. Its every element (except the last one) points to
7683  *         the first element of a group of equal values.
7684  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7685  *          arrIBg is \a arrIEnd[ -1 ].
7686  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7687  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7688  *          array using decrRef() as it is no more needed.
7689  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7690  */
7691 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7692 {
7693   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7694   ret->alloc(nbOfOldTuples,1);
7695   int *pt=ret->getPointer();
7696   std::fill(pt,pt+nbOfOldTuples,-1);
7697   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7698   const int *cIPtr=arrIBg;
7699   for(int i=0;i<nbOfGrps;i++)
7700     pt[arr[cIPtr[i]]]=-(i+2);
7701   int newNb=0;
7702   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7703     {
7704       if(pt[iNode]<0)
7705         {
7706           if(pt[iNode]==-1)
7707             pt[iNode]=newNb++;
7708           else
7709             {
7710               int grpId=-(pt[iNode]+2);
7711               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7712                 {
7713                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7714                     pt[arr[j]]=newNb;
7715                   else
7716                     {
7717                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7718                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7719                     }
7720                 }
7721               newNb++;
7722             }
7723         }
7724     }
7725   newNbOfTuples=newNb;
7726   return ret.retn();
7727 }
7728
7729 /*!
7730  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7731  * which if applied to \a this array would make it sorted ascendingly.
7732  * For more info on renumbering see \ref numbering. <br>
7733  * \b Example: <br>
7734  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7735  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7736  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7737  *
7738  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7739  *          array using decrRef() as it is no more needed.
7740  *  \throw If \a this is not allocated.
7741  *  \throw If \a this->getNumberOfComponents() != 1.
7742  */
7743 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7744 {
7745   checkAllocated();
7746   if(getNumberOfComponents()!=1)
7747     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7748   int nbOfTuples=getNumberOfTuples();
7749   const int *pt=getConstPointer();
7750   std::map<int,int> m;
7751   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7752   ret->alloc(nbOfTuples,1);
7753   int *opt=ret->getPointer();
7754   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7755     {
7756       int val=*pt;
7757       std::map<int,int>::iterator it=m.find(val);
7758       if(it!=m.end())
7759         {
7760           *opt=(*it).second;
7761           (*it).second++;
7762         }
7763       else
7764         {
7765           *opt=0;
7766           m.insert(std::pair<int,int>(val,1));
7767         }
7768     }
7769   int sum=0;
7770   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7771     {
7772       int vt=(*it).second;
7773       (*it).second=sum;
7774       sum+=vt;
7775     }
7776   pt=getConstPointer();
7777   opt=ret->getPointer();
7778   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7779     *opt+=m[*pt];
7780   //
7781   return ret.retn();
7782 }
7783
7784 /*!
7785  * Checks if contents of \a this array are equal to that of an array filled with
7786  * iota(). This method is particularly useful for DataArrayInt instances that represent
7787  * a renumbering array to check the real need in renumbering. In this case it is better to use isIdentity2
7788  * method of isIdentity method.
7789  *
7790  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7791  *  \throw If \a this is not allocated.
7792  *  \throw If \a this->getNumberOfComponents() != 1.
7793  *  \sa isIdentity2
7794  */
7795 bool DataArrayInt::isIdentity() const
7796 {
7797   checkAllocated();
7798   if(getNumberOfComponents()!=1)
7799     return false;
7800   int nbOfTuples(getNumberOfTuples());
7801   const int *pt=getConstPointer();
7802   for(int i=0;i<nbOfTuples;i++,pt++)
7803     if(*pt!=i)
7804       return false;
7805   return true;
7806 }
7807
7808 /*!
7809  * This method is stronger than isIdentity method. This method checks than \a this can be considered as an identity function
7810  * of a set having \a sizeExpected elements into itself.
7811  *
7812  * \param [in] sizeExpected - The number of elements
7813  * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) and if \a this has \a sizeExpected tuples in it.
7814  *
7815  *  \throw If \a this is not allocated.
7816  *  \throw If \a this->getNumberOfComponents() != 1.
7817  * \sa isIdentity
7818  */
7819 bool DataArrayInt::isIdentity2(int sizeExpected) const
7820 {
7821   bool ret0(isIdentity());
7822   if(!ret0)
7823     return false;
7824   return getNumberOfTuples()==sizeExpected;
7825 }
7826
7827 /*!
7828  * Checks if all values in \a this array are equal to \a val.
7829  *  \param [in] val - value to check equality of array values to.
7830  *  \return bool - \a true if all values are \a val.
7831  *  \throw If \a this is not allocated.
7832  *  \throw If \a this->getNumberOfComponents() != 1
7833  */
7834 bool DataArrayInt::isUniform(int val) const
7835 {
7836   checkAllocated();
7837   if(getNumberOfComponents()!=1)
7838     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7839   int nbOfTuples=getNumberOfTuples();
7840   const int *w=getConstPointer();
7841   const int *end2=w+nbOfTuples;
7842   for(;w!=end2;w++)
7843     if(*w!=val)
7844       return false;
7845   return true;
7846 }
7847
7848 /*!
7849  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7850  * array to the new one.
7851  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7852  */
7853 DataArrayDouble *DataArrayInt::convertToDblArr() const
7854 {
7855   checkAllocated();
7856   DataArrayDouble *ret=DataArrayDouble::New();
7857   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7858   std::size_t nbOfVals=getNbOfElems();
7859   const int *src=getConstPointer();
7860   double *dest=ret->getPointer();
7861   std::copy(src,src+nbOfVals,dest);
7862   ret->copyStringInfoFrom(*this);
7863   return ret;
7864 }
7865
7866 /*!
7867  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7868  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7869  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7870  * This method is a specialization of selectByTupleId2().
7871  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7872  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7873  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7874  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7875  *          is to delete using decrRef() as it is no more needed.
7876  *  \throw If \a tupleIdBg < 0.
7877  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7878     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7879  *  \sa DataArrayInt::selectByTupleId2
7880  */
7881 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7882 {
7883   checkAllocated();
7884   int nbt=getNumberOfTuples();
7885   if(tupleIdBg<0)
7886     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7887   if(tupleIdBg>nbt)
7888     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7889   int trueEnd=tupleIdEnd;
7890   if(tupleIdEnd!=-1)
7891     {
7892       if(tupleIdEnd>nbt)
7893         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7894     }
7895   else
7896     trueEnd=nbt;
7897   int nbComp=getNumberOfComponents();
7898   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7899   ret->alloc(trueEnd-tupleIdBg,nbComp);
7900   ret->copyStringInfoFrom(*this);
7901   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7902   return ret.retn();
7903 }
7904
7905 /*!
7906  * Changes the number of components within \a this array so that its raw data **does
7907  * not** change, instead splitting this data into tuples changes.
7908  *  \warning This method erases all (name and unit) component info set before!
7909  *  \param [in] newNbOfComp - number of components for \a this array to have.
7910  *  \throw If \a this is not allocated
7911  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7912  *  \throw If \a newNbOfCompo is lower than 1.
7913  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7914  *  \warning This method erases all (name and unit) component info set before!
7915  */
7916 void DataArrayInt::rearrange(int newNbOfCompo)
7917 {
7918   checkAllocated();
7919   if(newNbOfCompo<1)
7920     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7921   std::size_t nbOfElems=getNbOfElems();
7922   if(nbOfElems%newNbOfCompo!=0)
7923     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7924   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7925     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7926   _info_on_compo.clear();
7927   _info_on_compo.resize(newNbOfCompo);
7928   declareAsNew();
7929 }
7930
7931 /*!
7932  * Changes the number of components within \a this array to be equal to its number
7933  * of tuples, and inversely its number of tuples to become equal to its number of 
7934  * components. So that its raw data **does not** change, instead splitting this
7935  * data into tuples changes.
7936  *  \warning This method erases all (name and unit) component info set before!
7937  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7938  *  \throw If \a this is not allocated.
7939  *  \sa rearrange()
7940  */
7941 void DataArrayInt::transpose()
7942 {
7943   checkAllocated();
7944   int nbOfTuples=getNumberOfTuples();
7945   rearrange(nbOfTuples);
7946 }
7947
7948 /*!
7949  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7950  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7951  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7952  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7953  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7954  * components.  
7955  *  \param [in] newNbOfComp - number of components for the new array to have.
7956  *  \param [in] dftValue - value assigned to new values added to the new array.
7957  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7958  *          is to delete using decrRef() as it is no more needed.
7959  *  \throw If \a this is not allocated.
7960  */
7961 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7962 {
7963   checkAllocated();
7964   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7965   ret->alloc(getNumberOfTuples(),newNbOfComp);
7966   const int *oldc=getConstPointer();
7967   int *nc=ret->getPointer();
7968   int nbOfTuples=getNumberOfTuples();
7969   int oldNbOfComp=getNumberOfComponents();
7970   int dim=std::min(oldNbOfComp,newNbOfComp);
7971   for(int i=0;i<nbOfTuples;i++)
7972     {
7973       int j=0;
7974       for(;j<dim;j++)
7975         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7976       for(;j<newNbOfComp;j++)
7977         nc[newNbOfComp*i+j]=dftValue;
7978     }
7979   ret->setName(getName());
7980   for(int i=0;i<dim;i++)
7981     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7982   ret->setName(getName());
7983   return ret.retn();
7984 }
7985
7986 /*!
7987  * Changes number of tuples in the array. If the new number of tuples is smaller
7988  * than the current number the array is truncated, otherwise the array is extended.
7989  *  \param [in] nbOfTuples - new number of tuples. 
7990  *  \throw If \a this is not allocated.
7991  *  \throw If \a nbOfTuples is negative.
7992  */
7993 void DataArrayInt::reAlloc(int nbOfTuples)
7994 {
7995   if(nbOfTuples<0)
7996     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7997   checkAllocated();
7998   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7999   declareAsNew();
8000 }
8001
8002
8003 /*!
8004  * Returns a copy of \a this array composed of selected components.
8005  * The new DataArrayInt has the same number of tuples but includes components
8006  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
8007  * can be either less, same or more than \a this->getNbOfElems().
8008  *  \param [in] compoIds - sequence of zero based indices of components to include
8009  *              into the new array.
8010  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
8011  *          is to delete using decrRef() as it is no more needed.
8012  *  \throw If \a this is not allocated.
8013  *  \throw If a component index (\a i) is not valid: 
8014  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
8015  *
8016  *  \if ENABLE_EXAMPLES
8017  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
8018  *  \endif
8019  */
8020 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
8021 {
8022   checkAllocated();
8023   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
8024   int newNbOfCompo=(int)compoIds.size();
8025   int oldNbOfCompo=getNumberOfComponents();
8026   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
8027     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
8028   int nbOfTuples=getNumberOfTuples();
8029   ret->alloc(nbOfTuples,newNbOfCompo);
8030   ret->copyPartOfStringInfoFrom(*this,compoIds);
8031   const int *oldc=getConstPointer();
8032   int *nc=ret->getPointer();
8033   for(int i=0;i<nbOfTuples;i++)
8034     for(int j=0;j<newNbOfCompo;j++,nc++)
8035       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
8036   return ret.retn();
8037 }
8038
8039 /*!
8040  * Appends components of another array to components of \a this one, tuple by tuple.
8041  * So that the number of tuples of \a this array remains the same and the number of 
8042  * components increases.
8043  *  \param [in] other - the DataArrayInt to append to \a this one.
8044  *  \throw If \a this is not allocated.
8045  *  \throw If \a this and \a other arrays have different number of tuples.
8046  *
8047  *  \if ENABLE_EXAMPLES
8048  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
8049  *
8050  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
8051  *  \endif
8052  */
8053 void DataArrayInt::meldWith(const DataArrayInt *other)
8054 {
8055   if(!other)
8056     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
8057   checkAllocated();
8058   other->checkAllocated();
8059   int nbOfTuples=getNumberOfTuples();
8060   if(nbOfTuples!=other->getNumberOfTuples())
8061     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
8062   int nbOfComp1=getNumberOfComponents();
8063   int nbOfComp2=other->getNumberOfComponents();
8064   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
8065   int *w=newArr;
8066   const int *inp1=getConstPointer();
8067   const int *inp2=other->getConstPointer();
8068   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
8069     {
8070       w=std::copy(inp1,inp1+nbOfComp1,w);
8071       w=std::copy(inp2,inp2+nbOfComp2,w);
8072     }
8073   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
8074   std::vector<int> compIds(nbOfComp2);
8075   for(int i=0;i<nbOfComp2;i++)
8076     compIds[i]=nbOfComp1+i;
8077   copyPartOfStringInfoFrom2(compIds,*other);
8078 }
8079
8080 /*!
8081  * Copy all components in a specified order from another DataArrayInt.
8082  * The specified components become the first ones in \a this array.
8083  * Both numerical and textual data is copied. The number of tuples in \a this and
8084  * the other array can be different.
8085  *  \param [in] a - the array to copy data from.
8086  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
8087  *              to be copied.
8088  *  \throw If \a a is NULL.
8089  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
8090  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
8091  *
8092  *  \if ENABLE_EXAMPLES
8093  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
8094  *  \endif
8095  */
8096 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
8097 {
8098   if(!a)
8099     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
8100   checkAllocated();
8101   a->checkAllocated();
8102   copyPartOfStringInfoFrom2(compoIds,*a);
8103   std::size_t partOfCompoSz=compoIds.size();
8104   int nbOfCompo=getNumberOfComponents();
8105   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
8106   const int *ac=a->getConstPointer();
8107   int *nc=getPointer();
8108   for(int i=0;i<nbOfTuples;i++)
8109     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
8110       nc[nbOfCompo*i+compoIds[j]]=*ac;
8111 }
8112
8113 /*!
8114  * Copy all values from another DataArrayInt into specified tuples and components
8115  * of \a this array. Textual data is not copied.
8116  * The tree parameters defining set of indices of tuples and components are similar to
8117  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
8118  *  \param [in] a - the array to copy values from.
8119  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
8120  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8121  *              are located.
8122  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8123  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
8124  *  \param [in] endComp - index of the component before which the components to assign
8125  *              to are located.
8126  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8127  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
8128  *              must be equal to the number of columns to assign to, else an
8129  *              exception is thrown; if \a false, then it is only required that \a
8130  *              a->getNbOfElems() equals to number of values to assign to (this condition
8131  *              must be respected even if \a strictCompoCompare is \a true). The number of 
8132  *              values to assign to is given by following Python expression:
8133  *              \a nbTargetValues = 
8134  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
8135  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8136  *  \throw If \a a is NULL.
8137  *  \throw If \a a is not allocated.
8138  *  \throw If \a this is not allocated.
8139  *  \throw If parameters specifying tuples and components to assign to do not give a
8140  *            non-empty range of increasing indices.
8141  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
8142  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
8143  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8144  *
8145  *  \if ENABLE_EXAMPLES
8146  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
8147  *  \endif
8148  */
8149 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8150 {
8151   if(!a)
8152     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8153   const char msg[]="DataArrayInt::setPartOfValues1";
8154   checkAllocated();
8155   a->checkAllocated();
8156   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8157   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8158   int nbComp=getNumberOfComponents();
8159   int nbOfTuples=getNumberOfTuples();
8160   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8161   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8162   bool assignTech=true;
8163   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8164     {
8165       if(strictCompoCompare)
8166         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8167     }
8168   else
8169     {
8170       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8171       assignTech=false;
8172     }
8173   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8174   const int *srcPt=a->getConstPointer();
8175   if(assignTech)
8176     {
8177       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8178         for(int j=0;j<newNbOfComp;j++,srcPt++)
8179           pt[j*stepComp]=*srcPt;
8180     }
8181   else
8182     {
8183       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8184         {
8185           const int *srcPt2=srcPt;
8186           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8187             pt[j*stepComp]=*srcPt2;
8188         }
8189     }
8190 }
8191
8192 /*!
8193  * Assign a given value to values at specified tuples and components of \a this array.
8194  * The tree parameters defining set of indices of tuples and components are similar to
8195  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8196  *  \param [in] a - the value to assign.
8197  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8198  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8199  *              are located.
8200  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8201  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8202  *  \param [in] endComp - index of the component before which the components to assign
8203  *              to are located.
8204  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8205  *  \throw If \a this is not allocated.
8206  *  \throw If parameters specifying tuples and components to assign to, do not give a
8207  *            non-empty range of increasing indices or indices are out of a valid range
8208  *            for \c this array.
8209  *
8210  *  \if ENABLE_EXAMPLES
8211  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8212  *  \endif
8213  */
8214 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8215 {
8216   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8217   checkAllocated();
8218   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8219   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8220   int nbComp=getNumberOfComponents();
8221   int nbOfTuples=getNumberOfTuples();
8222   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8223   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8224   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8225   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8226     for(int j=0;j<newNbOfComp;j++)
8227       pt[j*stepComp]=a;
8228 }
8229
8230
8231 /*!
8232  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8233  * components of \a this array. Textual data is not copied.
8234  * The tuples and components to assign to are defined by C arrays of indices.
8235  * There are two *modes of usage*:
8236  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8237  *   of \a a is assigned to its own location within \a this array. 
8238  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8239  *   components of every specified tuple of \a this array. In this mode it is required
8240  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8241  * 
8242  *  \param [in] a - the array to copy values from.
8243  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8244  *              assign values of \a a to.
8245  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8246  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8247  *              \a bgTuples <= \a pi < \a endTuples.
8248  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8249  *              assign values of \a a to.
8250  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8251  *              pointer to a component index <em>(pi)</em> varies as this: 
8252  *              \a bgComp <= \a pi < \a endComp.
8253  *  \param [in] strictCompoCompare - this parameter is checked only if the
8254  *               *mode of usage* is the first; if it is \a true (default), 
8255  *               then \a a->getNumberOfComponents() must be equal 
8256  *               to the number of specified columns, else this is not required.
8257  *  \throw If \a a is NULL.
8258  *  \throw If \a a is not allocated.
8259  *  \throw If \a this is not allocated.
8260  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8261  *         out of a valid range for \a this array.
8262  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8263  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8264  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8265  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8266  *
8267  *  \if ENABLE_EXAMPLES
8268  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8269  *  \endif
8270  */
8271 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8272 {
8273   if(!a)
8274     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8275   const char msg[]="DataArrayInt::setPartOfValues2";
8276   checkAllocated();
8277   a->checkAllocated();
8278   int nbComp=getNumberOfComponents();
8279   int nbOfTuples=getNumberOfTuples();
8280   for(const int *z=bgComp;z!=endComp;z++)
8281     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8282   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8283   int newNbOfComp=(int)std::distance(bgComp,endComp);
8284   bool assignTech=true;
8285   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8286     {
8287       if(strictCompoCompare)
8288         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8289     }
8290   else
8291     {
8292       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8293       assignTech=false;
8294     }
8295   int *pt=getPointer();
8296   const int *srcPt=a->getConstPointer();
8297   if(assignTech)
8298     {    
8299       for(const int *w=bgTuples;w!=endTuples;w++)
8300         {
8301           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8302           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8303             {    
8304               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8305             }
8306         }
8307     }
8308   else
8309     {
8310       for(const int *w=bgTuples;w!=endTuples;w++)
8311         {
8312           const int *srcPt2=srcPt;
8313           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8314           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8315             {    
8316               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8317             }
8318         }
8319     }
8320 }
8321
8322 /*!
8323  * Assign a given value to values at specified tuples and components of \a this array.
8324  * The tuples and components to assign to are defined by C arrays of indices.
8325  *  \param [in] a - the value to assign.
8326  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8327  *              assign \a a to.
8328  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8329  *              pointer to a tuple index (\a pi) varies as this: 
8330  *              \a bgTuples <= \a pi < \a endTuples.
8331  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8332  *              assign \a a to.
8333  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8334  *              pointer to a component index (\a pi) varies as this: 
8335  *              \a bgComp <= \a pi < \a endComp.
8336  *  \throw If \a this is not allocated.
8337  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8338  *         out of a valid range for \a this array.
8339  *
8340  *  \if ENABLE_EXAMPLES
8341  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8342  *  \endif
8343  */
8344 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8345 {
8346   checkAllocated();
8347   int nbComp=getNumberOfComponents();
8348   int nbOfTuples=getNumberOfTuples();
8349   for(const int *z=bgComp;z!=endComp;z++)
8350     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8351   int *pt=getPointer();
8352   for(const int *w=bgTuples;w!=endTuples;w++)
8353     for(const int *z=bgComp;z!=endComp;z++)
8354       {
8355         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8356         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8357       }
8358 }
8359
8360 /*!
8361  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8362  * components of \a this array. Textual data is not copied.
8363  * The tuples to assign to are defined by a C array of indices.
8364  * The components to assign to are defined by three values similar to parameters of
8365  * the Python function \c range(\c start,\c stop,\c step).
8366  * There are two *modes of usage*:
8367  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8368  *   of \a a is assigned to its own location within \a this array. 
8369  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8370  *   components of every specified tuple of \a this array. In this mode it is required
8371  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8372  *
8373  *  \param [in] a - the array to copy values from.
8374  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8375  *              assign values of \a a to.
8376  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8377  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8378  *              \a bgTuples <= \a pi < \a endTuples.
8379  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8380  *  \param [in] endComp - index of the component before which the components to assign
8381  *              to are located.
8382  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8383  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8384  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8385  *               then \a a->getNumberOfComponents() must be equal 
8386  *               to the number of specified columns, else this is not required.
8387  *  \throw If \a a is NULL.
8388  *  \throw If \a a is not allocated.
8389  *  \throw If \a this is not allocated.
8390  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8391  *         \a this array.
8392  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8393  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8394  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8395  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8396  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8397  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8398  *  \throw If parameters specifying components to assign to, do not give a
8399  *            non-empty range of increasing indices or indices are out of a valid range
8400  *            for \c this array.
8401  *
8402  *  \if ENABLE_EXAMPLES
8403  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8404  *  \endif
8405  */
8406 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8407 {
8408   if(!a)
8409     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8410   const char msg[]="DataArrayInt::setPartOfValues3";
8411   checkAllocated();
8412   a->checkAllocated();
8413   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8414   int nbComp=getNumberOfComponents();
8415   int nbOfTuples=getNumberOfTuples();
8416   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8417   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8418   bool assignTech=true;
8419   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8420     {
8421       if(strictCompoCompare)
8422         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8423     }
8424   else
8425     {
8426       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8427       assignTech=false;
8428     }
8429   int *pt=getPointer()+bgComp;
8430   const int *srcPt=a->getConstPointer();
8431   if(assignTech)
8432     {
8433       for(const int *w=bgTuples;w!=endTuples;w++)
8434         for(int j=0;j<newNbOfComp;j++,srcPt++)
8435           {
8436             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8437             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8438           }
8439     }
8440   else
8441     {
8442       for(const int *w=bgTuples;w!=endTuples;w++)
8443         {
8444           const int *srcPt2=srcPt;
8445           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8446             {
8447               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8448               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8449             }
8450         }
8451     }
8452 }
8453
8454 /*!
8455  * Assign a given value to values at specified tuples and components of \a this array.
8456  * The tuples to assign to are defined by a C array of indices.
8457  * The components to assign to are defined by three values similar to parameters of
8458  * the Python function \c range(\c start,\c stop,\c step).
8459  *  \param [in] a - the value to assign.
8460  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8461  *              assign \a a to.
8462  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8463  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8464  *              \a bgTuples <= \a pi < \a endTuples.
8465  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8466  *  \param [in] endComp - index of the component before which the components to assign
8467  *              to are located.
8468  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8469  *  \throw If \a this is not allocated.
8470  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8471  *         \a this array.
8472  *  \throw If parameters specifying components to assign to, do not give a
8473  *            non-empty range of increasing indices or indices are out of a valid range
8474  *            for \c this array.
8475  *
8476  *  \if ENABLE_EXAMPLES
8477  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8478  *  \endif
8479  */
8480 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8481 {
8482   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8483   checkAllocated();
8484   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8485   int nbComp=getNumberOfComponents();
8486   int nbOfTuples=getNumberOfTuples();
8487   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8488   int *pt=getPointer()+bgComp;
8489   for(const int *w=bgTuples;w!=endTuples;w++)
8490     for(int j=0;j<newNbOfComp;j++)
8491       {
8492         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8493         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8494       }
8495 }
8496
8497 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8498 {
8499   if(!a)
8500     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8501   const char msg[]="DataArrayInt::setPartOfValues4";
8502   checkAllocated();
8503   a->checkAllocated();
8504   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8505   int newNbOfComp=(int)std::distance(bgComp,endComp);
8506   int nbComp=getNumberOfComponents();
8507   for(const int *z=bgComp;z!=endComp;z++)
8508     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8509   int nbOfTuples=getNumberOfTuples();
8510   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8511   bool assignTech=true;
8512   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8513     {
8514       if(strictCompoCompare)
8515         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8516     }
8517   else
8518     {
8519       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8520       assignTech=false;
8521     }
8522   const int *srcPt=a->getConstPointer();
8523   int *pt=getPointer()+bgTuples*nbComp;
8524   if(assignTech)
8525     {
8526       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8527         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8528           pt[*z]=*srcPt;
8529     }
8530   else
8531     {
8532       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8533         {
8534           const int *srcPt2=srcPt;
8535           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8536             pt[*z]=*srcPt2;
8537         }
8538     }
8539 }
8540
8541 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8542 {
8543   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8544   checkAllocated();
8545   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8546   int nbComp=getNumberOfComponents();
8547   for(const int *z=bgComp;z!=endComp;z++)
8548     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8549   int nbOfTuples=getNumberOfTuples();
8550   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8551   int *pt=getPointer()+bgTuples*nbComp;
8552   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8553     for(const int *z=bgComp;z!=endComp;z++)
8554       pt[*z]=a;
8555 }
8556
8557 /*!
8558  * Copy some tuples from another DataArrayInt into specified tuples
8559  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8560  * components.
8561  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8562  * All components of selected tuples are copied.
8563  *  \param [in] a - the array to copy values from.
8564  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8565  *              target tuples of \a this. \a tuplesSelec has two components, and the
8566  *              first component specifies index of the source tuple and the second
8567  *              one specifies index of the target tuple.
8568  *  \throw If \a this is not allocated.
8569  *  \throw If \a a is NULL.
8570  *  \throw If \a a is not allocated.
8571  *  \throw If \a tuplesSelec is NULL.
8572  *  \throw If \a tuplesSelec is not allocated.
8573  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8574  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8575  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8576  *         the corresponding (\a this or \a a) array.
8577  */
8578 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8579 {
8580   if(!a || !tuplesSelec)
8581     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8582   checkAllocated();
8583   a->checkAllocated();
8584   tuplesSelec->checkAllocated();
8585   int nbOfComp=getNumberOfComponents();
8586   if(nbOfComp!=a->getNumberOfComponents())
8587     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8588   if(tuplesSelec->getNumberOfComponents()!=2)
8589     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8590   int thisNt=getNumberOfTuples();
8591   int aNt=a->getNumberOfTuples();
8592   int *valsToSet=getPointer();
8593   const int *valsSrc=a->getConstPointer();
8594   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8595     {
8596       if(tuple[1]>=0 && tuple[1]<aNt)
8597         {
8598           if(tuple[0]>=0 && tuple[0]<thisNt)
8599             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8600           else
8601             {
8602               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8603               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8604               throw INTERP_KERNEL::Exception(oss.str().c_str());
8605             }
8606         }
8607       else
8608         {
8609           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8610           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8611           throw INTERP_KERNEL::Exception(oss.str().c_str());
8612         }
8613     }
8614 }
8615
8616 /*!
8617  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8618  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8619  * components.
8620  * The tuples to assign to are defined by index of the first tuple, and
8621  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8622  * The tuples to copy are defined by values of a DataArrayInt.
8623  * All components of selected tuples are copied.
8624  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8625  *              values to.
8626  *  \param [in] aBase - the array to copy values from.
8627  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8628  *  \throw If \a this is not allocated.
8629  *  \throw If \a aBase is NULL.
8630  *  \throw If \a aBase is not allocated.
8631  *  \throw If \a tuplesSelec is NULL.
8632  *  \throw If \a tuplesSelec is not allocated.
8633  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8634  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8635  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8636  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8637  *         \a aBase array.
8638  */
8639 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8640 {
8641   if(!aBase || !tuplesSelec)
8642     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8643   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8644   if(!a)
8645     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8646   checkAllocated();
8647   a->checkAllocated();
8648   tuplesSelec->checkAllocated();
8649   int nbOfComp=getNumberOfComponents();
8650   if(nbOfComp!=a->getNumberOfComponents())
8651     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8652   if(tuplesSelec->getNumberOfComponents()!=1)
8653     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8654   int thisNt=getNumberOfTuples();
8655   int aNt=a->getNumberOfTuples();
8656   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8657   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8658   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8659     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8660   const int *valsSrc=a->getConstPointer();
8661   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8662     {
8663       if(*tuple>=0 && *tuple<aNt)
8664         {
8665           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8666         }
8667       else
8668         {
8669           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8670           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8671           throw INTERP_KERNEL::Exception(oss.str().c_str());
8672         }
8673     }
8674 }
8675
8676 /*!
8677  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8678  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8679  * components.
8680  * The tuples to copy are defined by three values similar to parameters of
8681  * the Python function \c range(\c start,\c stop,\c step).
8682  * The tuples to assign to are defined by index of the first tuple, and
8683  * their number is defined by number of tuples to copy.
8684  * All components of selected tuples are copied.
8685  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8686  *              values to.
8687  *  \param [in] aBase - the array to copy values from.
8688  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8689  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8690  *              are located.
8691  *  \param [in] step - index increment to get index of the next tuple to copy.
8692  *  \throw If \a this is not allocated.
8693  *  \throw If \a aBase is NULL.
8694  *  \throw If \a aBase is not allocated.
8695  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8696  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8697  *  \throw If parameters specifying tuples to copy, do not give a
8698  *            non-empty range of increasing indices or indices are out of a valid range
8699  *            for the array \a aBase.
8700  */
8701 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8702 {
8703   if(!aBase)
8704     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8705   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8706   if(!a)
8707     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8708   checkAllocated();
8709   a->checkAllocated();
8710   int nbOfComp=getNumberOfComponents();
8711   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8712   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8713   if(nbOfComp!=a->getNumberOfComponents())
8714     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8715   int thisNt=getNumberOfTuples();
8716   int aNt=a->getNumberOfTuples();
8717   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8718   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8719     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8720   if(end2>aNt)
8721     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8722   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8723   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8724     {
8725       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8726     }
8727 }
8728
8729 /*!
8730  * Returns a value located at specified tuple and component.
8731  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8732  * parameters is checked. So this method is safe but expensive if used to go through
8733  * all values of \a this.
8734  *  \param [in] tupleId - index of tuple of interest.
8735  *  \param [in] compoId - index of component of interest.
8736  *  \return double - value located by \a tupleId and \a compoId.
8737  *  \throw If \a this is not allocated.
8738  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8739  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8740  */
8741 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8742 {
8743   checkAllocated();
8744   if(tupleId<0 || tupleId>=getNumberOfTuples())
8745     {
8746       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8747       throw INTERP_KERNEL::Exception(oss.str().c_str());
8748     }
8749   if(compoId<0 || compoId>=getNumberOfComponents())
8750     {
8751       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8752       throw INTERP_KERNEL::Exception(oss.str().c_str());
8753     }
8754   return _mem[tupleId*_info_on_compo.size()+compoId];
8755 }
8756
8757 /*!
8758  * Returns the first value of \a this. 
8759  *  \return int - the last value of \a this array.
8760  *  \throw If \a this is not allocated.
8761  *  \throw If \a this->getNumberOfComponents() != 1.
8762  *  \throw If \a this->getNumberOfTuples() < 1.
8763  */
8764 int DataArrayInt::front() const
8765 {
8766   checkAllocated();
8767   if(getNumberOfComponents()!=1)
8768     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8769   int nbOfTuples=getNumberOfTuples();
8770   if(nbOfTuples<1)
8771     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8772   return *(getConstPointer());
8773 }
8774
8775 /*!
8776  * Returns the last value of \a this. 
8777  *  \return int - the last value of \a this array.
8778  *  \throw If \a this is not allocated.
8779  *  \throw If \a this->getNumberOfComponents() != 1.
8780  *  \throw If \a this->getNumberOfTuples() < 1.
8781  */
8782 int DataArrayInt::back() const
8783 {
8784   checkAllocated();
8785   if(getNumberOfComponents()!=1)
8786     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8787   int nbOfTuples=getNumberOfTuples();
8788   if(nbOfTuples<1)
8789     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8790   return *(getConstPointer()+nbOfTuples-1);
8791 }
8792
8793 /*!
8794  * Assign pointer to one array to a pointer to another appay. Reference counter of
8795  * \a arrayToSet is incremented / decremented.
8796  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8797  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8798  */
8799 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8800 {
8801   if(newArray!=arrayToSet)
8802     {
8803       if(arrayToSet)
8804         arrayToSet->decrRef();
8805       arrayToSet=newArray;
8806       if(arrayToSet)
8807         arrayToSet->incrRef();
8808     }
8809 }
8810
8811 DataArrayIntIterator *DataArrayInt::iterator()
8812 {
8813   return new DataArrayIntIterator(this);
8814 }
8815
8816 /*!
8817  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8818  * given one. The ids are sorted in the ascending order.
8819  *  \param [in] val - the value to find within \a this.
8820  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8821  *          array using decrRef() as it is no more needed.
8822  *  \throw If \a this is not allocated.
8823  *  \throw If \a this->getNumberOfComponents() != 1.
8824  *  \sa DataArrayInt::getIdsEqualTuple
8825  */
8826 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8827 {
8828   checkAllocated();
8829   if(getNumberOfComponents()!=1)
8830     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8831   const int *cptr(getConstPointer());
8832   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8833   int nbOfTuples=getNumberOfTuples();
8834   for(int i=0;i<nbOfTuples;i++,cptr++)
8835     if(*cptr==val)
8836       ret->pushBackSilent(i);
8837   return ret.retn();
8838 }
8839
8840 /*!
8841  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8842  * equal to a given one. 
8843  *  \param [in] val - the value to ignore within \a this.
8844  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8845  *          array using decrRef() as it is no more needed.
8846  *  \throw If \a this is not allocated.
8847  *  \throw If \a this->getNumberOfComponents() != 1.
8848  */
8849 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8850 {
8851   checkAllocated();
8852   if(getNumberOfComponents()!=1)
8853     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8854   const int *cptr(getConstPointer());
8855   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8856   int nbOfTuples=getNumberOfTuples();
8857   for(int i=0;i<nbOfTuples;i++,cptr++)
8858     if(*cptr!=val)
8859       ret->pushBackSilent(i);
8860   return ret.retn();
8861 }
8862
8863 /*!
8864  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8865  * This method is an extension of  DataArrayInt::getIdsEqual method.
8866  *
8867  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8868  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8869  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8870  *          array using decrRef() as it is no more needed.
8871  *  \throw If \a this is not allocated.
8872  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8873  * \throw If \a this->getNumberOfComponents() is equal to 0.
8874  * \sa DataArrayInt::getIdsEqual
8875  */
8876 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8877 {
8878   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8879   checkAllocated();
8880   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8881     {
8882       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8883       throw INTERP_KERNEL::Exception(oss.str().c_str());
8884     }
8885   if(nbOfCompoExp==0)
8886     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8887   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8888   const int *bg(begin()),*end2(end()),*work(begin());
8889   while(work!=end2)
8890     {
8891       work=std::search(work,end2,tupleBg,tupleEnd);
8892       if(work!=end2)
8893         {
8894           std::size_t pos(std::distance(bg,work));
8895           if(pos%nbOfCompoExp==0)
8896             ret->pushBackSilent(pos/nbOfCompoExp);
8897           work++;
8898         }
8899     }
8900   return ret.retn();
8901 }
8902
8903 /*!
8904  * Assigns \a newValue to all elements holding \a oldValue within \a this
8905  * one-dimensional array.
8906  *  \param [in] oldValue - the value to replace.
8907  *  \param [in] newValue - the value to assign.
8908  *  \return int - number of replacements performed.
8909  *  \throw If \a this is not allocated.
8910  *  \throw If \a this->getNumberOfComponents() != 1.
8911  */
8912 int DataArrayInt::changeValue(int oldValue, int newValue)
8913 {
8914   checkAllocated();
8915   if(getNumberOfComponents()!=1)
8916     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8917   int *start=getPointer();
8918   int *end2=start+getNbOfElems();
8919   int ret=0;
8920   for(int *val=start;val!=end2;val++)
8921     {
8922       if(*val==oldValue)
8923         {
8924           *val=newValue;
8925           ret++;
8926         }
8927     }
8928   return ret;
8929 }
8930
8931 /*!
8932  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8933  * one of given values.
8934  *  \param [in] valsBg - an array of values to find within \a this array.
8935  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8936  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8937  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8938  *          array using decrRef() as it is no more needed.
8939  *  \throw If \a this->getNumberOfComponents() != 1.
8940  */
8941 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8942 {
8943   if(getNumberOfComponents()!=1)
8944     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8945   std::set<int> vals2(valsBg,valsEnd);
8946   const int *cptr=getConstPointer();
8947   std::vector<int> res;
8948   int nbOfTuples=getNumberOfTuples();
8949   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8950   for(int i=0;i<nbOfTuples;i++,cptr++)
8951     if(vals2.find(*cptr)!=vals2.end())
8952       ret->pushBackSilent(i);
8953   return ret.retn();
8954 }
8955
8956 /*!
8957  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8958  * equal to any of given values.
8959  *  \param [in] valsBg - an array of values to ignore within \a this array.
8960  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8961  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8962  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8963  *          array using decrRef() as it is no more needed.
8964  *  \throw If \a this->getNumberOfComponents() != 1.
8965  */
8966 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8967 {
8968   if(getNumberOfComponents()!=1)
8969     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8970   std::set<int> vals2(valsBg,valsEnd);
8971   const int *cptr=getConstPointer();
8972   std::vector<int> res;
8973   int nbOfTuples=getNumberOfTuples();
8974   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8975   for(int i=0;i<nbOfTuples;i++,cptr++)
8976     if(vals2.find(*cptr)==vals2.end())
8977       ret->pushBackSilent(i);
8978   return ret.retn();
8979 }
8980
8981 /*!
8982  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8983  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8984  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8985  * If any the tuple id is returned. If not -1 is returned.
8986  * 
8987  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8988  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8989  *
8990  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8991  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8992  */
8993 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8994 {
8995   checkAllocated();
8996   int nbOfCompo=getNumberOfComponents();
8997   if(nbOfCompo==0)
8998     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8999   if(nbOfCompo!=(int)tupl.size())
9000     {
9001       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
9002       throw INTERP_KERNEL::Exception(oss.str().c_str());
9003     }
9004   const int *cptr=getConstPointer();
9005   std::size_t nbOfVals=getNbOfElems();
9006   for(const int *work=cptr;work!=cptr+nbOfVals;)
9007     {
9008       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
9009       if(work!=cptr+nbOfVals)
9010         {
9011           if(std::distance(cptr,work)%nbOfCompo!=0)
9012             work++;
9013           else
9014             return std::distance(cptr,work)/nbOfCompo;
9015         }
9016     }
9017   return -1;
9018 }
9019
9020 /*!
9021  * This method searches the sequence specified in input parameter \b vals in \b this.
9022  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
9023  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
9024  * \sa DataArrayInt::locateTuple
9025  */
9026 int DataArrayInt::search(const std::vector<int>& vals) const
9027 {
9028   checkAllocated();
9029   int nbOfCompo=getNumberOfComponents();
9030   if(nbOfCompo!=1)
9031     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
9032   const int *cptr=getConstPointer();
9033   std::size_t nbOfVals=getNbOfElems();
9034   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
9035   if(loc!=cptr+nbOfVals)
9036     return std::distance(cptr,loc);
9037   return -1;
9038 }
9039
9040 /*!
9041  * This method expects to be called when number of components of this is equal to one.
9042  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
9043  * If not any tuple contains \b value -1 is returned.
9044  * \sa DataArrayInt::presenceOfValue
9045  */
9046 int DataArrayInt::locateValue(int value) const
9047 {
9048   checkAllocated();
9049   if(getNumberOfComponents()!=1)
9050     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9051   const int *cptr=getConstPointer();
9052   int nbOfTuples=getNumberOfTuples();
9053   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
9054   if(ret!=cptr+nbOfTuples)
9055     return std::distance(cptr,ret);
9056   return -1;
9057 }
9058
9059 /*!
9060  * This method expects to be called when number of components of this is equal to one.
9061  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
9062  * If not any tuple contains one of the values contained in 'vals' false is returned.
9063  * \sa DataArrayInt::presenceOfValue
9064  */
9065 int DataArrayInt::locateValue(const std::vector<int>& vals) const
9066 {
9067   checkAllocated();
9068   if(getNumberOfComponents()!=1)
9069     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9070   std::set<int> vals2(vals.begin(),vals.end());
9071   const int *cptr=getConstPointer();
9072   int nbOfTuples=getNumberOfTuples();
9073   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
9074     if(vals2.find(*w)!=vals2.end())
9075       return std::distance(cptr,w);
9076   return -1;
9077 }
9078
9079 /*!
9080  * This method returns the number of values in \a this that are equals to input parameter \a value.
9081  * This method only works for single component array.
9082  *
9083  * \return a value in [ 0, \c this->getNumberOfTuples() )
9084  *
9085  * \throw If \a this is not allocated
9086  *
9087  */
9088 int DataArrayInt::count(int value) const
9089 {
9090   int ret=0;
9091   checkAllocated();
9092   if(getNumberOfComponents()!=1)
9093     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
9094   const int *vals=begin();
9095   int nbOfTuples=getNumberOfTuples();
9096   for(int i=0;i<nbOfTuples;i++,vals++)
9097     if(*vals==value)
9098       ret++;
9099   return ret;
9100 }
9101
9102 /*!
9103  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
9104  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9105  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9106  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9107  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9108  * \sa DataArrayInt::locateTuple
9109  */
9110 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
9111 {
9112   return locateTuple(tupl)!=-1;
9113 }
9114
9115
9116 /*!
9117  * Returns \a true if a given value is present within \a this one-dimensional array.
9118  *  \param [in] value - the value to find within \a this array.
9119  *  \return bool - \a true in case if \a value is present within \a this array.
9120  *  \throw If \a this is not allocated.
9121  *  \throw If \a this->getNumberOfComponents() != 1.
9122  *  \sa locateValue()
9123  */
9124 bool DataArrayInt::presenceOfValue(int value) const
9125 {
9126   return locateValue(value)!=-1;
9127 }
9128
9129 /*!
9130  * This method expects to be called when number of components of this is equal to one.
9131  * This method returns true if it exists a tuple so that the value is contained in \b vals.
9132  * If not any tuple contains one of the values contained in 'vals' false is returned.
9133  * \sa DataArrayInt::locateValue
9134  */
9135 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
9136 {
9137   return locateValue(vals)!=-1;
9138 }
9139
9140 /*!
9141  * Accumulates values of each component of \a this array.
9142  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
9143  *         by the caller, that is filled by this method with sum value for each
9144  *         component.
9145  *  \throw If \a this is not allocated.
9146  */
9147 void DataArrayInt::accumulate(int *res) const
9148 {
9149   checkAllocated();
9150   const int *ptr=getConstPointer();
9151   int nbTuple=getNumberOfTuples();
9152   int nbComps=getNumberOfComponents();
9153   std::fill(res,res+nbComps,0);
9154   for(int i=0;i<nbTuple;i++)
9155     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9156 }
9157
9158 int DataArrayInt::accumulate(int compId) const
9159 {
9160   checkAllocated();
9161   const int *ptr=getConstPointer();
9162   int nbTuple=getNumberOfTuples();
9163   int nbComps=getNumberOfComponents();
9164   if(compId<0 || compId>=nbComps)
9165     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9166   int ret=0;
9167   for(int i=0;i<nbTuple;i++)
9168     ret+=ptr[i*nbComps+compId];
9169   return ret;
9170 }
9171
9172 /*!
9173  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9174  * The returned array will have same number of components than \a this and number of tuples equal to
9175  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9176  *
9177  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9178  *
9179  * \param [in] bgOfIndex - begin (included) of the input index array.
9180  * \param [in] endOfIndex - end (excluded) of the input index array.
9181  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9182  * 
9183  * \throw If bgOfIndex or end is NULL.
9184  * \throw If input index array is not ascendingly sorted.
9185  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9186  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9187  */
9188 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9189 {
9190   if(!bgOfIndex || !endOfIndex)
9191     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9192   checkAllocated();
9193   int nbCompo=getNumberOfComponents();
9194   int nbOfTuples=getNumberOfTuples();
9195   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9196   if(sz<1)
9197     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9198   sz--;
9199   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9200   const int *w=bgOfIndex;
9201   if(*w<0 || *w>=nbOfTuples)
9202     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9203   const int *srcPt=begin()+(*w)*nbCompo;
9204   int *tmp=ret->getPointer();
9205   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9206     {
9207       std::fill(tmp,tmp+nbCompo,0);
9208       if(w[1]>=w[0])
9209         {
9210           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9211             {
9212               if(j>=0 && j<nbOfTuples)
9213                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9214               else
9215                 {
9216                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9217                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9218                 }
9219             }
9220         }
9221       else
9222         {
9223           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9224           throw INTERP_KERNEL::Exception(oss.str().c_str());
9225         }
9226     }
9227   ret->copyStringInfoFrom(*this);
9228   return ret.retn();
9229 }
9230
9231 /*!
9232  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9233  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9234  * offsetA2</em> and (2)
9235  * the number of component in the result array is same as that of each of given arrays.
9236  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9237  * Info on components is copied from the first of the given arrays. Number of components
9238  * in the given arrays must be the same.
9239  *  \param [in] a1 - an array to include in the result array.
9240  *  \param [in] a2 - another array to include in the result array.
9241  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9242  *  \return DataArrayInt * - the new instance of DataArrayInt.
9243  *          The caller is to delete this result array using decrRef() as it is no more
9244  *          needed.
9245  *  \throw If either \a a1 or \a a2 is NULL.
9246  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9247  */
9248 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9249 {
9250   if(!a1 || !a2)
9251     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9252   int nbOfComp=a1->getNumberOfComponents();
9253   if(nbOfComp!=a2->getNumberOfComponents())
9254     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9255   int nbOfTuple1=a1->getNumberOfTuples();
9256   int nbOfTuple2=a2->getNumberOfTuples();
9257   DataArrayInt *ret=DataArrayInt::New();
9258   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9259   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9260   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9261   ret->copyStringInfoFrom(*a1);
9262   return ret;
9263 }
9264
9265 /*!
9266  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9267  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9268  * the number of component in the result array is same as that of each of given arrays.
9269  * Info on components is copied from the first of the given arrays. Number of components
9270  * in the given arrays must be  the same.
9271  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9272  * not the object itself.
9273  *  \param [in] arr - a sequence of arrays to include in the result array.
9274  *  \return DataArrayInt * - the new instance of DataArrayInt.
9275  *          The caller is to delete this result array using decrRef() as it is no more
9276  *          needed.
9277  *  \throw If all arrays within \a arr are NULL.
9278  *  \throw If getNumberOfComponents() of arrays within \a arr.
9279  */
9280 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9281 {
9282   std::vector<const DataArrayInt *> a;
9283   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9284     if(*it4)
9285       a.push_back(*it4);
9286   if(a.empty())
9287     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9288   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9289   int nbOfComp=(*it)->getNumberOfComponents();
9290   int nbt=(*it++)->getNumberOfTuples();
9291   for(int i=1;it!=a.end();it++,i++)
9292     {
9293       if((*it)->getNumberOfComponents()!=nbOfComp)
9294         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9295       nbt+=(*it)->getNumberOfTuples();
9296     }
9297   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9298   ret->alloc(nbt,nbOfComp);
9299   int *pt=ret->getPointer();
9300   for(it=a.begin();it!=a.end();it++)
9301     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9302   ret->copyStringInfoFrom(*(a[0]));
9303   return ret.retn();
9304 }
9305
9306 /*!
9307  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9308  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9309  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9310  * 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.
9311  * 
9312  * \return DataArrayInt * - a new object to be managed by the caller.
9313  */
9314 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9315 {
9316   int retSz=1;
9317   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9318     {
9319       if(*it4)
9320         {
9321           (*it4)->checkAllocated();
9322           if((*it4)->getNumberOfComponents()!=1)
9323             {
9324               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9325               throw INTERP_KERNEL::Exception(oss.str().c_str());
9326             }
9327           int nbTupl=(*it4)->getNumberOfTuples();
9328           if(nbTupl<1)
9329             {
9330               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9331               throw INTERP_KERNEL::Exception(oss.str().c_str());
9332             }
9333           if((*it4)->front()!=0)
9334             {
9335               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9336               throw INTERP_KERNEL::Exception(oss.str().c_str());
9337             }
9338           retSz+=nbTupl-1;
9339         }
9340       else
9341         {
9342           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9343           throw INTERP_KERNEL::Exception(oss.str().c_str());
9344         }
9345     }
9346   if(arrs.empty())
9347     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9348   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9349   ret->alloc(retSz,1);
9350   int *pt=ret->getPointer(); *pt++=0;
9351   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9352     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9353   ret->copyStringInfoFrom(*(arrs[0]));
9354   return ret.retn();
9355 }
9356
9357 /*!
9358  * Returns the maximal value and its location within \a this one-dimensional array.
9359  *  \param [out] tupleId - index of the tuple holding the maximal value.
9360  *  \return int - the maximal value among all values of \a this array.
9361  *  \throw If \a this->getNumberOfComponents() != 1
9362  *  \throw If \a this->getNumberOfTuples() < 1
9363  */
9364 int DataArrayInt::getMaxValue(int& tupleId) const
9365 {
9366   checkAllocated();
9367   if(getNumberOfComponents()!=1)
9368     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9369   int nbOfTuples=getNumberOfTuples();
9370   if(nbOfTuples<=0)
9371     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9372   const int *vals=getConstPointer();
9373   const int *loc=std::max_element(vals,vals+nbOfTuples);
9374   tupleId=(int)std::distance(vals,loc);
9375   return *loc;
9376 }
9377
9378 /*!
9379  * Returns the maximal value within \a this array that is allowed to have more than
9380  *  one component.
9381  *  \return int - the maximal value among all values of \a this array.
9382  *  \throw If \a this is not allocated.
9383  */
9384 int DataArrayInt::getMaxValueInArray() const
9385 {
9386   checkAllocated();
9387   const int *loc=std::max_element(begin(),end());
9388   return *loc;
9389 }
9390
9391 /*!
9392  * Returns the minimal value and its location within \a this one-dimensional array.
9393  *  \param [out] tupleId - index of the tuple holding the minimal value.
9394  *  \return int - the minimal value among all values of \a this array.
9395  *  \throw If \a this->getNumberOfComponents() != 1
9396  *  \throw If \a this->getNumberOfTuples() < 1
9397  */
9398 int DataArrayInt::getMinValue(int& tupleId) const
9399 {
9400   checkAllocated();
9401   if(getNumberOfComponents()!=1)
9402     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9403   int nbOfTuples=getNumberOfTuples();
9404   if(nbOfTuples<=0)
9405     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9406   const int *vals=getConstPointer();
9407   const int *loc=std::min_element(vals,vals+nbOfTuples);
9408   tupleId=(int)std::distance(vals,loc);
9409   return *loc;
9410 }
9411
9412 /*!
9413  * Returns the minimal value within \a this array that is allowed to have more than
9414  *  one component.
9415  *  \return int - the minimal value among all values of \a this array.
9416  *  \throw If \a this is not allocated.
9417  */
9418 int DataArrayInt::getMinValueInArray() const
9419 {
9420   checkAllocated();
9421   const int *loc=std::min_element(begin(),end());
9422   return *loc;
9423 }
9424
9425 /*!
9426  * Returns in a single walk in \a this the min value and the max value in \a this.
9427  * \a this is expected to be single component array.
9428  *
9429  * \param [out] minValue - the min value in \a this.
9430  * \param [out] maxValue - the max value in \a this.
9431  *
9432  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9433  */
9434 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9435 {
9436   checkAllocated();
9437   if(getNumberOfComponents()!=1)
9438     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9439   int nbTuples(getNumberOfTuples());
9440   const int *pt(begin());
9441   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9442   for(int i=0;i<nbTuples;i++,pt++)
9443     {
9444       if(*pt<minValue)
9445         minValue=*pt;
9446       if(*pt>maxValue)
9447         maxValue=*pt;
9448     }
9449 }
9450
9451 /*!
9452  * Converts every value of \a this array to its absolute value.
9453  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9454  * should be called instead.
9455  *
9456  * \throw If \a this is not allocated.
9457  * \sa DataArrayInt::computeAbs
9458  */
9459 void DataArrayInt::abs()
9460 {
9461   checkAllocated();
9462   int *ptr(getPointer());
9463   std::size_t nbOfElems(getNbOfElems());
9464   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9465   declareAsNew();
9466 }
9467
9468 /*!
9469  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9470  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9471  *
9472  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9473  *         same number of tuples and component as \a this array.
9474  *         The caller is to delete this result array using decrRef() as it is no more
9475  *         needed.
9476  * \throw If \a this is not allocated.
9477  * \sa DataArrayInt::abs
9478  */
9479 DataArrayInt *DataArrayInt::computeAbs() const
9480 {
9481   checkAllocated();
9482   DataArrayInt *newArr(DataArrayInt::New());
9483   int nbOfTuples(getNumberOfTuples());
9484   int nbOfComp(getNumberOfComponents());
9485   newArr->alloc(nbOfTuples,nbOfComp);
9486   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9487   newArr->copyStringInfoFrom(*this);
9488   return newArr;
9489 }
9490
9491 /*!
9492  * Apply a liner function to a given component of \a this array, so that
9493  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9494  *  \param [in] a - the first coefficient of the function.
9495  *  \param [in] b - the second coefficient of the function.
9496  *  \param [in] compoId - the index of component to modify.
9497  *  \throw If \a this is not allocated.
9498  */
9499 void DataArrayInt::applyLin(int a, int b, int compoId)
9500 {
9501   checkAllocated();
9502   int *ptr=getPointer()+compoId;
9503   int nbOfComp=getNumberOfComponents();
9504   int nbOfTuple=getNumberOfTuples();
9505   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9506     *ptr=a*(*ptr)+b;
9507   declareAsNew();
9508 }
9509
9510 /*!
9511  * Apply a liner function to all elements of \a this array, so that
9512  * an element _x_ becomes \f$ a * x + b \f$.
9513  *  \param [in] a - the first coefficient of the function.
9514  *  \param [in] b - the second coefficient of the function.
9515  *  \throw If \a this is not allocated.
9516  */
9517 void DataArrayInt::applyLin(int a, int b)
9518 {
9519   checkAllocated();
9520   int *ptr=getPointer();
9521   std::size_t nbOfElems=getNbOfElems();
9522   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9523     *ptr=a*(*ptr)+b;
9524   declareAsNew();
9525 }
9526
9527 /*!
9528  * Returns a full copy of \a this array except that sign of all elements is reversed.
9529  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9530  *          same number of tuples and component as \a this array.
9531  *          The caller is to delete this result array using decrRef() as it is no more
9532  *          needed.
9533  *  \throw If \a this is not allocated.
9534  */
9535 DataArrayInt *DataArrayInt::negate() const
9536 {
9537   checkAllocated();
9538   DataArrayInt *newArr=DataArrayInt::New();
9539   int nbOfTuples=getNumberOfTuples();
9540   int nbOfComp=getNumberOfComponents();
9541   newArr->alloc(nbOfTuples,nbOfComp);
9542   const int *cptr=getConstPointer();
9543   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9544   newArr->copyStringInfoFrom(*this);
9545   return newArr;
9546 }
9547
9548 /*!
9549  * Modify all elements of \a this array, so that
9550  * an element _x_ becomes \f$ numerator / x \f$.
9551  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9552  *           array, all elements processed before detection of the zero element remain
9553  *           modified.
9554  *  \param [in] numerator - the numerator used to modify array elements.
9555  *  \throw If \a this is not allocated.
9556  *  \throw If there is an element equal to 0 in \a this array.
9557  */
9558 void DataArrayInt::applyInv(int numerator)
9559 {
9560   checkAllocated();
9561   int *ptr=getPointer();
9562   std::size_t nbOfElems=getNbOfElems();
9563   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9564     {
9565       if(*ptr!=0)
9566         {
9567           *ptr=numerator/(*ptr);
9568         }
9569       else
9570         {
9571           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9572           oss << " !";
9573           throw INTERP_KERNEL::Exception(oss.str().c_str());
9574         }
9575     }
9576   declareAsNew();
9577 }
9578
9579 /*!
9580  * Modify all elements of \a this array, so that
9581  * an element _x_ becomes \f$ x / val \f$.
9582  *  \param [in] val - the denominator used to modify array elements.
9583  *  \throw If \a this is not allocated.
9584  *  \throw If \a val == 0.
9585  */
9586 void DataArrayInt::applyDivideBy(int val)
9587 {
9588   if(val==0)
9589     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9590   checkAllocated();
9591   int *ptr=getPointer();
9592   std::size_t nbOfElems=getNbOfElems();
9593   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9594   declareAsNew();
9595 }
9596
9597 /*!
9598  * Modify all elements of \a this array, so that
9599  * an element _x_ becomes  <em> x % val </em>.
9600  *  \param [in] val - the divisor used to modify array elements.
9601  *  \throw If \a this is not allocated.
9602  *  \throw If \a val <= 0.
9603  */
9604 void DataArrayInt::applyModulus(int val)
9605 {
9606   if(val<=0)
9607     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9608   checkAllocated();
9609   int *ptr=getPointer();
9610   std::size_t nbOfElems=getNbOfElems();
9611   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9612   declareAsNew();
9613 }
9614
9615 /*!
9616  * This method works only on data array with one component.
9617  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9618  * this[*id] in [\b vmin,\b vmax)
9619  * 
9620  * \param [in] vmin begin of range. This value is included in range (included).
9621  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9622  * \return a newly allocated data array that the caller should deal with.
9623  *
9624  * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative
9625  */
9626 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9627 {
9628   checkAllocated();
9629   if(getNumberOfComponents()!=1)
9630     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9631   const int *cptr(begin());
9632   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9633   int nbOfTuples(getNumberOfTuples());
9634   for(int i=0;i<nbOfTuples;i++,cptr++)
9635     if(*cptr>=vmin && *cptr<vmax)
9636       ret->pushBackSilent(i);
9637   return ret.retn();
9638 }
9639
9640 /*!
9641  * This method works only on data array with one component.
9642  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9643  * this[*id] \b not in [\b vmin,\b vmax)
9644  * 
9645  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9646  * \param [in] vmax end of range. This value is included in range (included).
9647  * \return a newly allocated data array that the caller should deal with.
9648  * 
9649  * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative
9650  */
9651 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9652 {
9653   checkAllocated();
9654   if(getNumberOfComponents()!=1)
9655     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9656   const int *cptr(getConstPointer());
9657   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9658   int nbOfTuples(getNumberOfTuples());
9659   for(int i=0;i<nbOfTuples;i++,cptr++)
9660     if(*cptr<vmin || *cptr>=vmax)
9661       ret->pushBackSilent(i);
9662   return ret.retn();
9663 }
9664
9665 /*!
9666  * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
9667  *
9668  * \return a newly allocated data array that the caller should deal with.
9669  * \sa DataArrayInt::getIdsInRange
9670  */
9671 DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const
9672 {
9673   checkAllocated();
9674   if(getNumberOfComponents()!=1)
9675     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !");
9676   const int *cptr(getConstPointer());
9677   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9678   int nbOfTuples(getNumberOfTuples());
9679   for(int i=0;i<nbOfTuples;i++,cptr++)
9680     if(*cptr<0)
9681       ret->pushBackSilent(i);
9682   return ret.retn();
9683 }
9684
9685 /*!
9686  * This method works only on data array with one component.
9687  * 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.
9688  * 
9689  * \param [in] vmin begin of range. This value is included in range (included).
9690  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9691  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9692 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9693 {
9694   checkAllocated();
9695   if(getNumberOfComponents()!=1)
9696     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9697   int nbOfTuples=getNumberOfTuples();
9698   bool ret=true;
9699   const int *cptr=getConstPointer();
9700   for(int i=0;i<nbOfTuples;i++,cptr++)
9701     {
9702       if(*cptr>=vmin && *cptr<vmax)
9703         { ret=ret && *cptr==i; }
9704       else
9705         {
9706           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9707           throw INTERP_KERNEL::Exception(oss.str().c_str());
9708         }
9709     }
9710   return ret;
9711 }
9712
9713 /*!
9714  * Modify all elements of \a this array, so that
9715  * an element _x_ becomes <em> val % x </em>.
9716  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9717  *           array, all elements processed before detection of the zero element remain
9718  *           modified.
9719  *  \param [in] val - the divident used to modify array elements.
9720  *  \throw If \a this is not allocated.
9721  *  \throw If there is an element equal to or less than 0 in \a this array.
9722  */
9723 void DataArrayInt::applyRModulus(int val)
9724 {
9725   checkAllocated();
9726   int *ptr=getPointer();
9727   std::size_t nbOfElems=getNbOfElems();
9728   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9729     {
9730       if(*ptr>0)
9731         {
9732           *ptr=val%(*ptr);
9733         }
9734       else
9735         {
9736           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9737           oss << " !";
9738           throw INTERP_KERNEL::Exception(oss.str().c_str());
9739         }
9740     }
9741   declareAsNew();
9742 }
9743
9744 /*!
9745  * Modify all elements of \a this array, so that
9746  * an element _x_ becomes <em> val ^ x </em>.
9747  *  \param [in] val - the value used to apply pow on all array elements.
9748  *  \throw If \a this is not allocated.
9749  *  \throw If \a val < 0.
9750  */
9751 void DataArrayInt::applyPow(int val)
9752 {
9753   checkAllocated();
9754   if(val<0)
9755     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9756   int *ptr=getPointer();
9757   std::size_t nbOfElems=getNbOfElems();
9758   if(val==0)
9759     {
9760       std::fill(ptr,ptr+nbOfElems,1);
9761       return ;
9762     }
9763   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9764     {
9765       int tmp=1;
9766       for(int j=0;j<val;j++)
9767         tmp*=*ptr;
9768       *ptr=tmp;
9769     }
9770   declareAsNew();
9771 }
9772
9773 /*!
9774  * Modify all elements of \a this array, so that
9775  * an element _x_ becomes \f$ val ^ x \f$.
9776  *  \param [in] val - the value used to apply pow on all array elements.
9777  *  \throw If \a this is not allocated.
9778  *  \throw If there is an element < 0 in \a this array.
9779  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9780  *           array, all elements processed before detection of the zero element remain
9781  *           modified.
9782  */
9783 void DataArrayInt::applyRPow(int val)
9784 {
9785   checkAllocated();
9786   int *ptr=getPointer();
9787   std::size_t nbOfElems=getNbOfElems();
9788   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9789     {
9790       if(*ptr>=0)
9791         {
9792           int tmp=1;
9793           for(int j=0;j<*ptr;j++)
9794             tmp*=val;
9795           *ptr=tmp;
9796         }
9797       else
9798         {
9799           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9800           oss << " !";
9801           throw INTERP_KERNEL::Exception(oss.str().c_str());
9802         }
9803     }
9804   declareAsNew();
9805 }
9806
9807 /*!
9808  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9809  * of components in the result array is a sum of the number of components of given arrays
9810  * and (2) the number of tuples in the result array is same as that of each of given
9811  * arrays. In other words the i-th tuple of result array includes all components of
9812  * i-th tuples of all given arrays.
9813  * Number of tuples in the given arrays must be the same.
9814  *  \param [in] a1 - an array to include in the result array.
9815  *  \param [in] a2 - another array to include in the result array.
9816  *  \return DataArrayInt * - the new instance of DataArrayInt.
9817  *          The caller is to delete this result array using decrRef() as it is no more
9818  *          needed.
9819  *  \throw If both \a a1 and \a a2 are NULL.
9820  *  \throw If any given array is not allocated.
9821  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9822  */
9823 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9824 {
9825   std::vector<const DataArrayInt *> arr(2);
9826   arr[0]=a1; arr[1]=a2;
9827   return Meld(arr);
9828 }
9829
9830 /*!
9831  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9832  * of components in the result array is a sum of the number of components of given arrays
9833  * and (2) the number of tuples in the result array is same as that of each of given
9834  * arrays. In other words the i-th tuple of result array includes all components of
9835  * i-th tuples of all given arrays.
9836  * Number of tuples in the given arrays must be  the same.
9837  *  \param [in] arr - a sequence of arrays to include in the result array.
9838  *  \return DataArrayInt * - the new instance of DataArrayInt.
9839  *          The caller is to delete this result array using decrRef() as it is no more
9840  *          needed.
9841  *  \throw If all arrays within \a arr are NULL.
9842  *  \throw If any given array is not allocated.
9843  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9844  */
9845 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9846 {
9847   std::vector<const DataArrayInt *> a;
9848   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9849     if(*it4)
9850       a.push_back(*it4);
9851   if(a.empty())
9852     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9853   std::vector<const DataArrayInt *>::const_iterator it;
9854   for(it=a.begin();it!=a.end();it++)
9855     (*it)->checkAllocated();
9856   it=a.begin();
9857   int nbOfTuples=(*it)->getNumberOfTuples();
9858   std::vector<int> nbc(a.size());
9859   std::vector<const int *> pts(a.size());
9860   nbc[0]=(*it)->getNumberOfComponents();
9861   pts[0]=(*it++)->getConstPointer();
9862   for(int i=1;it!=a.end();it++,i++)
9863     {
9864       if(nbOfTuples!=(*it)->getNumberOfTuples())
9865         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9866       nbc[i]=(*it)->getNumberOfComponents();
9867       pts[i]=(*it)->getConstPointer();
9868     }
9869   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9870   DataArrayInt *ret=DataArrayInt::New();
9871   ret->alloc(nbOfTuples,totalNbOfComp);
9872   int *retPtr=ret->getPointer();
9873   for(int i=0;i<nbOfTuples;i++)
9874     for(int j=0;j<(int)a.size();j++)
9875       {
9876         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9877         pts[j]+=nbc[j];
9878       }
9879   int k=0;
9880   for(int i=0;i<(int)a.size();i++)
9881     for(int j=0;j<nbc[i];j++,k++)
9882       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9883   return ret;
9884 }
9885
9886 /*!
9887  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9888  * The i-th item of the result array is an ID of a set of elements belonging to a
9889  * unique set of groups, which the i-th element is a part of. This set of elements
9890  * belonging to a unique set of groups is called \a family, so the result array contains
9891  * IDs of families each element belongs to.
9892  *
9893  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9894  * then there are 3 families:
9895  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9896  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9897  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9898  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9899  * stands for the element #3 which is in none of groups.
9900  *
9901  *  \param [in] groups - sequence of groups of element IDs.
9902  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9903  *         in \a groups.
9904  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9905  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9906  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9907  *         delete this array using decrRef() as it is no more needed.
9908  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9909  */
9910 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9911 {
9912   std::vector<const DataArrayInt *> groups2;
9913   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9914     if(*it4)
9915       groups2.push_back(*it4);
9916   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9917   ret->alloc(newNb,1);
9918   int *retPtr=ret->getPointer();
9919   std::fill(retPtr,retPtr+newNb,0);
9920   int fid=1;
9921   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9922     {
9923       const int *ptr=(*iter)->getConstPointer();
9924       std::size_t nbOfElem=(*iter)->getNbOfElems();
9925       int sfid=fid;
9926       for(int j=0;j<sfid;j++)
9927         {
9928           bool found=false;
9929           for(std::size_t i=0;i<nbOfElem;i++)
9930             {
9931               if(ptr[i]>=0 && ptr[i]<newNb)
9932                 {
9933                   if(retPtr[ptr[i]]==j)
9934                     {
9935                       retPtr[ptr[i]]=fid;
9936                       found=true;
9937                     }
9938                 }
9939               else
9940                 {
9941                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9942                   oss << ") !";
9943                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9944                 }
9945             }
9946           if(found)
9947             fid++;
9948         }
9949     }
9950   fidsOfGroups.clear();
9951   fidsOfGroups.resize(groups2.size());
9952   int grId=0;
9953   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9954     {
9955       std::set<int> tmp;
9956       const int *ptr=(*iter)->getConstPointer();
9957       std::size_t nbOfElem=(*iter)->getNbOfElems();
9958       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9959         tmp.insert(retPtr[*p]);
9960       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9961     }
9962   return ret.retn();
9963 }
9964
9965 /*!
9966  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9967  * arrays. The result array does not contain any duplicates and its values
9968  * are sorted in ascending order.
9969  *  \param [in] arr - sequence of DataArrayInt's to unite.
9970  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9971  *         array using decrRef() as it is no more needed.
9972  *  \throw If any \a arr[i] is not allocated.
9973  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9974  */
9975 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9976 {
9977   std::vector<const DataArrayInt *> a;
9978   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9979     if(*it4)
9980       a.push_back(*it4);
9981   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9982     {
9983       (*it)->checkAllocated();
9984       if((*it)->getNumberOfComponents()!=1)
9985         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9986     }
9987   //
9988   std::set<int> r;
9989   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9990     {
9991       const int *pt=(*it)->getConstPointer();
9992       int nbOfTuples=(*it)->getNumberOfTuples();
9993       r.insert(pt,pt+nbOfTuples);
9994     }
9995   DataArrayInt *ret=DataArrayInt::New();
9996   ret->alloc((int)r.size(),1);
9997   std::copy(r.begin(),r.end(),ret->getPointer());
9998   return ret;
9999 }
10000
10001 /*!
10002  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
10003  * arrays. The result array does not contain any duplicates and its values
10004  * are sorted in ascending order.
10005  *  \param [in] arr - sequence of DataArrayInt's to intersect.
10006  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10007  *         array using decrRef() as it is no more needed.
10008  *  \throw If any \a arr[i] is not allocated.
10009  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
10010  */
10011 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
10012 {
10013   std::vector<const DataArrayInt *> a;
10014   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
10015     if(*it4)
10016       a.push_back(*it4);
10017   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10018     {
10019       (*it)->checkAllocated();
10020       if((*it)->getNumberOfComponents()!=1)
10021         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
10022     }
10023   //
10024   std::set<int> r;
10025   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10026     {
10027       const int *pt=(*it)->getConstPointer();
10028       int nbOfTuples=(*it)->getNumberOfTuples();
10029       std::set<int> s1(pt,pt+nbOfTuples);
10030       if(it!=a.begin())
10031         {
10032           std::set<int> r2;
10033           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
10034           r=r2;
10035         }
10036       else
10037         r=s1;
10038     }
10039   DataArrayInt *ret(DataArrayInt::New());
10040   ret->alloc((int)r.size(),1);
10041   std::copy(r.begin(),r.end(),ret->getPointer());
10042   return ret;
10043 }
10044
10045 /// @cond INTERNAL
10046 namespace ParaMEDMEMImpl
10047 {
10048   class OpSwitchedOn
10049   {
10050   public:
10051     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
10052     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
10053   private:
10054     int *_pt;
10055     int _cnt;
10056   };
10057
10058   class OpSwitchedOff
10059   {
10060   public:
10061     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
10062     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
10063   private:
10064     int *_pt;
10065     int _cnt;
10066   };
10067 }
10068 /// @endcond
10069
10070 /*!
10071  * This method returns the list of ids in ascending mode so that v[id]==true.
10072  */
10073 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
10074 {
10075   int sz((int)std::count(v.begin(),v.end(),true));
10076   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10077   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
10078   return ret.retn();
10079 }
10080
10081 /*!
10082  * This method returns the list of ids in ascending mode so that v[id]==false.
10083  */
10084 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
10085 {
10086   int sz((int)std::count(v.begin(),v.end(),false));
10087   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10088   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
10089   return ret.retn();
10090 }
10091
10092 /*!
10093  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
10094  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
10095  *
10096  * \param [in] v the input data structure to be translate into skyline format.
10097  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
10098  * \param [out] dataIndex the second element of the skyline format.
10099  */
10100 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
10101 {
10102   int sz((int)v.size());
10103   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
10104   ret1->alloc(sz+1,1);
10105   int *pt(ret1->getPointer()); *pt=0;
10106   for(int i=0;i<sz;i++,pt++)
10107     pt[1]=pt[0]+(int)v[i].size();
10108   ret0->alloc(ret1->back(),1);
10109   pt=ret0->getPointer();
10110   for(int i=0;i<sz;i++)
10111     pt=std::copy(v[i].begin(),v[i].end(),pt);
10112   data=ret0.retn(); dataIndex=ret1.retn();
10113 }
10114
10115 /*!
10116  * Returns a new DataArrayInt which contains a complement of elements of \a this
10117  * one-dimensional array. I.e. the result array contains all elements from the range [0,
10118  * \a nbOfElement) not present in \a this array.
10119  *  \param [in] nbOfElement - maximal size of the result array.
10120  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10121  *         array using decrRef() as it is no more needed.
10122  *  \throw If \a this is not allocated.
10123  *  \throw If \a this->getNumberOfComponents() != 1.
10124  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
10125  *         nbOfElement ).
10126  */
10127 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
10128 {
10129   checkAllocated();
10130   if(getNumberOfComponents()!=1)
10131     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
10132   std::vector<bool> tmp(nbOfElement);
10133   const int *pt=getConstPointer();
10134   int nbOfTuples=getNumberOfTuples();
10135   for(const int *w=pt;w!=pt+nbOfTuples;w++)
10136     if(*w>=0 && *w<nbOfElement)
10137       tmp[*w]=true;
10138     else
10139       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
10140   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
10141   DataArrayInt *ret=DataArrayInt::New();
10142   ret->alloc(nbOfRetVal,1);
10143   int j=0;
10144   int *retPtr=ret->getPointer();
10145   for(int i=0;i<nbOfElement;i++)
10146     if(!tmp[i])
10147       retPtr[j++]=i;
10148   return ret;
10149 }
10150
10151 /*!
10152  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10153  * from an \a other one-dimensional array.
10154  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10155  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10156  *         caller is to delete this array using decrRef() as it is no more needed.
10157  *  \throw If \a other is NULL.
10158  *  \throw If \a other is not allocated.
10159  *  \throw If \a other->getNumberOfComponents() != 1.
10160  *  \throw If \a this is not allocated.
10161  *  \throw If \a this->getNumberOfComponents() != 1.
10162  *  \sa DataArrayInt::buildSubstractionOptimized()
10163  */
10164 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10165 {
10166   if(!other)
10167     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10168   checkAllocated();
10169   other->checkAllocated();
10170   if(getNumberOfComponents()!=1)
10171     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10172   if(other->getNumberOfComponents()!=1)
10173     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10174   const int *pt=getConstPointer();
10175   int nbOfTuples=getNumberOfTuples();
10176   std::set<int> s1(pt,pt+nbOfTuples);
10177   pt=other->getConstPointer();
10178   nbOfTuples=other->getNumberOfTuples();
10179   std::set<int> s2(pt,pt+nbOfTuples);
10180   std::vector<int> r;
10181   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10182   DataArrayInt *ret=DataArrayInt::New();
10183   ret->alloc((int)r.size(),1);
10184   std::copy(r.begin(),r.end(),ret->getPointer());
10185   return ret;
10186 }
10187
10188 /*!
10189  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10190  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10191  * 
10192  * \param [in] other an array with one component and expected to be sorted ascendingly.
10193  * \ret list of ids in \a this but not in \a other.
10194  * \sa DataArrayInt::buildSubstraction
10195  */
10196 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10197 {
10198   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10199   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10200   checkAllocated(); other->checkAllocated();
10201   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10202   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10203   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10204   const int *work1(pt1Bg),*work2(pt2Bg);
10205   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10206   for(;work1!=pt1End;work1++)
10207     {
10208       if(work2!=pt2End && *work1==*work2)
10209         work2++;
10210       else
10211         ret->pushBackSilent(*work1);
10212     }
10213   return ret.retn();
10214 }
10215
10216
10217 /*!
10218  * Returns a new DataArrayInt which contains all elements of \a this and a given
10219  * one-dimensional arrays. The result array does not contain any duplicates
10220  * and its values are sorted in ascending order.
10221  *  \param [in] other - an array to unite with \a this one.
10222  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10223  *         array using decrRef() as it is no more needed.
10224  *  \throw If \a this or \a other is not allocated.
10225  *  \throw If \a this->getNumberOfComponents() != 1.
10226  *  \throw If \a other->getNumberOfComponents() != 1.
10227  */
10228 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10229 {
10230   std::vector<const DataArrayInt *>arrs(2);
10231   arrs[0]=this; arrs[1]=other;
10232   return BuildUnion(arrs);
10233 }
10234
10235
10236 /*!
10237  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10238  * one-dimensional arrays. The result array does not contain any duplicates
10239  * and its values are sorted in ascending order.
10240  *  \param [in] other - an array to intersect with \a this one.
10241  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10242  *         array using decrRef() as it is no more needed.
10243  *  \throw If \a this or \a other is not allocated.
10244  *  \throw If \a this->getNumberOfComponents() != 1.
10245  *  \throw If \a other->getNumberOfComponents() != 1.
10246  */
10247 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10248 {
10249   std::vector<const DataArrayInt *>arrs(2);
10250   arrs[0]=this; arrs[1]=other;
10251   return BuildIntersection(arrs);
10252 }
10253
10254 /*!
10255  * This method can be applied on allocated with one component DataArrayInt instance.
10256  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10257  * 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]
10258  * 
10259  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10260  * \throw if \a this is not allocated or if \a this has not exactly one component.
10261  * \sa DataArrayInt::buildUniqueNotSorted
10262  */
10263 DataArrayInt *DataArrayInt::buildUnique() const
10264 {
10265   checkAllocated();
10266   if(getNumberOfComponents()!=1)
10267     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10268   int nbOfTuples=getNumberOfTuples();
10269   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
10270   int *data=tmp->getPointer();
10271   int *last=std::unique(data,data+nbOfTuples);
10272   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10273   ret->alloc(std::distance(data,last),1);
10274   std::copy(data,last,ret->getPointer());
10275   return ret.retn();
10276 }
10277
10278 /*!
10279  * This method can be applied on allocated with one component DataArrayInt instance.
10280  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10281  *
10282  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10283  *
10284  * \throw if \a this is not allocated or if \a this has not exactly one component.
10285  *
10286  * \sa DataArrayInt::buildUnique
10287  */
10288 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10289 {
10290   checkAllocated();
10291     if(getNumberOfComponents()!=1)
10292       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10293   int minVal,maxVal;
10294   getMinMaxValues(minVal,maxVal);
10295   std::vector<bool> b(maxVal-minVal+1,false);
10296   const int *ptBg(begin()),*endBg(end());
10297   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10298   for(const int *pt=ptBg;pt!=endBg;pt++)
10299     {
10300       if(!b[*pt-minVal])
10301         {
10302           ret->pushBackSilent(*pt);
10303           b[*pt-minVal]=true;
10304         }
10305     }
10306   ret->copyStringInfoFrom(*this);
10307   return ret.retn();
10308 }
10309
10310 /*!
10311  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10312  * "index" array. Such "index" array is returned for example by 
10313  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
10314  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10315  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
10316  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10317  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
10318  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10319  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10320  *          The caller is to delete this array using decrRef() as it is no more needed. 
10321  *  \throw If \a this is not allocated.
10322  *  \throw If \a this->getNumberOfComponents() != 1.
10323  *  \throw If \a this->getNumberOfTuples() < 2.
10324  *
10325  *  \b Example: <br> 
10326  *         - this contains [1,3,6,7,7,9,15]
10327  *         - result array contains [2,3,1,0,2,6],
10328  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10329  *
10330  * \sa DataArrayInt::computeOffsets2
10331  */
10332 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10333 {
10334   checkAllocated();
10335   if(getNumberOfComponents()!=1)
10336     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10337   int nbOfTuples=getNumberOfTuples();
10338   if(nbOfTuples<2)
10339     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10340   const int *ptr=getConstPointer();
10341   DataArrayInt *ret=DataArrayInt::New();
10342   ret->alloc(nbOfTuples-1,1);
10343   int *out=ret->getPointer();
10344   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10345   return ret;
10346 }
10347
10348 /*!
10349  * Modifies \a this one-dimensional array so that value of each element \a x
10350  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10351  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10352  * and components remains the same.<br>
10353  * This method is useful for allToAllV in MPI with contiguous policy. This method
10354  * differs from computeOffsets2() in that the number of tuples is \b not changed by
10355  * this one.
10356  *  \throw If \a this is not allocated.
10357  *  \throw If \a this->getNumberOfComponents() != 1.
10358  *
10359  *  \b Example: <br>
10360  *          - Before \a this contains [3,5,1,2,0,8]
10361  *          - After \a this contains  [0,3,8,9,11,11]<br>
10362  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10363  *          array is retained and thus there is no space to store the last element.
10364  */
10365 void DataArrayInt::computeOffsets()
10366 {
10367   checkAllocated();
10368   if(getNumberOfComponents()!=1)
10369     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10370   int nbOfTuples=getNumberOfTuples();
10371   if(nbOfTuples==0)
10372     return ;
10373   int *work=getPointer();
10374   int tmp=work[0];
10375   work[0]=0;
10376   for(int i=1;i<nbOfTuples;i++)
10377     {
10378       int tmp2=work[i];
10379       work[i]=work[i-1]+tmp;
10380       tmp=tmp2;
10381     }
10382   declareAsNew();
10383 }
10384
10385
10386 /*!
10387  * Modifies \a this one-dimensional array so that value of each element \a x
10388  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10389  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10390  * components remains the same and number of tuples is inceamented by one.<br>
10391  * This method is useful for allToAllV in MPI with contiguous policy. This method
10392  * differs from computeOffsets() in that the number of tuples is changed by this one.
10393  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10394  *  \throw If \a this is not allocated.
10395  *  \throw If \a this->getNumberOfComponents() != 1.
10396  *
10397  *  \b Example: <br>
10398  *          - Before \a this contains [3,5,1,2,0,8]
10399  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10400  * \sa DataArrayInt::deltaShiftIndex
10401  */
10402 void DataArrayInt::computeOffsets2()
10403 {
10404   checkAllocated();
10405   if(getNumberOfComponents()!=1)
10406     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
10407   int nbOfTuples=getNumberOfTuples();
10408   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10409   const int *work=getConstPointer();
10410   ret[0]=0;
10411   for(int i=0;i<nbOfTuples;i++)
10412     ret[i+1]=work[i]+ret[i];
10413   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10414   declareAsNew();
10415 }
10416
10417 /*!
10418  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10419  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10420  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10421  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10422  * filling completely one of the ranges in \a this.
10423  *
10424  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10425  * \param [out] rangeIdsFetched the range ids fetched
10426  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10427  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10428  *
10429  * \sa DataArrayInt::computeOffsets2
10430  *
10431  *  \b Example: <br>
10432  *          - \a this : [0,3,7,9,15,18]
10433  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10434  *          - \a rangeIdsFetched result array: [0,2,4]
10435  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10436  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10437  * <br>
10438  */
10439 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10440 {
10441   if(!listOfIds)
10442     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10443   listOfIds->checkAllocated(); checkAllocated();
10444   if(listOfIds->getNumberOfComponents()!=1)
10445     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10446   if(getNumberOfComponents()!=1)
10447     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10448   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10449   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10450   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10451   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10452   while(tupPtr!=tupEnd && offPtr!=offEnd)
10453     {
10454       if(*tupPtr==*offPtr)
10455         {
10456           int i=offPtr[0];
10457           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10458           if(i==offPtr[1])
10459             {
10460               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10461               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10462               offPtr++;
10463             }
10464         }
10465       else
10466         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10467     }
10468   rangeIdsFetched=ret0.retn();
10469   idsInInputListThatFetch=ret1.retn();
10470 }
10471
10472 /*!
10473  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10474  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10475  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10476  * beginning within the "iota" array. And \a this is a one-dimensional array
10477  * considered as a selector of groups described by \a offsets to include into the result array.
10478  *  \throw If \a offsets is NULL.
10479  *  \throw If \a offsets is not allocated.
10480  *  \throw If \a offsets->getNumberOfComponents() != 1.
10481  *  \throw If \a offsets is not monotonically increasing.
10482  *  \throw If \a this is not allocated.
10483  *  \throw If \a this->getNumberOfComponents() != 1.
10484  *  \throw If any element of \a this is not a valid index for \a offsets array.
10485  *
10486  *  \b Example: <br>
10487  *          - \a this: [0,2,3]
10488  *          - \a offsets: [0,3,6,10,14,20]
10489  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10490  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10491  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10492  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10493  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10494  */
10495 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10496 {
10497   if(!offsets)
10498     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10499   checkAllocated();
10500   if(getNumberOfComponents()!=1)
10501     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10502   offsets->checkAllocated();
10503   if(offsets->getNumberOfComponents()!=1)
10504     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10505   int othNbTuples=offsets->getNumberOfTuples()-1;
10506   int nbOfTuples=getNumberOfTuples();
10507   int retNbOftuples=0;
10508   const int *work=getConstPointer();
10509   const int *offPtr=offsets->getConstPointer();
10510   for(int i=0;i<nbOfTuples;i++)
10511     {
10512       int val=work[i];
10513       if(val>=0 && val<othNbTuples)
10514         {
10515           int delta=offPtr[val+1]-offPtr[val];
10516           if(delta>=0)
10517             retNbOftuples+=delta;
10518           else
10519             {
10520               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10521               throw INTERP_KERNEL::Exception(oss.str().c_str());
10522             }
10523         }
10524       else
10525         {
10526           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10527           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10528           throw INTERP_KERNEL::Exception(oss.str().c_str());
10529         }
10530     }
10531   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10532   ret->alloc(retNbOftuples,1);
10533   int *retPtr=ret->getPointer();
10534   for(int i=0;i<nbOfTuples;i++)
10535     {
10536       int val=work[i];
10537       int start=offPtr[val];
10538       int off=offPtr[val+1]-start;
10539       for(int j=0;j<off;j++,retPtr++)
10540         *retPtr=start+j;
10541     }
10542   return ret.retn();
10543 }
10544
10545 /*!
10546  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10547  * scaled array (monotonically increasing).
10548 from that of \a this and \a
10549  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10550  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10551  * beginning within the "iota" array. And \a this is a one-dimensional array
10552  * considered as a selector of groups described by \a offsets to include into the result array.
10553  *  \throw If \a  is NULL.
10554  *  \throw If \a this is not allocated.
10555  *  \throw If \a this->getNumberOfComponents() != 1.
10556  *  \throw If \a this->getNumberOfTuples() == 0.
10557  *  \throw If \a this is not monotonically increasing.
10558  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10559  *
10560  *  \b Example: <br>
10561  *          - \a bg , \a stop and \a step : (0,5,2)
10562  *          - \a this: [0,3,6,10,14,20]
10563  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10564  */
10565 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10566 {
10567   if(!isAllocated())
10568     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10569   if(getNumberOfComponents()!=1)
10570     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10571   int nbOfTuples(getNumberOfTuples());
10572   if(nbOfTuples==0)
10573     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10574   const int *ids(begin());
10575   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10576   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10577     {
10578       if(pos>=0 && pos<nbOfTuples-1)
10579         {
10580           int delta(ids[pos+1]-ids[pos]);
10581           sz+=delta;
10582           if(delta<0)
10583             {
10584               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10585               throw INTERP_KERNEL::Exception(oss.str().c_str());
10586             }          
10587         }
10588       else
10589         {
10590           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10591           throw INTERP_KERNEL::Exception(oss.str().c_str());
10592         }
10593     }
10594   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10595   int *retPtr(ret->getPointer());
10596   pos=bg;
10597   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10598     {
10599       int delta(ids[pos+1]-ids[pos]);
10600       for(int j=0;j<delta;j++,retPtr++)
10601         *retPtr=pos;
10602     }
10603   return ret.retn();
10604 }
10605
10606 /*!
10607  * 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.
10608  * 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
10609  * in tuple **i** of returned DataArrayInt.
10610  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10611  *
10612  * 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)]
10613  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10614  * 
10615  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10616  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10617  * \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
10618  *        is thrown if no ranges in \a ranges contains value in \a this.
10619  * 
10620  * \sa DataArrayInt::findIdInRangeForEachTuple
10621  */
10622 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10623 {
10624   if(!ranges)
10625     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10626   if(ranges->getNumberOfComponents()!=2)
10627     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10628   checkAllocated();
10629   if(getNumberOfComponents()!=1)
10630     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10631   int nbTuples=getNumberOfTuples();
10632   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10633   int nbOfRanges=ranges->getNumberOfTuples();
10634   const int *rangesPtr=ranges->getConstPointer();
10635   int *retPtr=ret->getPointer();
10636   const int *inPtr=getConstPointer();
10637   for(int i=0;i<nbTuples;i++,retPtr++)
10638     {
10639       int val=inPtr[i];
10640       bool found=false;
10641       for(int j=0;j<nbOfRanges && !found;j++)
10642         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10643           { *retPtr=j; found=true; }
10644       if(found)
10645         continue;
10646       else
10647         {
10648           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10649           throw INTERP_KERNEL::Exception(oss.str().c_str());
10650         }
10651     }
10652   return ret.retn();
10653 }
10654
10655 /*!
10656  * 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.
10657  * 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
10658  * in tuple **i** of returned DataArrayInt.
10659  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10660  *
10661  * 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)]
10662  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10663  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10664  * 
10665  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10666  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10667  * \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
10668  *        is thrown if no ranges in \a ranges contains value in \a this.
10669  * \sa DataArrayInt::findRangeIdForEachTuple
10670  */
10671 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10672 {
10673   if(!ranges)
10674     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10675   if(ranges->getNumberOfComponents()!=2)
10676     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10677   checkAllocated();
10678   if(getNumberOfComponents()!=1)
10679     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10680   int nbTuples=getNumberOfTuples();
10681   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10682   int nbOfRanges=ranges->getNumberOfTuples();
10683   const int *rangesPtr=ranges->getConstPointer();
10684   int *retPtr=ret->getPointer();
10685   const int *inPtr=getConstPointer();
10686   for(int i=0;i<nbTuples;i++,retPtr++)
10687     {
10688       int val=inPtr[i];
10689       bool found=false;
10690       for(int j=0;j<nbOfRanges && !found;j++)
10691         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10692           { *retPtr=val-rangesPtr[2*j]; found=true; }
10693       if(found)
10694         continue;
10695       else
10696         {
10697           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10698           throw INTERP_KERNEL::Exception(oss.str().c_str());
10699         }
10700     }
10701   return ret.retn();
10702 }
10703
10704 /*!
10705  * \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).
10706  * 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).
10707  * 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 !
10708  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10709  * This method does nothing if number of tuples is lower of equal to 1.
10710  *
10711  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10712  *
10713  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10714  */
10715 void DataArrayInt::sortEachPairToMakeALinkedList()
10716 {
10717   checkAllocated();
10718   if(getNumberOfComponents()!=2)
10719     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10720   int nbOfTuples(getNumberOfTuples());
10721   if(nbOfTuples<=1)
10722     return ;
10723   int *conn(getPointer());
10724   for(int i=1;i<nbOfTuples;i++,conn+=2)
10725     {
10726       if(i>1)
10727         {
10728           if(conn[2]==conn[3])
10729             {
10730               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10731               throw INTERP_KERNEL::Exception(oss.str().c_str());
10732             }
10733           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10734             std::swap(conn[2],conn[3]);
10735           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10736           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10737             {
10738               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10739               throw INTERP_KERNEL::Exception(oss.str().c_str());
10740             }
10741         }
10742       else
10743         {
10744           if(conn[0]==conn[1] || conn[2]==conn[3])
10745             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10746           int tmp[4];
10747           std::set<int> s;
10748           s.insert(conn,conn+4);
10749           if(s.size()!=3)
10750             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10751           if(std::count(conn,conn+4,conn[0])==2)
10752             {
10753               tmp[0]=conn[1];
10754               tmp[1]=conn[0];
10755               tmp[2]=conn[0];
10756               if(conn[2]==conn[0])
10757                 { tmp[3]=conn[3]; }
10758               else
10759                 { tmp[3]=conn[2];}
10760               std::copy(tmp,tmp+4,conn);
10761             }
10762         }
10763     }
10764 }
10765
10766 /*!
10767  * 
10768  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10769  *             \a nbTimes  should be at least equal to 1.
10770  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10771  * \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.
10772  */
10773 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10774 {
10775   checkAllocated();
10776   if(getNumberOfComponents()!=1)
10777     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10778   if(nbTimes<1)
10779     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10780   int nbTuples=getNumberOfTuples();
10781   const int *inPtr=getConstPointer();
10782   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10783   int *retPtr=ret->getPointer();
10784   for(int i=0;i<nbTuples;i++,inPtr++)
10785     {
10786       int val=*inPtr;
10787       for(int j=0;j<nbTimes;j++,retPtr++)
10788         *retPtr=val;
10789     }
10790   ret->copyStringInfoFrom(*this);
10791   return ret.retn();
10792 }
10793
10794 /*!
10795  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10796  * But the number of components can be different from one.
10797  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10798  */
10799 DataArrayInt *DataArrayInt::getDifferentValues() const
10800 {
10801   checkAllocated();
10802   std::set<int> ret;
10803   ret.insert(begin(),end());
10804   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10805   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10806   return ret2.retn();
10807 }
10808
10809 /*!
10810  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10811  * them it tells which tuple id have this id.
10812  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10813  * This method returns two arrays having same size.
10814  * 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.
10815  * 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]]
10816  */
10817 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10818 {
10819   checkAllocated();
10820   if(getNumberOfComponents()!=1)
10821     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10822   int id=0;
10823   std::map<int,int> m,m2,m3;
10824   for(const int *w=begin();w!=end();w++)
10825     m[*w]++;
10826   differentIds.resize(m.size());
10827   std::vector<DataArrayInt *> ret(m.size());
10828   std::vector<int *> retPtr(m.size());
10829   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10830     {
10831       m2[(*it).first]=id;
10832       ret[id]=DataArrayInt::New();
10833       ret[id]->alloc((*it).second,1);
10834       retPtr[id]=ret[id]->getPointer();
10835       differentIds[id]=(*it).first;
10836     }
10837   id=0;
10838   for(const int *w=begin();w!=end();w++,id++)
10839     {
10840       retPtr[m2[*w]][m3[*w]++]=id;
10841     }
10842   return ret;
10843 }
10844
10845 /*!
10846  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10847  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10848  *
10849  * \param [in] nbOfSlices - number of slices expected.
10850  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10851  * 
10852  * \sa DataArray::GetSlice
10853  * \throw If \a this is not allocated or not with exactly one component.
10854  * \throw If an element in \a this if < 0.
10855  */
10856 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10857 {
10858   if(!isAllocated() || getNumberOfComponents()!=1)
10859     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10860   if(nbOfSlices<=0)
10861     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10862   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10863   int sumPerSlc(sum/nbOfSlices),pos(0);
10864   const int *w(begin());
10865   std::vector< std::pair<int,int> > ret(nbOfSlices);
10866   for(int i=0;i<nbOfSlices;i++)
10867     {
10868       std::pair<int,int> p(pos,-1);
10869       int locSum(0);
10870       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10871       if(i!=nbOfSlices-1)
10872         p.second=pos;
10873       else
10874         p.second=nbOfTuples;
10875       ret[i]=p;
10876     }
10877   return ret;
10878 }
10879
10880 /*!
10881  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10882  * valid cases.
10883  * 1.  The arrays have same number of tuples and components. Then each value of
10884  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10885  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10886  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10887  *   component. Then
10888  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10889  * 3.  The arrays have same number of components and one array, say _a2_, has one
10890  *   tuple. Then
10891  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10892  *
10893  * Info on components is copied either from the first array (in the first case) or from
10894  * the array with maximal number of elements (getNbOfElems()).
10895  *  \param [in] a1 - an array to sum up.
10896  *  \param [in] a2 - another array to sum up.
10897  *  \return DataArrayInt * - the new instance of DataArrayInt.
10898  *          The caller is to delete this result array using decrRef() as it is no more
10899  *          needed.
10900  *  \throw If either \a a1 or \a a2 is NULL.
10901  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10902  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10903  *         none of them has number of tuples or components equal to 1.
10904  */
10905 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10906 {
10907   if(!a1 || !a2)
10908     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10909   int nbOfTuple=a1->getNumberOfTuples();
10910   int nbOfTuple2=a2->getNumberOfTuples();
10911   int nbOfComp=a1->getNumberOfComponents();
10912   int nbOfComp2=a2->getNumberOfComponents();
10913   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10914   if(nbOfTuple==nbOfTuple2)
10915     {
10916       if(nbOfComp==nbOfComp2)
10917         {
10918           ret=DataArrayInt::New();
10919           ret->alloc(nbOfTuple,nbOfComp);
10920           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10921           ret->copyStringInfoFrom(*a1);
10922         }
10923       else
10924         {
10925           int nbOfCompMin,nbOfCompMax;
10926           const DataArrayInt *aMin, *aMax;
10927           if(nbOfComp>nbOfComp2)
10928             {
10929               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10930               aMin=a2; aMax=a1;
10931             }
10932           else
10933             {
10934               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10935               aMin=a1; aMax=a2;
10936             }
10937           if(nbOfCompMin==1)
10938             {
10939               ret=DataArrayInt::New();
10940               ret->alloc(nbOfTuple,nbOfCompMax);
10941               const int *aMinPtr=aMin->getConstPointer();
10942               const int *aMaxPtr=aMax->getConstPointer();
10943               int *res=ret->getPointer();
10944               for(int i=0;i<nbOfTuple;i++)
10945                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10946               ret->copyStringInfoFrom(*aMax);
10947             }
10948           else
10949             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10950         }
10951     }
10952   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10953     {
10954       if(nbOfComp==nbOfComp2)
10955         {
10956           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10957           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10958           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10959           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10960           ret=DataArrayInt::New();
10961           ret->alloc(nbOfTupleMax,nbOfComp);
10962           int *res=ret->getPointer();
10963           for(int i=0;i<nbOfTupleMax;i++)
10964             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10965           ret->copyStringInfoFrom(*aMax);
10966         }
10967       else
10968         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10969     }
10970   else
10971     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10972   return ret.retn();
10973 }
10974
10975 /*!
10976  * Adds values of another DataArrayInt to values of \a this one. There are 3
10977  * valid cases.
10978  * 1.  The arrays have same number of tuples and components. Then each value of
10979  *   \a other array is added to the corresponding value of \a this array, i.e.:
10980  *   _a_ [ i, j ] += _other_ [ i, j ].
10981  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10982  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10983  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10984  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10985  *
10986  *  \param [in] other - an array to add to \a this one.
10987  *  \throw If \a other is NULL.
10988  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10989  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10990  *         \a other has number of both tuples and components not equal to 1.
10991  */
10992 void DataArrayInt::addEqual(const DataArrayInt *other)
10993 {
10994   if(!other)
10995     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10996   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10997   checkAllocated(); other->checkAllocated();
10998   int nbOfTuple=getNumberOfTuples();
10999   int nbOfTuple2=other->getNumberOfTuples();
11000   int nbOfComp=getNumberOfComponents();
11001   int nbOfComp2=other->getNumberOfComponents();
11002   if(nbOfTuple==nbOfTuple2)
11003     {
11004       if(nbOfComp==nbOfComp2)
11005         {
11006           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
11007         }
11008       else if(nbOfComp2==1)
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,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
11014         }
11015       else
11016         throw INTERP_KERNEL::Exception(msg);
11017     }
11018   else if(nbOfTuple2==1)
11019     {
11020       if(nbOfComp2==nbOfComp)
11021         {
11022           int *ptr=getPointer();
11023           const int *ptrc=other->getConstPointer();
11024           for(int i=0;i<nbOfTuple;i++)
11025             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
11026         }
11027       else
11028         throw INTERP_KERNEL::Exception(msg);
11029     }
11030   else
11031     throw INTERP_KERNEL::Exception(msg);
11032   declareAsNew();
11033 }
11034
11035 /*!
11036  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
11037  * valid cases.
11038  * 1.  The arrays have same number of tuples and components. Then each value of
11039  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
11040  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
11041  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11042  *   component. Then
11043  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
11044  * 3.  The arrays have same number of components and one array, say _a2_, has one
11045  *   tuple. Then
11046  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
11047  *
11048  * Info on components is copied either from the first array (in the first case) or from
11049  * the array with maximal number of elements (getNbOfElems()).
11050  *  \param [in] a1 - an array to subtract from.
11051  *  \param [in] a2 - an array to subtract.
11052  *  \return DataArrayInt * - the new instance of DataArrayInt.
11053  *          The caller is to delete this result array using decrRef() as it is no more
11054  *          needed.
11055  *  \throw If either \a a1 or \a a2 is NULL.
11056  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11057  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11058  *         none of them has number of tuples or components equal to 1.
11059  */
11060 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
11061 {
11062   if(!a1 || !a2)
11063     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
11064   int nbOfTuple1=a1->getNumberOfTuples();
11065   int nbOfTuple2=a2->getNumberOfTuples();
11066   int nbOfComp1=a1->getNumberOfComponents();
11067   int nbOfComp2=a2->getNumberOfComponents();
11068   if(nbOfTuple2==nbOfTuple1)
11069     {
11070       if(nbOfComp1==nbOfComp2)
11071         {
11072           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11073           ret->alloc(nbOfTuple2,nbOfComp1);
11074           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
11075           ret->copyStringInfoFrom(*a1);
11076           return ret.retn();
11077         }
11078       else if(nbOfComp2==1)
11079         {
11080           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11081           ret->alloc(nbOfTuple1,nbOfComp1);
11082           const int *a2Ptr=a2->getConstPointer();
11083           const int *a1Ptr=a1->getConstPointer();
11084           int *res=ret->getPointer();
11085           for(int i=0;i<nbOfTuple1;i++)
11086             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
11087           ret->copyStringInfoFrom(*a1);
11088           return ret.retn();
11089         }
11090       else
11091         {
11092           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11093           return 0;
11094         }
11095     }
11096   else if(nbOfTuple2==1)
11097     {
11098       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11099       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11100       ret->alloc(nbOfTuple1,nbOfComp1);
11101       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11102       int *pt=ret->getPointer();
11103       for(int i=0;i<nbOfTuple1;i++)
11104         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
11105       ret->copyStringInfoFrom(*a1);
11106       return ret.retn();
11107     }
11108   else
11109     {
11110       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
11111       return 0;
11112     }
11113 }
11114
11115 /*!
11116  * Subtract values of another DataArrayInt from values of \a this one. There are 3
11117  * valid cases.
11118  * 1.  The arrays have same number of tuples and components. Then each value of
11119  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
11120  *   _a_ [ i, j ] -= _other_ [ i, j ].
11121  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11122  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
11123  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11124  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
11125  *
11126  *  \param [in] other - an array to subtract from \a this one.
11127  *  \throw If \a other is NULL.
11128  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11129  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11130  *         \a other has number of both tuples and components not equal to 1.
11131  */
11132 void DataArrayInt::substractEqual(const DataArrayInt *other)
11133 {
11134   if(!other)
11135     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
11136   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
11137   checkAllocated(); other->checkAllocated();
11138   int nbOfTuple=getNumberOfTuples();
11139   int nbOfTuple2=other->getNumberOfTuples();
11140   int nbOfComp=getNumberOfComponents();
11141   int nbOfComp2=other->getNumberOfComponents();
11142   if(nbOfTuple==nbOfTuple2)
11143     {
11144       if(nbOfComp==nbOfComp2)
11145         {
11146           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
11147         }
11148       else if(nbOfComp2==1)
11149         {
11150           int *ptr=getPointer();
11151           const int *ptrc=other->getConstPointer();
11152           for(int i=0;i<nbOfTuple;i++)
11153             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11154         }
11155       else
11156         throw INTERP_KERNEL::Exception(msg);
11157     }
11158   else if(nbOfTuple2==1)
11159     {
11160       int *ptr=getPointer();
11161       const int *ptrc=other->getConstPointer();
11162       for(int i=0;i<nbOfTuple;i++)
11163         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11164     }
11165   else
11166     throw INTERP_KERNEL::Exception(msg);
11167   declareAsNew();
11168 }
11169
11170 /*!
11171  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11172  * valid cases.
11173  * 1.  The arrays have same number of tuples and components. Then each value of
11174  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11175  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11176  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11177  *   component. Then
11178  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11179  * 3.  The arrays have same number of components and one array, say _a2_, has one
11180  *   tuple. Then
11181  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11182  *
11183  * Info on components is copied either from the first array (in the first case) or from
11184  * the array with maximal number of elements (getNbOfElems()).
11185  *  \param [in] a1 - a factor array.
11186  *  \param [in] a2 - another factor array.
11187  *  \return DataArrayInt * - the new instance of DataArrayInt.
11188  *          The caller is to delete this result array using decrRef() as it is no more
11189  *          needed.
11190  *  \throw If either \a a1 or \a a2 is NULL.
11191  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11192  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11193  *         none of them has number of tuples or components equal to 1.
11194  */
11195 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11196 {
11197   if(!a1 || !a2)
11198     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11199   int nbOfTuple=a1->getNumberOfTuples();
11200   int nbOfTuple2=a2->getNumberOfTuples();
11201   int nbOfComp=a1->getNumberOfComponents();
11202   int nbOfComp2=a2->getNumberOfComponents();
11203   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
11204   if(nbOfTuple==nbOfTuple2)
11205     {
11206       if(nbOfComp==nbOfComp2)
11207         {
11208           ret=DataArrayInt::New();
11209           ret->alloc(nbOfTuple,nbOfComp);
11210           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11211           ret->copyStringInfoFrom(*a1);
11212         }
11213       else
11214         {
11215           int nbOfCompMin,nbOfCompMax;
11216           const DataArrayInt *aMin, *aMax;
11217           if(nbOfComp>nbOfComp2)
11218             {
11219               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11220               aMin=a2; aMax=a1;
11221             }
11222           else
11223             {
11224               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11225               aMin=a1; aMax=a2;
11226             }
11227           if(nbOfCompMin==1)
11228             {
11229               ret=DataArrayInt::New();
11230               ret->alloc(nbOfTuple,nbOfCompMax);
11231               const int *aMinPtr=aMin->getConstPointer();
11232               const int *aMaxPtr=aMax->getConstPointer();
11233               int *res=ret->getPointer();
11234               for(int i=0;i<nbOfTuple;i++)
11235                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11236               ret->copyStringInfoFrom(*aMax);
11237             }
11238           else
11239             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11240         }
11241     }
11242   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11243     {
11244       if(nbOfComp==nbOfComp2)
11245         {
11246           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11247           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11248           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11249           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11250           ret=DataArrayInt::New();
11251           ret->alloc(nbOfTupleMax,nbOfComp);
11252           int *res=ret->getPointer();
11253           for(int i=0;i<nbOfTupleMax;i++)
11254             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11255           ret->copyStringInfoFrom(*aMax);
11256         }
11257       else
11258         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11259     }
11260   else
11261     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11262   return ret.retn();
11263 }
11264
11265
11266 /*!
11267  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11268  * valid cases.
11269  * 1.  The arrays have same number of tuples and components. Then each value of
11270  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11271  *   _a_ [ i, j ] *= _other_ [ i, j ].
11272  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11273  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11274  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11275  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11276  *
11277  *  \param [in] other - an array to multiply to \a this one.
11278  *  \throw If \a other is NULL.
11279  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11280  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11281  *         \a other has number of both tuples and components not equal to 1.
11282  */
11283 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11284 {
11285   if(!other)
11286     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11287   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11288   checkAllocated(); other->checkAllocated();
11289   int nbOfTuple=getNumberOfTuples();
11290   int nbOfTuple2=other->getNumberOfTuples();
11291   int nbOfComp=getNumberOfComponents();
11292   int nbOfComp2=other->getNumberOfComponents();
11293   if(nbOfTuple==nbOfTuple2)
11294     {
11295       if(nbOfComp==nbOfComp2)
11296         {
11297           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11298         }
11299       else if(nbOfComp2==1)
11300         {
11301           int *ptr=getPointer();
11302           const int *ptrc=other->getConstPointer();
11303           for(int i=0;i<nbOfTuple;i++)
11304             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11305         }
11306       else
11307         throw INTERP_KERNEL::Exception(msg);
11308     }
11309   else if(nbOfTuple2==1)
11310     {
11311       if(nbOfComp2==nbOfComp)
11312         {
11313           int *ptr=getPointer();
11314           const int *ptrc=other->getConstPointer();
11315           for(int i=0;i<nbOfTuple;i++)
11316             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11317         }
11318       else
11319         throw INTERP_KERNEL::Exception(msg);
11320     }
11321   else
11322     throw INTERP_KERNEL::Exception(msg);
11323   declareAsNew();
11324 }
11325
11326
11327 /*!
11328  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11329  * valid cases.
11330  * 1.  The arrays have same number of tuples and components. Then each value of
11331  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11332  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11333  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11334  *   component. Then
11335  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11336  * 3.  The arrays have same number of components and one array, say _a2_, has one
11337  *   tuple. Then
11338  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11339  *
11340  * Info on components is copied either from the first array (in the first case) or from
11341  * the array with maximal number of elements (getNbOfElems()).
11342  *  \warning No check of division by zero is performed!
11343  *  \param [in] a1 - a numerator array.
11344  *  \param [in] a2 - a denominator array.
11345  *  \return DataArrayInt * - the new instance of DataArrayInt.
11346  *          The caller is to delete this result array using decrRef() as it is no more
11347  *          needed.
11348  *  \throw If either \a a1 or \a a2 is NULL.
11349  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11350  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11351  *         none of them has number of tuples or components equal to 1.
11352  */
11353 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11354 {
11355   if(!a1 || !a2)
11356     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11357   int nbOfTuple1=a1->getNumberOfTuples();
11358   int nbOfTuple2=a2->getNumberOfTuples();
11359   int nbOfComp1=a1->getNumberOfComponents();
11360   int nbOfComp2=a2->getNumberOfComponents();
11361   if(nbOfTuple2==nbOfTuple1)
11362     {
11363       if(nbOfComp1==nbOfComp2)
11364         {
11365           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11366           ret->alloc(nbOfTuple2,nbOfComp1);
11367           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11368           ret->copyStringInfoFrom(*a1);
11369           return ret.retn();
11370         }
11371       else if(nbOfComp2==1)
11372         {
11373           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11374           ret->alloc(nbOfTuple1,nbOfComp1);
11375           const int *a2Ptr=a2->getConstPointer();
11376           const int *a1Ptr=a1->getConstPointer();
11377           int *res=ret->getPointer();
11378           for(int i=0;i<nbOfTuple1;i++)
11379             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11380           ret->copyStringInfoFrom(*a1);
11381           return ret.retn();
11382         }
11383       else
11384         {
11385           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11386           return 0;
11387         }
11388     }
11389   else if(nbOfTuple2==1)
11390     {
11391       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11392       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11393       ret->alloc(nbOfTuple1,nbOfComp1);
11394       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11395       int *pt=ret->getPointer();
11396       for(int i=0;i<nbOfTuple1;i++)
11397         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11398       ret->copyStringInfoFrom(*a1);
11399       return ret.retn();
11400     }
11401   else
11402     {
11403       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11404       return 0;
11405     }
11406 }
11407
11408 /*!
11409  * Divide values of \a this array by values of another DataArrayInt. There are 3
11410  * valid cases.
11411  * 1.  The arrays have same number of tuples and components. Then each value of
11412  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11413  *   _a_ [ i, j ] /= _other_ [ i, j ].
11414  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11415  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11416  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11417  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11418  *
11419  *  \warning No check of division by zero is performed!
11420  *  \param [in] other - an array to divide \a this one by.
11421  *  \throw If \a other is NULL.
11422  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11423  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11424  *         \a other has number of both tuples and components not equal to 1.
11425  */
11426 void DataArrayInt::divideEqual(const DataArrayInt *other)
11427 {
11428   if(!other)
11429     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11430   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11431   checkAllocated(); other->checkAllocated();
11432   int nbOfTuple=getNumberOfTuples();
11433   int nbOfTuple2=other->getNumberOfTuples();
11434   int nbOfComp=getNumberOfComponents();
11435   int nbOfComp2=other->getNumberOfComponents();
11436   if(nbOfTuple==nbOfTuple2)
11437     {
11438       if(nbOfComp==nbOfComp2)
11439         {
11440           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11441         }
11442       else if(nbOfComp2==1)
11443         {
11444           int *ptr=getPointer();
11445           const int *ptrc=other->getConstPointer();
11446           for(int i=0;i<nbOfTuple;i++)
11447             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11448         }
11449       else
11450         throw INTERP_KERNEL::Exception(msg);
11451     }
11452   else if(nbOfTuple2==1)
11453     {
11454       if(nbOfComp2==nbOfComp)
11455         {
11456           int *ptr=getPointer();
11457           const int *ptrc=other->getConstPointer();
11458           for(int i=0;i<nbOfTuple;i++)
11459             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11460         }
11461       else
11462         throw INTERP_KERNEL::Exception(msg);
11463     }
11464   else
11465     throw INTERP_KERNEL::Exception(msg);
11466   declareAsNew();
11467 }
11468
11469
11470 /*!
11471  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11472  * valid cases.
11473  * 1.  The arrays have same number of tuples and components. Then each value of
11474  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11475  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11476  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11477  *   component. Then
11478  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11479  * 3.  The arrays have same number of components and one array, say _a2_, has one
11480  *   tuple. Then
11481  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11482  *
11483  * Info on components is copied either from the first array (in the first case) or from
11484  * the array with maximal number of elements (getNbOfElems()).
11485  *  \warning No check of division by zero is performed!
11486  *  \param [in] a1 - a dividend array.
11487  *  \param [in] a2 - a divisor array.
11488  *  \return DataArrayInt * - the new instance of DataArrayInt.
11489  *          The caller is to delete this result array using decrRef() as it is no more
11490  *          needed.
11491  *  \throw If either \a a1 or \a a2 is NULL.
11492  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11493  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11494  *         none of them has number of tuples or components equal to 1.
11495  */
11496 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11497 {
11498   if(!a1 || !a2)
11499     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11500   int nbOfTuple1=a1->getNumberOfTuples();
11501   int nbOfTuple2=a2->getNumberOfTuples();
11502   int nbOfComp1=a1->getNumberOfComponents();
11503   int nbOfComp2=a2->getNumberOfComponents();
11504   if(nbOfTuple2==nbOfTuple1)
11505     {
11506       if(nbOfComp1==nbOfComp2)
11507         {
11508           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11509           ret->alloc(nbOfTuple2,nbOfComp1);
11510           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11511           ret->copyStringInfoFrom(*a1);
11512           return ret.retn();
11513         }
11514       else if(nbOfComp2==1)
11515         {
11516           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11517           ret->alloc(nbOfTuple1,nbOfComp1);
11518           const int *a2Ptr=a2->getConstPointer();
11519           const int *a1Ptr=a1->getConstPointer();
11520           int *res=ret->getPointer();
11521           for(int i=0;i<nbOfTuple1;i++)
11522             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11523           ret->copyStringInfoFrom(*a1);
11524           return ret.retn();
11525         }
11526       else
11527         {
11528           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11529           return 0;
11530         }
11531     }
11532   else if(nbOfTuple2==1)
11533     {
11534       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11535       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11536       ret->alloc(nbOfTuple1,nbOfComp1);
11537       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11538       int *pt=ret->getPointer();
11539       for(int i=0;i<nbOfTuple1;i++)
11540         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11541       ret->copyStringInfoFrom(*a1);
11542       return ret.retn();
11543     }
11544   else
11545     {
11546       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11547       return 0;
11548     }
11549 }
11550
11551 /*!
11552  * Modify \a this array so that each value becomes a modulus of division of this value by
11553  * a value of another DataArrayInt. There are 3 valid cases.
11554  * 1.  The arrays have same number of tuples and components. Then each value of
11555  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11556  *   _a_ [ i, j ] %= _other_ [ i, j ].
11557  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11558  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11559  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11560  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11561  *
11562  *  \warning No check of division by zero is performed!
11563  *  \param [in] other - a divisor array.
11564  *  \throw If \a other is NULL.
11565  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11566  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11567  *         \a other has number of both tuples and components not equal to 1.
11568  */
11569 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11570 {
11571   if(!other)
11572     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11573   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11574   checkAllocated(); other->checkAllocated();
11575   int nbOfTuple=getNumberOfTuples();
11576   int nbOfTuple2=other->getNumberOfTuples();
11577   int nbOfComp=getNumberOfComponents();
11578   int nbOfComp2=other->getNumberOfComponents();
11579   if(nbOfTuple==nbOfTuple2)
11580     {
11581       if(nbOfComp==nbOfComp2)
11582         {
11583           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11584         }
11585       else if(nbOfComp2==1)
11586         {
11587           if(nbOfComp2==nbOfComp)
11588             {
11589               int *ptr=getPointer();
11590               const int *ptrc=other->getConstPointer();
11591               for(int i=0;i<nbOfTuple;i++)
11592                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11593             }
11594           else
11595             throw INTERP_KERNEL::Exception(msg);
11596         }
11597       else
11598         throw INTERP_KERNEL::Exception(msg);
11599     }
11600   else if(nbOfTuple2==1)
11601     {
11602       int *ptr=getPointer();
11603       const int *ptrc=other->getConstPointer();
11604       for(int i=0;i<nbOfTuple;i++)
11605         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11606     }
11607   else
11608     throw INTERP_KERNEL::Exception(msg);
11609   declareAsNew();
11610 }
11611
11612 /*!
11613  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11614  * valid cases.
11615  *
11616  *  \param [in] a1 - an array to pow up.
11617  *  \param [in] a2 - another array to sum up.
11618  *  \return DataArrayInt * - the new instance of DataArrayInt.
11619  *          The caller is to delete this result array using decrRef() as it is no more
11620  *          needed.
11621  *  \throw If either \a a1 or \a a2 is NULL.
11622  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11623  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11624  *  \throw If there is a negative value in \a a2.
11625  */
11626 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11627 {
11628   if(!a1 || !a2)
11629     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11630   int nbOfTuple=a1->getNumberOfTuples();
11631   int nbOfTuple2=a2->getNumberOfTuples();
11632   int nbOfComp=a1->getNumberOfComponents();
11633   int nbOfComp2=a2->getNumberOfComponents();
11634   if(nbOfTuple!=nbOfTuple2)
11635     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11636   if(nbOfComp!=1 || nbOfComp2!=1)
11637     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11638   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11639   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11640   int *ptr=ret->getPointer();
11641   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11642     {
11643       if(*ptr2>=0)
11644         {
11645           int tmp=1;
11646           for(int j=0;j<*ptr2;j++)
11647             tmp*=*ptr1;
11648           *ptr=tmp;
11649         }
11650       else
11651         {
11652           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11653           throw INTERP_KERNEL::Exception(oss.str().c_str());
11654         }
11655     }
11656   return ret.retn();
11657 }
11658
11659 /*!
11660  * Apply pow on values of another DataArrayInt to values of \a this one.
11661  *
11662  *  \param [in] other - an array to pow to \a this one.
11663  *  \throw If \a other is NULL.
11664  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11665  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11666  *  \throw If there is a negative value in \a other.
11667  */
11668 void DataArrayInt::powEqual(const DataArrayInt *other)
11669 {
11670   if(!other)
11671     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11672   int nbOfTuple=getNumberOfTuples();
11673   int nbOfTuple2=other->getNumberOfTuples();
11674   int nbOfComp=getNumberOfComponents();
11675   int nbOfComp2=other->getNumberOfComponents();
11676   if(nbOfTuple!=nbOfTuple2)
11677     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11678   if(nbOfComp!=1 || nbOfComp2!=1)
11679     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11680   int *ptr=getPointer();
11681   const int *ptrc=other->begin();
11682   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11683     {
11684       if(*ptrc>=0)
11685         {
11686           int tmp=1;
11687           for(int j=0;j<*ptrc;j++)
11688             tmp*=*ptr;
11689           *ptr=tmp;
11690         }
11691       else
11692         {
11693           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11694           throw INTERP_KERNEL::Exception(oss.str().c_str());
11695         }
11696     }
11697   declareAsNew();
11698 }
11699
11700 /*!
11701  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11702  * This map, if applied to \a start array, would make it sorted. For example, if
11703  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11704  * [5,6,0,3,2,7,1,4].
11705  *  \param [in] start - pointer to the first element of the array for which the
11706  *         permutation map is computed.
11707  *  \param [in] end - pointer specifying the end of the array \a start, so that
11708  *         the last value of \a start is \a end[ -1 ].
11709  *  \return int * - the result permutation array that the caller is to delete as it is no
11710  *         more needed.
11711  *  \throw If there are equal values in the input array.
11712  */
11713 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11714 {
11715   std::size_t sz=std::distance(start,end);
11716   int *ret=(int *)malloc(sz*sizeof(int));
11717   int *work=new int[sz];
11718   std::copy(start,end,work);
11719   std::sort(work,work+sz);
11720   if(std::unique(work,work+sz)!=work+sz)
11721     {
11722       delete [] work;
11723       free(ret);
11724       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11725     }
11726   std::map<int,int> m;
11727   for(int *workPt=work;workPt!=work+sz;workPt++)
11728     m[*workPt]=(int)std::distance(work,workPt);
11729   int *iter2=ret;
11730   for(const int *iter=start;iter!=end;iter++,iter2++)
11731     *iter2=m[*iter];
11732   delete [] work;
11733   return ret;
11734 }
11735
11736 /*!
11737  * Returns a new DataArrayInt containing an arithmetic progression
11738  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11739  * function.
11740  *  \param [in] begin - the start value of the result sequence.
11741  *  \param [in] end - limiting value, so that every value of the result array is less than
11742  *              \a end.
11743  *  \param [in] step - specifies the increment or decrement.
11744  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11745  *          array using decrRef() as it is no more needed.
11746  *  \throw If \a step == 0.
11747  *  \throw If \a end < \a begin && \a step > 0.
11748  *  \throw If \a end > \a begin && \a step < 0.
11749  */
11750 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11751 {
11752   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11753   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11754   ret->alloc(nbOfTuples,1);
11755   int *ptr=ret->getPointer();
11756   if(step>0)
11757     {
11758       for(int i=begin;i<end;i+=step,ptr++)
11759         *ptr=i;
11760     }
11761   else
11762     {
11763       for(int i=begin;i>end;i+=step,ptr++)
11764         *ptr=i;
11765     }
11766   return ret.retn();
11767 }
11768
11769 /*!
11770  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11771  * Server side.
11772  */
11773 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11774 {
11775   tinyInfo.resize(2);
11776   if(isAllocated())
11777     {
11778       tinyInfo[0]=getNumberOfTuples();
11779       tinyInfo[1]=getNumberOfComponents();
11780     }
11781   else
11782     {
11783       tinyInfo[0]=-1;
11784       tinyInfo[1]=-1;
11785     }
11786 }
11787
11788 /*!
11789  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11790  * Server side.
11791  */
11792 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11793 {
11794   if(isAllocated())
11795     {
11796       int nbOfCompo=getNumberOfComponents();
11797       tinyInfo.resize(nbOfCompo+1);
11798       tinyInfo[0]=getName();
11799       for(int i=0;i<nbOfCompo;i++)
11800         tinyInfo[i+1]=getInfoOnComponent(i);
11801     }
11802   else
11803     {
11804       tinyInfo.resize(1);
11805       tinyInfo[0]=getName();
11806     }
11807 }
11808
11809 /*!
11810  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11811  * This method returns if a feeding is needed.
11812  */
11813 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11814 {
11815   int nbOfTuple=tinyInfoI[0];
11816   int nbOfComp=tinyInfoI[1];
11817   if(nbOfTuple!=-1 || nbOfComp!=-1)
11818     {
11819       alloc(nbOfTuple,nbOfComp);
11820       return true;
11821     }
11822   return false;
11823 }
11824
11825 /*!
11826  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11827  * This method returns if a feeding is needed.
11828  */
11829 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11830 {
11831   setName(tinyInfoS[0]);
11832   if(isAllocated())
11833     {
11834       int nbOfCompo=tinyInfoI[1];
11835       for(int i=0;i<nbOfCompo;i++)
11836         setInfoOnComponent(i,tinyInfoS[i+1]);
11837     }
11838 }
11839
11840 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11841 {
11842   if(_da)
11843     {
11844       _da->incrRef();
11845       if(_da->isAllocated())
11846         {
11847           _nb_comp=da->getNumberOfComponents();
11848           _nb_tuple=da->getNumberOfTuples();
11849           _pt=da->getPointer();
11850         }
11851     }
11852 }
11853
11854 DataArrayIntIterator::~DataArrayIntIterator()
11855 {
11856   if(_da)
11857     _da->decrRef();
11858 }
11859
11860 DataArrayIntTuple *DataArrayIntIterator::nextt()
11861 {
11862   if(_tuple_id<_nb_tuple)
11863     {
11864       _tuple_id++;
11865       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11866       _pt+=_nb_comp;
11867       return ret;
11868     }
11869   else
11870     return 0;
11871 }
11872
11873 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11874 {
11875 }
11876
11877 std::string DataArrayIntTuple::repr() const
11878 {
11879   std::ostringstream oss; oss << "(";
11880   for(int i=0;i<_nb_of_compo-1;i++)
11881     oss << _pt[i] << ", ";
11882   oss << _pt[_nb_of_compo-1] << ")";
11883   return oss.str();
11884 }
11885
11886 int DataArrayIntTuple::intValue() const
11887 {
11888   if(_nb_of_compo==1)
11889     return *_pt;
11890   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11891 }
11892
11893 /*!
11894  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11895  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11896  * 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
11897  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11898  */
11899 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11900 {
11901   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11902     {
11903       DataArrayInt *ret=DataArrayInt::New();
11904       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11905       return ret;
11906     }
11907   else
11908     {
11909       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11910       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11911       throw INTERP_KERNEL::Exception(oss.str().c_str());
11912     }
11913 }