Salome HOME
fix conflict
[modules/med.git] / medtool / 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  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3651  * array contating 6 components.
3652  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3653  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3654  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3655  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3656  *  \throw If \a this->getNumberOfComponents() != 6.
3657  */
3658 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3659 {
3660   checkAllocated();
3661   int nbOfComp=getNumberOfComponents();
3662   if(nbOfComp!=6)
3663     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3664   DataArrayDouble *ret=DataArrayDouble::New();
3665   int nbOfTuple=getNumberOfTuples();
3666   ret->alloc(nbOfTuple,1);
3667   const double *src=getConstPointer();
3668   double *dest=ret->getPointer();
3669   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3670     *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];
3671   return ret;
3672 }
3673
3674 /*!
3675  * Computes the determinant of every square matrix defined by the tuple of \a this
3676  * array, which contains either 4, 6 or 9 components. The case of 6 components
3677  * corresponds to that of the upper triangular matrix.
3678  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3679  *          is the determinant of matrix of the corresponding tuple of \a this array.
3680  *          The caller is to delete this result array using decrRef() as it is no more
3681  *          needed. 
3682  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3683  */
3684 DataArrayDouble *DataArrayDouble::determinant() const
3685 {
3686   checkAllocated();
3687   DataArrayDouble *ret=DataArrayDouble::New();
3688   int nbOfTuple=getNumberOfTuples();
3689   ret->alloc(nbOfTuple,1);
3690   const double *src=getConstPointer();
3691   double *dest=ret->getPointer();
3692   switch(getNumberOfComponents())
3693   {
3694     case 6:
3695       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3696         *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];
3697       return ret;
3698     case 4:
3699       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3700         *dest=src[0]*src[3]-src[1]*src[2];
3701       return ret;
3702     case 9:
3703       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3704         *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];
3705       return ret;
3706     default:
3707       ret->decrRef();
3708       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3709   }
3710 }
3711
3712 /*!
3713  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3714  * \a this array, which contains 6 components.
3715  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3716  *          components, whose each tuple contains the eigenvalues of the matrix of
3717  *          corresponding tuple of \a this array. 
3718  *          The caller is to delete this result array using decrRef() as it is no more
3719  *          needed. 
3720  *  \throw If \a this->getNumberOfComponents() != 6.
3721  */
3722 DataArrayDouble *DataArrayDouble::eigenValues() const
3723 {
3724   checkAllocated();
3725   int nbOfComp=getNumberOfComponents();
3726   if(nbOfComp!=6)
3727     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3728   DataArrayDouble *ret=DataArrayDouble::New();
3729   int nbOfTuple=getNumberOfTuples();
3730   ret->alloc(nbOfTuple,3);
3731   const double *src=getConstPointer();
3732   double *dest=ret->getPointer();
3733   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3734     INTERP_KERNEL::computeEigenValues6(src,dest);
3735   return ret;
3736 }
3737
3738 /*!
3739  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3740  * \a this array, which contains 6 components.
3741  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3742  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3743  *          corresponding tuple of \a this array.
3744  *          The caller is to delete this result array using decrRef() as it is no more
3745  *          needed.
3746  *  \throw If \a this->getNumberOfComponents() != 6.
3747  */
3748 DataArrayDouble *DataArrayDouble::eigenVectors() const
3749 {
3750   checkAllocated();
3751   int nbOfComp=getNumberOfComponents();
3752   if(nbOfComp!=6)
3753     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3754   DataArrayDouble *ret=DataArrayDouble::New();
3755   int nbOfTuple=getNumberOfTuples();
3756   ret->alloc(nbOfTuple,9);
3757   const double *src=getConstPointer();
3758   double *dest=ret->getPointer();
3759   for(int i=0;i<nbOfTuple;i++,src+=6)
3760     {
3761       double tmp[3];
3762       INTERP_KERNEL::computeEigenValues6(src,tmp);
3763       for(int j=0;j<3;j++,dest+=3)
3764         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3765     }
3766   return ret;
3767 }
3768
3769 /*!
3770  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3771  * array, which contains either 4, 6 or 9 components. The case of 6 components
3772  * corresponds to that of the upper triangular matrix.
3773  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3774  *          same number of components as \a this one, whose each tuple is the inverse
3775  *          matrix of the matrix of corresponding tuple of \a this array. 
3776  *          The caller is to delete this result array using decrRef() as it is no more
3777  *          needed. 
3778  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3779  */
3780 DataArrayDouble *DataArrayDouble::inverse() const
3781 {
3782   checkAllocated();
3783   int nbOfComp=getNumberOfComponents();
3784   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3785     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3786   DataArrayDouble *ret=DataArrayDouble::New();
3787   int nbOfTuple=getNumberOfTuples();
3788   ret->alloc(nbOfTuple,nbOfComp);
3789   const double *src=getConstPointer();
3790   double *dest=ret->getPointer();
3791   if(nbOfComp==6)
3792     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3793       {
3794         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];
3795         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3796         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3797         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3798         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3799         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3800         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3801       }
3802   else if(nbOfComp==4)
3803     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3804       {
3805         double det=src[0]*src[3]-src[1]*src[2];
3806         dest[0]=src[3]/det;
3807         dest[1]=-src[1]/det;
3808         dest[2]=-src[2]/det;
3809         dest[3]=src[0]/det;
3810       }
3811   else
3812     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3813       {
3814         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];
3815         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3816         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3817         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3818         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3819         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3820         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3821         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3822         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3823         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3824       }
3825   return ret;
3826 }
3827
3828 /*!
3829  * Computes the trace of every matrix defined by the tuple of \a this
3830  * array, which contains either 4, 6 or 9 components. The case of 6 components
3831  * corresponds to that of the upper triangular matrix.
3832  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3833  *          1 component, whose each tuple is the trace of
3834  *          the matrix of corresponding tuple of \a this array. 
3835  *          The caller is to delete this result array using decrRef() as it is no more
3836  *          needed. 
3837  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3838  */
3839 DataArrayDouble *DataArrayDouble::trace() const
3840 {
3841   checkAllocated();
3842   int nbOfComp=getNumberOfComponents();
3843   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3844     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3845   DataArrayDouble *ret=DataArrayDouble::New();
3846   int nbOfTuple=getNumberOfTuples();
3847   ret->alloc(nbOfTuple,1);
3848   const double *src=getConstPointer();
3849   double *dest=ret->getPointer();
3850   if(nbOfComp==6)
3851     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3852       *dest=src[0]+src[1]+src[2];
3853   else if(nbOfComp==4)
3854     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3855       *dest=src[0]+src[3];
3856   else
3857     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3858       *dest=src[0]+src[4]+src[8];
3859   return ret;
3860 }
3861
3862 /*!
3863  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3864  * \a this array, which contains 6 components.
3865  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3866  *          same number of components and tuples as \a this array.
3867  *          The caller is to delete this result array using decrRef() as it is no more
3868  *          needed.
3869  *  \throw If \a this->getNumberOfComponents() != 6.
3870  */
3871 DataArrayDouble *DataArrayDouble::deviator() const
3872 {
3873   checkAllocated();
3874   int nbOfComp=getNumberOfComponents();
3875   if(nbOfComp!=6)
3876     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3877   DataArrayDouble *ret=DataArrayDouble::New();
3878   int nbOfTuple=getNumberOfTuples();
3879   ret->alloc(nbOfTuple,6);
3880   const double *src=getConstPointer();
3881   double *dest=ret->getPointer();
3882   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3883     {
3884       double tr=(src[0]+src[1]+src[2])/3.;
3885       dest[0]=src[0]-tr;
3886       dest[1]=src[1]-tr;
3887       dest[2]=src[2]-tr;
3888       dest[3]=src[3];
3889       dest[4]=src[4];
3890       dest[5]=src[5];
3891     }
3892   return ret;
3893 }
3894
3895 /*!
3896  * Computes the magnitude of every vector defined by the tuple of
3897  * \a this array.
3898  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3899  *          same number of tuples as \a this array and one component.
3900  *          The caller is to delete this result array using decrRef() as it is no more
3901  *          needed.
3902  *  \throw If \a this is not allocated.
3903  */
3904 DataArrayDouble *DataArrayDouble::magnitude() const
3905 {
3906   checkAllocated();
3907   int nbOfComp=getNumberOfComponents();
3908   DataArrayDouble *ret=DataArrayDouble::New();
3909   int nbOfTuple=getNumberOfTuples();
3910   ret->alloc(nbOfTuple,1);
3911   const double *src=getConstPointer();
3912   double *dest=ret->getPointer();
3913   for(int i=0;i<nbOfTuple;i++,dest++)
3914     {
3915       double sum=0.;
3916       for(int j=0;j<nbOfComp;j++,src++)
3917         sum+=(*src)*(*src);
3918       *dest=sqrt(sum);
3919     }
3920   return ret;
3921 }
3922
3923 /*!
3924  * Computes for each tuple the sum of number of components values in the tuple and return it.
3925  * 
3926  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3927  *          same number of tuples as \a this array and one component.
3928  *          The caller is to delete this result array using decrRef() as it is no more
3929  *          needed.
3930  *  \throw If \a this is not allocated.
3931  */
3932 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3933 {
3934   checkAllocated();
3935   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3936   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3937   ret->alloc(nbOfTuple,1);
3938   const double *src(getConstPointer());
3939   double *dest(ret->getPointer());
3940   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3941     *dest=std::accumulate(src,src+nbOfComp,0.);
3942   return ret.retn();
3943 }
3944
3945 /*!
3946  * Computes the maximal value within every tuple of \a this array.
3947  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3948  *          same number of tuples as \a this array and one component.
3949  *          The caller is to delete this result array using decrRef() as it is no more
3950  *          needed.
3951  *  \throw If \a this is not allocated.
3952  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3953  */
3954 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3955 {
3956   checkAllocated();
3957   int nbOfComp=getNumberOfComponents();
3958   MEDCouplingAutoRefCountObjectPtr<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++,src+=nbOfComp)
3964     *dest=*std::max_element(src,src+nbOfComp);
3965   return ret.retn();
3966 }
3967
3968 /*!
3969  * Computes the maximal value within every tuple of \a this array and it returns the first component
3970  * id for each tuple that corresponds to the maximal value within the tuple.
3971  * 
3972  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3973  *          same number of tuples and only one component.
3974  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3975  *          same number of tuples as \a this array and one component.
3976  *          The caller is to delete this result array using decrRef() as it is no more
3977  *          needed.
3978  *  \throw If \a this is not allocated.
3979  *  \sa DataArrayDouble::maxPerTuple
3980  */
3981 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3982 {
3983   checkAllocated();
3984   int nbOfComp=getNumberOfComponents();
3985   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3986   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3987   int nbOfTuple=getNumberOfTuples();
3988   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3989   const double *src=getConstPointer();
3990   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3991   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3992     {
3993       const double *loc=std::max_element(src,src+nbOfComp);
3994       *dest=*loc;
3995       *dest1=(int)std::distance(src,loc);
3996     }
3997   compoIdOfMaxPerTuple=ret1.retn();
3998   return ret0.retn();
3999 }
4000
4001 /*!
4002  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
4003  * \n This returned array contains the euclidian distance for each tuple in \a this. 
4004  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
4005  * \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)
4006  *
4007  * \warning use this method with care because it can leads to big amount of consumed memory !
4008  * 
4009  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4010  *
4011  * \throw If \a this is not allocated.
4012  *
4013  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
4014  */
4015 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
4016 {
4017   checkAllocated();
4018   int nbOfComp=getNumberOfComponents();
4019   int nbOfTuples=getNumberOfTuples();
4020   const double *inData=getConstPointer();
4021   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4022   ret->alloc(nbOfTuples*nbOfTuples,1);
4023   double *outData=ret->getPointer();
4024   for(int i=0;i<nbOfTuples;i++)
4025     {
4026       outData[i*nbOfTuples+i]=0.;
4027       for(int j=i+1;j<nbOfTuples;j++)
4028         {
4029           double dist=0.;
4030           for(int k=0;k<nbOfComp;k++)
4031             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4032           dist=sqrt(dist);
4033           outData[i*nbOfTuples+j]=dist;
4034           outData[j*nbOfTuples+i]=dist;
4035         }
4036     }
4037   return ret.retn();
4038 }
4039
4040 /*!
4041  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4042  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4043  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4044  * \n Output rectangular matrix is sorted along rows.
4045  * \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)
4046  *
4047  * \warning use this method with care because it can leads to big amount of consumed memory !
4048  * 
4049  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4050  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4051  *
4052  * \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.
4053  *
4054  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4055  */
4056 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4057 {
4058   if(!other)
4059     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4060   checkAllocated();
4061   other->checkAllocated();
4062   int nbOfComp=getNumberOfComponents();
4063   int otherNbOfComp=other->getNumberOfComponents();
4064   if(nbOfComp!=otherNbOfComp)
4065     {
4066       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4067       throw INTERP_KERNEL::Exception(oss.str().c_str());
4068     }
4069   int nbOfTuples=getNumberOfTuples();
4070   int otherNbOfTuples=other->getNumberOfTuples();
4071   const double *inData=getConstPointer();
4072   const double *inDataOther=other->getConstPointer();
4073   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4074   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4075   double *outData=ret->getPointer();
4076   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4077     {
4078       for(int j=0;j<nbOfTuples;j++)
4079         {
4080           double dist=0.;
4081           for(int k=0;k<nbOfComp;k++)
4082             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4083           dist=sqrt(dist);
4084           outData[i*nbOfTuples+j]=dist;
4085         }
4086     }
4087   return ret.retn();
4088 }
4089
4090 /*!
4091  * Sorts value within every tuple of \a this array.
4092  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4093  *              in descending order.
4094  *  \throw If \a this is not allocated.
4095  */
4096 void DataArrayDouble::sortPerTuple(bool asc)
4097 {
4098   checkAllocated();
4099   double *pt=getPointer();
4100   int nbOfTuple=getNumberOfTuples();
4101   int nbOfComp=getNumberOfComponents();
4102   if(asc)
4103     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4104       std::sort(pt,pt+nbOfComp);
4105   else
4106     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4107       std::sort(pt,pt+nbOfComp,std::greater<double>());
4108   declareAsNew();
4109 }
4110
4111 /*!
4112  * Converts every value of \a this array to its absolute value.
4113  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4114  * should be called instead.
4115  *
4116  * \throw If \a this is not allocated.
4117  * \sa DataArrayDouble::computeAbs
4118  */
4119 void DataArrayDouble::abs()
4120 {
4121   checkAllocated();
4122   double *ptr(getPointer());
4123   std::size_t nbOfElems(getNbOfElems());
4124   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4125   declareAsNew();
4126 }
4127
4128 /*!
4129  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4130  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4131  *
4132  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4133  *         same number of tuples and component as \a this array.
4134  *         The caller is to delete this result array using decrRef() as it is no more
4135  *         needed.
4136  * \throw If \a this is not allocated.
4137  * \sa DataArrayDouble::abs
4138  */
4139 DataArrayDouble *DataArrayDouble::computeAbs() const
4140 {
4141   checkAllocated();
4142   DataArrayDouble *newArr(DataArrayDouble::New());
4143   int nbOfTuples(getNumberOfTuples());
4144   int nbOfComp(getNumberOfComponents());
4145   newArr->alloc(nbOfTuples,nbOfComp);
4146   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4147   newArr->copyStringInfoFrom(*this);
4148   return newArr;
4149 }
4150
4151 /*!
4152  * Apply a linear function to a given component of \a this array, so that
4153  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4154  *  \param [in] a - the first coefficient of the function.
4155  *  \param [in] b - the second coefficient of the function.
4156  *  \param [in] compoId - the index of component to modify.
4157  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4158  */
4159 void DataArrayDouble::applyLin(double a, double b, int compoId)
4160 {
4161   checkAllocated();
4162   double *ptr(getPointer()+compoId);
4163   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4164   if(compoId<0 || compoId>=nbOfComp)
4165     {
4166       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4167       throw INTERP_KERNEL::Exception(oss.str().c_str());
4168     }
4169   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4170     *ptr=a*(*ptr)+b;
4171   declareAsNew();
4172 }
4173
4174 /*!
4175  * Apply a linear function to all elements of \a this array, so that
4176  * an element _x_ becomes \f$ a * x + b \f$.
4177  *  \param [in] a - the first coefficient of the function.
4178  *  \param [in] b - the second coefficient of the function.
4179  *  \throw If \a this is not allocated.
4180  */
4181 void DataArrayDouble::applyLin(double a, double b)
4182 {
4183   checkAllocated();
4184   double *ptr=getPointer();
4185   std::size_t nbOfElems=getNbOfElems();
4186   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4187     *ptr=a*(*ptr)+b;
4188   declareAsNew();
4189 }
4190
4191 /*!
4192  * Modify all elements of \a this array, so that
4193  * an element _x_ becomes \f$ numerator / x \f$.
4194  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4195  *           array, all elements processed before detection of the zero element remain
4196  *           modified.
4197  *  \param [in] numerator - the numerator used to modify array elements.
4198  *  \throw If \a this is not allocated.
4199  *  \throw If there is an element equal to 0.0 in \a this array.
4200  */
4201 void DataArrayDouble::applyInv(double numerator)
4202 {
4203   checkAllocated();
4204   double *ptr=getPointer();
4205   std::size_t nbOfElems=getNbOfElems();
4206   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4207     {
4208       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4209         {
4210           *ptr=numerator/(*ptr);
4211         }
4212       else
4213         {
4214           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4215           oss << " !";
4216           throw INTERP_KERNEL::Exception(oss.str().c_str());
4217         }
4218     }
4219   declareAsNew();
4220 }
4221
4222 /*!
4223  * Returns a full copy of \a this array except that sign of all elements is reversed.
4224  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4225  *          same number of tuples and component as \a this array.
4226  *          The caller is to delete this result array using decrRef() as it is no more
4227  *          needed.
4228  *  \throw If \a this is not allocated.
4229  */
4230 DataArrayDouble *DataArrayDouble::negate() const
4231 {
4232   checkAllocated();
4233   DataArrayDouble *newArr=DataArrayDouble::New();
4234   int nbOfTuples=getNumberOfTuples();
4235   int nbOfComp=getNumberOfComponents();
4236   newArr->alloc(nbOfTuples,nbOfComp);
4237   const double *cptr=getConstPointer();
4238   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4239   newArr->copyStringInfoFrom(*this);
4240   return newArr;
4241 }
4242
4243 /*!
4244  * Modify all elements of \a this array, so that
4245  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4246  * all values in \a this have to be >= 0 if val is \b not integer.
4247  *  \param [in] val - the value used to apply pow on all array elements.
4248  *  \throw If \a this is not allocated.
4249  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4250  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4251  *           modified.
4252  */
4253 void DataArrayDouble::applyPow(double val)
4254 {
4255   checkAllocated();
4256   double *ptr=getPointer();
4257   std::size_t nbOfElems=getNbOfElems();
4258   int val2=(int)val;
4259   bool isInt=((double)val2)==val;
4260   if(!isInt)
4261     {
4262       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4263         {
4264           if(*ptr>=0)
4265             *ptr=pow(*ptr,val);
4266           else
4267             {
4268               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4269               throw INTERP_KERNEL::Exception(oss.str().c_str());
4270             }
4271         }
4272     }
4273   else
4274     {
4275       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4276         *ptr=pow(*ptr,val2);
4277     }
4278   declareAsNew();
4279 }
4280
4281 /*!
4282  * Modify all elements of \a this array, so that
4283  * an element _x_ becomes \f$ val ^ x \f$.
4284  *  \param [in] val - the value used to apply pow on all array elements.
4285  *  \throw If \a this is not allocated.
4286  *  \throw If \a val < 0.
4287  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4288  *           array, all elements processed before detection of the zero element remain
4289  *           modified.
4290  */
4291 void DataArrayDouble::applyRPow(double val)
4292 {
4293   checkAllocated();
4294   if(val<0.)
4295     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4296   double *ptr=getPointer();
4297   std::size_t nbOfElems=getNbOfElems();
4298   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4299     *ptr=pow(val,*ptr);
4300   declareAsNew();
4301 }
4302
4303 /*!
4304  * Returns a new DataArrayDouble created from \a this one by applying \a
4305  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4306  * For more info see \ref MEDCouplingArrayApplyFunc
4307  *  \param [in] nbOfComp - number of components in the result array.
4308  *  \param [in] func - the \a FunctionToEvaluate declared as 
4309  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4310  *              where \a pos points to the first component of a tuple of \a this array
4311  *              and \a res points to the first component of a tuple of the result array.
4312  *              Note that length (number of components) of \a pos can differ from
4313  *              that of \a res.
4314  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4315  *          same number of tuples as \a this array.
4316  *          The caller is to delete this result array using decrRef() as it is no more
4317  *          needed.
4318  *  \throw If \a this is not allocated.
4319  *  \throw If \a func returns \a false.
4320  */
4321 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4322 {
4323   checkAllocated();
4324   DataArrayDouble *newArr=DataArrayDouble::New();
4325   int nbOfTuples=getNumberOfTuples();
4326   int oldNbOfComp=getNumberOfComponents();
4327   newArr->alloc(nbOfTuples,nbOfComp);
4328   const double *ptr=getConstPointer();
4329   double *ptrToFill=newArr->getPointer();
4330   for(int i=0;i<nbOfTuples;i++)
4331     {
4332       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4333         {
4334           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4335           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4336           oss << ") : Evaluation of function failed !";
4337           newArr->decrRef();
4338           throw INTERP_KERNEL::Exception(oss.str().c_str());
4339         }
4340     }
4341   return newArr;
4342 }
4343
4344 /*!
4345  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4346  * tuple of \a this array. Textual data is not copied.
4347  * For more info see \ref MEDCouplingArrayApplyFunc1.
4348  *  \param [in] nbOfComp - number of components in the result array.
4349  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4350  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4351  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4352  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4353  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4354  *          same number of tuples as \a this array and \a nbOfComp components.
4355  *          The caller is to delete this result array using decrRef() as it is no more
4356  *          needed.
4357  *  \throw If \a this is not allocated.
4358  *  \throw If computing \a func fails.
4359  */
4360 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4361 {
4362   INTERP_KERNEL::ExprParser expr(func);
4363   expr.parse();
4364   std::set<std::string> vars;
4365   expr.getTrueSetOfVars(vars);
4366   std::vector<std::string> varsV(vars.begin(),vars.end());
4367   return applyFunc3(nbOfComp,varsV,func,isSafe);
4368 }
4369
4370 /*!
4371  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4372  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4373  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4374  *
4375  * For more info see \ref MEDCouplingArrayApplyFunc0.
4376  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4377  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4378  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4379  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4380  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4381  *          same number of tuples and components as \a this array.
4382  *          The caller is to delete this result array using decrRef() as it is no more
4383  *          needed.
4384  *  \sa applyFuncOnThis
4385  *  \throw If \a this is not allocated.
4386  *  \throw If computing \a func fails.
4387  */
4388 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4389 {
4390   int nbOfComp(getNumberOfComponents());
4391   if(nbOfComp<=0)
4392     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4393   checkAllocated();
4394   int nbOfTuples(getNumberOfTuples());
4395   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4396   newArr->alloc(nbOfTuples,nbOfComp);
4397   INTERP_KERNEL::ExprParser expr(func);
4398   expr.parse();
4399   std::set<std::string> vars;
4400   expr.getTrueSetOfVars(vars);
4401   if((int)vars.size()>1)
4402     {
4403       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 : ";
4404       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4405       throw INTERP_KERNEL::Exception(oss.str().c_str());
4406     }
4407   if(vars.empty())
4408     {
4409       expr.prepareFastEvaluator();
4410       newArr->rearrange(1);
4411       newArr->fillWithValue(expr.evaluateDouble());
4412       newArr->rearrange(nbOfComp);
4413       return newArr.retn();
4414     }
4415   std::vector<std::string> vars2(vars.begin(),vars.end());
4416   double buff,*ptrToFill(newArr->getPointer());
4417   const double *ptr(begin());
4418   std::vector<double> stck;
4419   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4420   expr.prepareFastEvaluator();
4421   if(!isSafe)
4422     {
4423       for(int i=0;i<nbOfTuples;i++)
4424         {
4425           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4426             {
4427               buff=*ptr;
4428               expr.evaluateDoubleInternal(stck);
4429               *ptrToFill=stck.back();
4430               stck.pop_back();
4431             }
4432         }
4433     }
4434   else
4435     {
4436       for(int i=0;i<nbOfTuples;i++)
4437         {
4438           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4439             {
4440               buff=*ptr;
4441               try
4442               {
4443                   expr.evaluateDoubleInternalSafe(stck);
4444               }
4445               catch(INTERP_KERNEL::Exception& e)
4446               {
4447                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4448                   oss << buff;
4449                   oss << ") : Evaluation of function failed !" << e.what();
4450                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4451               }
4452               *ptrToFill=stck.back();
4453               stck.pop_back();
4454             }
4455         }
4456     }
4457   return newArr.retn();
4458 }
4459
4460 /*!
4461  * This method is a non const method that modify the array in \a this.
4462  * This method only works on one component array. It means that function \a func must
4463  * contain at most one variable.
4464  * This method is a specialization of applyFunc method with one parameter on one component array.
4465  *
4466  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4467  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4468  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4469  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4470  *
4471  * \sa applyFunc
4472  */
4473 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4474 {
4475   int nbOfComp(getNumberOfComponents());
4476   if(nbOfComp<=0)
4477     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4478   checkAllocated();
4479   int nbOfTuples(getNumberOfTuples());
4480   INTERP_KERNEL::ExprParser expr(func);
4481   expr.parse();
4482   std::set<std::string> vars;
4483   expr.getTrueSetOfVars(vars);
4484   if((int)vars.size()>1)
4485     {
4486       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 : ";
4487       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4488       throw INTERP_KERNEL::Exception(oss.str().c_str());
4489     }
4490   if(vars.empty())
4491     {
4492       expr.prepareFastEvaluator();
4493       std::vector<std::string> compInfo(getInfoOnComponents());
4494       rearrange(1);
4495       fillWithValue(expr.evaluateDouble());
4496       rearrange(nbOfComp);
4497       setInfoOnComponents(compInfo);
4498       return ;
4499     }
4500   std::vector<std::string> vars2(vars.begin(),vars.end());
4501   double buff,*ptrToFill(getPointer());
4502   const double *ptr(begin());
4503   std::vector<double> stck;
4504   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4505   expr.prepareFastEvaluator();
4506   if(!isSafe)
4507     {
4508       for(int i=0;i<nbOfTuples;i++)
4509         {
4510           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4511             {
4512               buff=*ptr;
4513               expr.evaluateDoubleInternal(stck);
4514               *ptrToFill=stck.back();
4515               stck.pop_back();
4516             }
4517         }
4518     }
4519   else
4520     {
4521       for(int i=0;i<nbOfTuples;i++)
4522         {
4523           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4524             {
4525               buff=*ptr;
4526               try
4527               {
4528                   expr.evaluateDoubleInternalSafe(stck);
4529               }
4530               catch(INTERP_KERNEL::Exception& e)
4531               {
4532                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4533                   oss << buff;
4534                   oss << ") : Evaluation of function failed !" << e.what();
4535                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4536               }
4537               *ptrToFill=stck.back();
4538               stck.pop_back();
4539             }
4540         }
4541     }
4542 }
4543
4544 /*!
4545  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4546  * tuple of \a this array. Textual data is not copied.
4547  * For more info see \ref MEDCouplingArrayApplyFunc2.
4548  *  \param [in] nbOfComp - number of components in the result array.
4549  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4550  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4551  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4552  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4553  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4554  *          same number of tuples as \a this array.
4555  *          The caller is to delete this result array using decrRef() as it is no more
4556  *          needed.
4557  *  \throw If \a this is not allocated.
4558  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4559  *  \throw If computing \a func fails.
4560  */
4561 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const
4562 {
4563   return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe);
4564 }
4565
4566 /*!
4567  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4568  * tuple of \a this array. Textual data is not copied.
4569  * For more info see \ref MEDCouplingArrayApplyFunc3.
4570  *  \param [in] nbOfComp - number of components in the result array.
4571  *  \param [in] varsOrder - sequence of vars defining their order.
4572  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4573  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4574  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4575  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4576  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4577  *          same number of tuples as \a this array.
4578  *          The caller is to delete this result array using decrRef() as it is no more
4579  *          needed.
4580  *  \throw If \a this is not allocated.
4581  *  \throw If \a func contains vars not in \a varsOrder.
4582  *  \throw If computing \a func fails.
4583  */
4584 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4585 {
4586   if(nbOfComp<=0)
4587     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !");
4588   std::vector<std::string> varsOrder2(varsOrder);
4589   int oldNbOfComp(getNumberOfComponents());
4590   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4591     varsOrder2.push_back(std::string());
4592   checkAllocated();
4593   int nbOfTuples(getNumberOfTuples());
4594   INTERP_KERNEL::ExprParser expr(func);
4595   expr.parse();
4596   std::set<std::string> vars;
4597   expr.getTrueSetOfVars(vars);
4598   if((int)vars.size()>oldNbOfComp)
4599     {
4600       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4601       oss << vars.size() << " variables : ";
4602       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4603       throw INTERP_KERNEL::Exception(oss.str().c_str());
4604     }
4605   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4606   newArr->alloc(nbOfTuples,nbOfComp);
4607   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4608   double *buffPtr(buff),*ptrToFill;
4609   std::vector<double> stck;
4610   for(int iComp=0;iComp<nbOfComp;iComp++)
4611     {
4612       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4613       expr.prepareFastEvaluator();
4614       const double *ptr(getConstPointer());
4615       ptrToFill=newArr->getPointer()+iComp;
4616       if(!isSafe)
4617         {
4618           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4619             {
4620               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4621               expr.evaluateDoubleInternal(stck);
4622               *ptrToFill=stck.back();
4623               stck.pop_back();
4624             }
4625         }
4626       else
4627         {
4628           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4629             {
4630               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4631               try
4632               {
4633                   expr.evaluateDoubleInternalSafe(stck);
4634                   *ptrToFill=stck.back();
4635                   stck.pop_back();
4636               }
4637               catch(INTERP_KERNEL::Exception& e)
4638               {
4639                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4640                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4641                   oss << ") : Evaluation of function failed !" << e.what();
4642                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4643               }
4644             }
4645         }
4646     }
4647   return newArr.retn();
4648 }
4649
4650 void DataArrayDouble::applyFuncFast32(const std::string& func)
4651 {
4652   checkAllocated();
4653   INTERP_KERNEL::ExprParser expr(func);
4654   expr.parse();
4655   char *funcStr=expr.compileX86();
4656   MYFUNCPTR funcPtr;
4657   *((void **)&funcPtr)=funcStr;//he he...
4658   //
4659   double *ptr=getPointer();
4660   int nbOfComp=getNumberOfComponents();
4661   int nbOfTuples=getNumberOfTuples();
4662   int nbOfElems=nbOfTuples*nbOfComp;
4663   for(int i=0;i<nbOfElems;i++,ptr++)
4664     *ptr=funcPtr(*ptr);
4665   declareAsNew();
4666 }
4667
4668 void DataArrayDouble::applyFuncFast64(const std::string& func)
4669 {
4670   checkAllocated();
4671   INTERP_KERNEL::ExprParser expr(func);
4672   expr.parse();
4673   char *funcStr=expr.compileX86_64();
4674   MYFUNCPTR funcPtr;
4675   *((void **)&funcPtr)=funcStr;//he he...
4676   //
4677   double *ptr=getPointer();
4678   int nbOfComp=getNumberOfComponents();
4679   int nbOfTuples=getNumberOfTuples();
4680   int nbOfElems=nbOfTuples*nbOfComp;
4681   for(int i=0;i<nbOfElems;i++,ptr++)
4682     *ptr=funcPtr(*ptr);
4683   declareAsNew();
4684 }
4685
4686 DataArrayDoubleIterator *DataArrayDouble::iterator()
4687 {
4688   return new DataArrayDoubleIterator(this);
4689 }
4690
4691 /*!
4692  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4693  * array whose values are within a given range. Textual data is not copied.
4694  *  \param [in] vmin - a lowest acceptable value (included).
4695  *  \param [in] vmax - a greatest acceptable value (included).
4696  *  \return DataArrayInt * - the new instance of DataArrayInt.
4697  *          The caller is to delete this result array using decrRef() as it is no more
4698  *          needed.
4699  *  \throw If \a this->getNumberOfComponents() != 1.
4700  *
4701  *  \sa DataArrayDouble::getIdsNotInRange
4702  *
4703  *  \if ENABLE_EXAMPLES
4704  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4705  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4706  *  \endif
4707  */
4708 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4709 {
4710   checkAllocated();
4711   if(getNumberOfComponents()!=1)
4712     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4713   const double *cptr(begin());
4714   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4715   int nbOfTuples(getNumberOfTuples());
4716   for(int i=0;i<nbOfTuples;i++,cptr++)
4717     if(*cptr>=vmin && *cptr<=vmax)
4718       ret->pushBackSilent(i);
4719   return ret.retn();
4720 }
4721
4722 /*!
4723  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4724  * array whose values are not within a given range. Textual data is not copied.
4725  *  \param [in] vmin - a lowest not acceptable value (excluded).
4726  *  \param [in] vmax - a greatest not acceptable value (excluded).
4727  *  \return DataArrayInt * - the new instance of DataArrayInt.
4728  *          The caller is to delete this result array using decrRef() as it is no more
4729  *          needed.
4730  *  \throw If \a this->getNumberOfComponents() != 1.
4731  *
4732  *  \sa DataArrayDouble::getIdsInRange
4733  */
4734 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4735 {
4736   checkAllocated();
4737   if(getNumberOfComponents()!=1)
4738     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4739   const double *cptr(begin());
4740   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4741   int nbOfTuples(getNumberOfTuples());
4742   for(int i=0;i<nbOfTuples;i++,cptr++)
4743     if(*cptr<vmin || *cptr>vmax)
4744       ret->pushBackSilent(i);
4745   return ret.retn();
4746 }
4747
4748 /*!
4749  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4750  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4751  * the number of component in the result array is same as that of each of given arrays.
4752  * Info on components is copied from the first of the given arrays. Number of components
4753  * in the given arrays must be  the same.
4754  *  \param [in] a1 - an array to include in the result array.
4755  *  \param [in] a2 - another array to include in the result array.
4756  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4757  *          The caller is to delete this result array using decrRef() as it is no more
4758  *          needed.
4759  *  \throw If both \a a1 and \a a2 are NULL.
4760  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4761  */
4762 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4763 {
4764   std::vector<const DataArrayDouble *> tmp(2);
4765   tmp[0]=a1; tmp[1]=a2;
4766   return Aggregate(tmp);
4767 }
4768
4769 /*!
4770  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4771  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4772  * the number of component in the result array is same as that of each of given arrays.
4773  * Info on components is copied from the first of the given arrays. Number of components
4774  * in the given arrays must be  the same.
4775  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4776  * not the object itself.
4777  *  \param [in] arr - a sequence of arrays to include in the result array.
4778  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4779  *          The caller is to delete this result array using decrRef() as it is no more
4780  *          needed.
4781  *  \throw If all arrays within \a arr are NULL.
4782  *  \throw If getNumberOfComponents() of arrays within \a arr.
4783  */
4784 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4785 {
4786   std::vector<const DataArrayDouble *> a;
4787   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4788     if(*it4)
4789       a.push_back(*it4);
4790   if(a.empty())
4791     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4792   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4793   int nbOfComp=(*it)->getNumberOfComponents();
4794   int nbt=(*it++)->getNumberOfTuples();
4795   for(int i=1;it!=a.end();it++,i++)
4796     {
4797       if((*it)->getNumberOfComponents()!=nbOfComp)
4798         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4799       nbt+=(*it)->getNumberOfTuples();
4800     }
4801   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4802   ret->alloc(nbt,nbOfComp);
4803   double *pt=ret->getPointer();
4804   for(it=a.begin();it!=a.end();it++)
4805     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4806   ret->copyStringInfoFrom(*(a[0]));
4807   return ret.retn();
4808 }
4809
4810 /*!
4811  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4812  * of components in the result array is a sum of the number of components of given arrays
4813  * and (2) the number of tuples in the result array is same as that of each of given
4814  * arrays. In other words the i-th tuple of result array includes all components of
4815  * i-th tuples of all given arrays.
4816  * Number of tuples in the given arrays must be  the same.
4817  *  \param [in] a1 - an array to include in the result array.
4818  *  \param [in] a2 - another array to include in the result array.
4819  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4820  *          The caller is to delete this result array using decrRef() as it is no more
4821  *          needed.
4822  *  \throw If both \a a1 and \a a2 are NULL.
4823  *  \throw If any given array is not allocated.
4824  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4825  */
4826 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4827 {
4828   std::vector<const DataArrayDouble *> arr(2);
4829   arr[0]=a1; arr[1]=a2;
4830   return Meld(arr);
4831 }
4832
4833 /*!
4834  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4835  * of components in the result array is a sum of the number of components of given arrays
4836  * and (2) the number of tuples in the result array is same as that of each of given
4837  * arrays. In other words the i-th tuple of result array includes all components of
4838  * i-th tuples of all given arrays.
4839  * Number of tuples in the given arrays must be  the same.
4840  *  \param [in] arr - a sequence of arrays to include in the result array.
4841  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4842  *          The caller is to delete this result array using decrRef() as it is no more
4843  *          needed.
4844  *  \throw If all arrays within \a arr are NULL.
4845  *  \throw If any given array is not allocated.
4846  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4847  */
4848 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4849 {
4850   std::vector<const DataArrayDouble *> a;
4851   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4852     if(*it4)
4853       a.push_back(*it4);
4854   if(a.empty())
4855     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4856   std::vector<const DataArrayDouble *>::const_iterator it;
4857   for(it=a.begin();it!=a.end();it++)
4858     (*it)->checkAllocated();
4859   it=a.begin();
4860   int nbOfTuples=(*it)->getNumberOfTuples();
4861   std::vector<int> nbc(a.size());
4862   std::vector<const double *> pts(a.size());
4863   nbc[0]=(*it)->getNumberOfComponents();
4864   pts[0]=(*it++)->getConstPointer();
4865   for(int i=1;it!=a.end();it++,i++)
4866     {
4867       if(nbOfTuples!=(*it)->getNumberOfTuples())
4868         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4869       nbc[i]=(*it)->getNumberOfComponents();
4870       pts[i]=(*it)->getConstPointer();
4871     }
4872   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4873   DataArrayDouble *ret=DataArrayDouble::New();
4874   ret->alloc(nbOfTuples,totalNbOfComp);
4875   double *retPtr=ret->getPointer();
4876   for(int i=0;i<nbOfTuples;i++)
4877     for(int j=0;j<(int)a.size();j++)
4878       {
4879         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4880         pts[j]+=nbc[j];
4881       }
4882   int k=0;
4883   for(int i=0;i<(int)a.size();i++)
4884     for(int j=0;j<nbc[i];j++,k++)
4885       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4886   return ret;
4887 }
4888
4889 /*!
4890  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4891  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4892  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4893  * Info on components and name is copied from the first of the given arrays.
4894  * Number of tuples and components in the given arrays must be the same.
4895  *  \param [in] a1 - a given array.
4896  *  \param [in] a2 - another given array.
4897  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4898  *          The caller is to delete this result array using decrRef() as it is no more
4899  *          needed.
4900  *  \throw If either \a a1 or \a a2 is NULL.
4901  *  \throw If any given array is not allocated.
4902  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4903  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4904  */
4905 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4906 {
4907   if(!a1 || !a2)
4908     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4909   a1->checkAllocated();
4910   a2->checkAllocated();
4911   int nbOfComp=a1->getNumberOfComponents();
4912   if(nbOfComp!=a2->getNumberOfComponents())
4913     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4914   int nbOfTuple=a1->getNumberOfTuples();
4915   if(nbOfTuple!=a2->getNumberOfTuples())
4916     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4917   DataArrayDouble *ret=DataArrayDouble::New();
4918   ret->alloc(nbOfTuple,1);
4919   double *retPtr=ret->getPointer();
4920   const double *a1Ptr=a1->getConstPointer();
4921   const double *a2Ptr=a2->getConstPointer();
4922   for(int i=0;i<nbOfTuple;i++)
4923     {
4924       double sum=0.;
4925       for(int j=0;j<nbOfComp;j++)
4926         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4927       retPtr[i]=sum;
4928     }
4929   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4930   ret->setName(a1->getName());
4931   return ret;
4932 }
4933
4934 /*!
4935  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4936  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4937  * product of two vectors defined by the i-th tuples of given arrays.
4938  * Info on components is copied from the first of the given arrays.
4939  * Number of tuples in the given arrays must be the same.
4940  * Number of components in the given arrays must be 3.
4941  *  \param [in] a1 - a given array.
4942  *  \param [in] a2 - another given array.
4943  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4944  *          The caller is to delete this result array using decrRef() as it is no more
4945  *          needed.
4946  *  \throw If either \a a1 or \a a2 is NULL.
4947  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4948  *  \throw If \a a1->getNumberOfComponents() != 3
4949  *  \throw If \a a2->getNumberOfComponents() != 3
4950  */
4951 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4952 {
4953   if(!a1 || !a2)
4954     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4955   int nbOfComp=a1->getNumberOfComponents();
4956   if(nbOfComp!=a2->getNumberOfComponents())
4957     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4958   if(nbOfComp!=3)
4959     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4960   int nbOfTuple=a1->getNumberOfTuples();
4961   if(nbOfTuple!=a2->getNumberOfTuples())
4962     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4963   DataArrayDouble *ret=DataArrayDouble::New();
4964   ret->alloc(nbOfTuple,3);
4965   double *retPtr=ret->getPointer();
4966   const double *a1Ptr=a1->getConstPointer();
4967   const double *a2Ptr=a2->getConstPointer();
4968   for(int i=0;i<nbOfTuple;i++)
4969     {
4970       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4971       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4972       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4973     }
4974   ret->copyStringInfoFrom(*a1);
4975   return ret;
4976 }
4977
4978 /*!
4979  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4980  * Info on components is copied from the first of the given arrays.
4981  * Number of tuples and components in the given arrays must be the same.
4982  *  \param [in] a1 - an array to compare values with another one.
4983  *  \param [in] a2 - another array to compare values with the first one.
4984  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4985  *          The caller is to delete this result array using decrRef() as it is no more
4986  *          needed.
4987  *  \throw If either \a a1 or \a a2 is NULL.
4988  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4989  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4990  */
4991 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4992 {
4993   if(!a1 || !a2)
4994     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4995   int nbOfComp=a1->getNumberOfComponents();
4996   if(nbOfComp!=a2->getNumberOfComponents())
4997     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4998   int nbOfTuple=a1->getNumberOfTuples();
4999   if(nbOfTuple!=a2->getNumberOfTuples())
5000     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
5001   DataArrayDouble *ret=DataArrayDouble::New();
5002   ret->alloc(nbOfTuple,nbOfComp);
5003   double *retPtr=ret->getPointer();
5004   const double *a1Ptr=a1->getConstPointer();
5005   const double *a2Ptr=a2->getConstPointer();
5006   int nbElem=nbOfTuple*nbOfComp;
5007   for(int i=0;i<nbElem;i++)
5008     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
5009   ret->copyStringInfoFrom(*a1);
5010   return ret;
5011 }
5012
5013 /*!
5014  * Returns a new DataArrayDouble containing minimal values of two given arrays.
5015  * Info on components is copied from the first of the given arrays.
5016  * Number of tuples and components in the given arrays must be the same.
5017  *  \param [in] a1 - an array to compare values with another one.
5018  *  \param [in] a2 - another array to compare values with the first one.
5019  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5020  *          The caller is to delete this result array using decrRef() as it is no more
5021  *          needed.
5022  *  \throw If either \a a1 or \a a2 is NULL.
5023  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5024  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5025  */
5026 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
5027 {
5028   if(!a1 || !a2)
5029     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
5030   int nbOfComp=a1->getNumberOfComponents();
5031   if(nbOfComp!=a2->getNumberOfComponents())
5032     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5033   int nbOfTuple=a1->getNumberOfTuples();
5034   if(nbOfTuple!=a2->getNumberOfTuples())
5035     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5036   DataArrayDouble *ret=DataArrayDouble::New();
5037   ret->alloc(nbOfTuple,nbOfComp);
5038   double *retPtr=ret->getPointer();
5039   const double *a1Ptr=a1->getConstPointer();
5040   const double *a2Ptr=a2->getConstPointer();
5041   int nbElem=nbOfTuple*nbOfComp;
5042   for(int i=0;i<nbElem;i++)
5043     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5044   ret->copyStringInfoFrom(*a1);
5045   return ret;
5046 }
5047
5048 /*!
5049  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5050  * valid cases.
5051  * 1.  The arrays have same number of tuples and components. Then each value of
5052  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5053  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5054  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5055  *   component. Then
5056  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5057  * 3.  The arrays have same number of components and one array, say _a2_, has one
5058  *   tuple. Then
5059  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5060  *
5061  * Info on components is copied either from the first array (in the first case) or from
5062  * the array with maximal number of elements (getNbOfElems()).
5063  *  \param [in] a1 - an array to sum up.
5064  *  \param [in] a2 - another array to sum up.
5065  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5066  *          The caller is to delete this result array using decrRef() as it is no more
5067  *          needed.
5068  *  \throw If either \a a1 or \a a2 is NULL.
5069  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5070  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5071  *         none of them has number of tuples or components equal to 1.
5072  */
5073 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5074 {
5075   if(!a1 || !a2)
5076     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5077   int nbOfTuple=a1->getNumberOfTuples();
5078   int nbOfTuple2=a2->getNumberOfTuples();
5079   int nbOfComp=a1->getNumberOfComponents();
5080   int nbOfComp2=a2->getNumberOfComponents();
5081   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5082   if(nbOfTuple==nbOfTuple2)
5083     {
5084       if(nbOfComp==nbOfComp2)
5085         {
5086           ret=DataArrayDouble::New();
5087           ret->alloc(nbOfTuple,nbOfComp);
5088           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5089           ret->copyStringInfoFrom(*a1);
5090         }
5091       else
5092         {
5093           int nbOfCompMin,nbOfCompMax;
5094           const DataArrayDouble *aMin, *aMax;
5095           if(nbOfComp>nbOfComp2)
5096             {
5097               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5098               aMin=a2; aMax=a1;
5099             }
5100           else
5101             {
5102               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5103               aMin=a1; aMax=a2;
5104             }
5105           if(nbOfCompMin==1)
5106             {
5107               ret=DataArrayDouble::New();
5108               ret->alloc(nbOfTuple,nbOfCompMax);
5109               const double *aMinPtr=aMin->getConstPointer();
5110               const double *aMaxPtr=aMax->getConstPointer();
5111               double *res=ret->getPointer();
5112               for(int i=0;i<nbOfTuple;i++)
5113                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5114               ret->copyStringInfoFrom(*aMax);
5115             }
5116           else
5117             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5118         }
5119     }
5120   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5121     {
5122       if(nbOfComp==nbOfComp2)
5123         {
5124           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5125           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5126           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5127           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5128           ret=DataArrayDouble::New();
5129           ret->alloc(nbOfTupleMax,nbOfComp);
5130           double *res=ret->getPointer();
5131           for(int i=0;i<nbOfTupleMax;i++)
5132             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5133           ret->copyStringInfoFrom(*aMax);
5134         }
5135       else
5136         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5137     }
5138   else
5139     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5140   return ret.retn();
5141 }
5142
5143 /*!
5144  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5145  * valid cases.
5146  * 1.  The arrays have same number of tuples and components. Then each value of
5147  *   \a other array is added to the corresponding value of \a this array, i.e.:
5148  *   _a_ [ i, j ] += _other_ [ i, j ].
5149  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5150  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5151  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5152  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5153  *
5154  *  \param [in] other - an array to add to \a this one.
5155  *  \throw If \a other is NULL.
5156  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5157  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5158  *         \a other has number of both tuples and components not equal to 1.
5159  */
5160 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5161 {
5162   if(!other)
5163     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5164   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5165   checkAllocated();
5166   other->checkAllocated();
5167   int nbOfTuple=getNumberOfTuples();
5168   int nbOfTuple2=other->getNumberOfTuples();
5169   int nbOfComp=getNumberOfComponents();
5170   int nbOfComp2=other->getNumberOfComponents();
5171   if(nbOfTuple==nbOfTuple2)
5172     {
5173       if(nbOfComp==nbOfComp2)
5174         {
5175           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5176         }
5177       else if(nbOfComp2==1)
5178         {
5179           double *ptr=getPointer();
5180           const double *ptrc=other->getConstPointer();
5181           for(int i=0;i<nbOfTuple;i++)
5182             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5183         }
5184       else
5185         throw INTERP_KERNEL::Exception(msg);
5186     }
5187   else if(nbOfTuple2==1)
5188     {
5189       if(nbOfComp2==nbOfComp)
5190         {
5191           double *ptr=getPointer();
5192           const double *ptrc=other->getConstPointer();
5193           for(int i=0;i<nbOfTuple;i++)
5194             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5195         }
5196       else
5197         throw INTERP_KERNEL::Exception(msg);
5198     }
5199   else
5200     throw INTERP_KERNEL::Exception(msg);
5201   declareAsNew();
5202 }
5203
5204 /*!
5205  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5206  * valid cases.
5207  * 1.  The arrays have same number of tuples and components. Then each value of
5208  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5209  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5210  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5211  *   component. Then
5212  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5213  * 3.  The arrays have same number of components and one array, say _a2_, has one
5214  *   tuple. Then
5215  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5216  *
5217  * Info on components is copied either from the first array (in the first case) or from
5218  * the array with maximal number of elements (getNbOfElems()).
5219  *  \param [in] a1 - an array to subtract from.
5220  *  \param [in] a2 - an array to subtract.
5221  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5222  *          The caller is to delete this result array using decrRef() as it is no more
5223  *          needed.
5224  *  \throw If either \a a1 or \a a2 is NULL.
5225  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5226  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5227  *         none of them has number of tuples or components equal to 1.
5228  */
5229 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5230 {
5231   if(!a1 || !a2)
5232     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5233   int nbOfTuple1=a1->getNumberOfTuples();
5234   int nbOfTuple2=a2->getNumberOfTuples();
5235   int nbOfComp1=a1->getNumberOfComponents();
5236   int nbOfComp2=a2->getNumberOfComponents();
5237   if(nbOfTuple2==nbOfTuple1)
5238     {
5239       if(nbOfComp1==nbOfComp2)
5240         {
5241           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5242           ret->alloc(nbOfTuple2,nbOfComp1);
5243           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5244           ret->copyStringInfoFrom(*a1);
5245           return ret.retn();
5246         }
5247       else if(nbOfComp2==1)
5248         {
5249           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5250           ret->alloc(nbOfTuple1,nbOfComp1);
5251           const double *a2Ptr=a2->getConstPointer();
5252           const double *a1Ptr=a1->getConstPointer();
5253           double *res=ret->getPointer();
5254           for(int i=0;i<nbOfTuple1;i++)
5255             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5256           ret->copyStringInfoFrom(*a1);
5257           return ret.retn();
5258         }
5259       else
5260         {
5261           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5262           return 0;
5263         }
5264     }
5265   else if(nbOfTuple2==1)
5266     {
5267       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5268       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5269       ret->alloc(nbOfTuple1,nbOfComp1);
5270       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5271       double *pt=ret->getPointer();
5272       for(int i=0;i<nbOfTuple1;i++)
5273         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5274       ret->copyStringInfoFrom(*a1);
5275       return ret.retn();
5276     }
5277   else
5278     {
5279       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5280       return 0;
5281     }
5282 }
5283
5284 /*!
5285  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5286  * valid cases.
5287  * 1.  The arrays have same number of tuples and components. Then each value of
5288  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5289  *   _a_ [ i, j ] -= _other_ [ i, j ].
5290  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5291  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5292  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5293  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5294  *
5295  *  \param [in] other - an array to subtract from \a this one.
5296  *  \throw If \a other is NULL.
5297  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5298  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5299  *         \a other has number of both tuples and components not equal to 1.
5300  */
5301 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5302 {
5303   if(!other)
5304     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5305   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5306   checkAllocated();
5307   other->checkAllocated();
5308   int nbOfTuple=getNumberOfTuples();
5309   int nbOfTuple2=other->getNumberOfTuples();
5310   int nbOfComp=getNumberOfComponents();
5311   int nbOfComp2=other->getNumberOfComponents();
5312   if(nbOfTuple==nbOfTuple2)
5313     {
5314       if(nbOfComp==nbOfComp2)
5315         {
5316           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5317         }
5318       else if(nbOfComp2==1)
5319         {
5320           double *ptr=getPointer();
5321           const double *ptrc=other->getConstPointer();
5322           for(int i=0;i<nbOfTuple;i++)
5323             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5324         }
5325       else
5326         throw INTERP_KERNEL::Exception(msg);
5327     }
5328   else if(nbOfTuple2==1)
5329     {
5330       if(nbOfComp2==nbOfComp)
5331         {
5332           double *ptr=getPointer();
5333           const double *ptrc=other->getConstPointer();
5334           for(int i=0;i<nbOfTuple;i++)
5335             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5336         }
5337       else
5338         throw INTERP_KERNEL::Exception(msg);
5339     }
5340   else
5341     throw INTERP_KERNEL::Exception(msg);
5342   declareAsNew();
5343 }
5344
5345 /*!
5346  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5347  * valid cases.
5348  * 1.  The arrays have same number of tuples and components. Then each value of
5349  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5350  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5351  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5352  *   component. Then
5353  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5354  * 3.  The arrays have same number of components and one array, say _a2_, has one
5355  *   tuple. Then
5356  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5357  *
5358  * Info on components is copied either from the first array (in the first case) or from
5359  * the array with maximal number of elements (getNbOfElems()).
5360  *  \param [in] a1 - a factor array.
5361  *  \param [in] a2 - another factor array.
5362  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5363  *          The caller is to delete this result array using decrRef() as it is no more
5364  *          needed.
5365  *  \throw If either \a a1 or \a a2 is NULL.
5366  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5367  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5368  *         none of them has number of tuples or components equal to 1.
5369  */
5370 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5371 {
5372   if(!a1 || !a2)
5373     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5374   int nbOfTuple=a1->getNumberOfTuples();
5375   int nbOfTuple2=a2->getNumberOfTuples();
5376   int nbOfComp=a1->getNumberOfComponents();
5377   int nbOfComp2=a2->getNumberOfComponents();
5378   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5379   if(nbOfTuple==nbOfTuple2)
5380     {
5381       if(nbOfComp==nbOfComp2)
5382         {
5383           ret=DataArrayDouble::New();
5384           ret->alloc(nbOfTuple,nbOfComp);
5385           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5386           ret->copyStringInfoFrom(*a1);
5387         }
5388       else
5389         {
5390           int nbOfCompMin,nbOfCompMax;
5391           const DataArrayDouble *aMin, *aMax;
5392           if(nbOfComp>nbOfComp2)
5393             {
5394               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5395               aMin=a2; aMax=a1;
5396             }
5397           else
5398             {
5399               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5400               aMin=a1; aMax=a2;
5401             }
5402           if(nbOfCompMin==1)
5403             {
5404               ret=DataArrayDouble::New();
5405               ret->alloc(nbOfTuple,nbOfCompMax);
5406               const double *aMinPtr=aMin->getConstPointer();
5407               const double *aMaxPtr=aMax->getConstPointer();
5408               double *res=ret->getPointer();
5409               for(int i=0;i<nbOfTuple;i++)
5410                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5411               ret->copyStringInfoFrom(*aMax);
5412             }
5413           else
5414             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5415         }
5416     }
5417   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5418     {
5419       if(nbOfComp==nbOfComp2)
5420         {
5421           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5422           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5423           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5424           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5425           ret=DataArrayDouble::New();
5426           ret->alloc(nbOfTupleMax,nbOfComp);
5427           double *res=ret->getPointer();
5428           for(int i=0;i<nbOfTupleMax;i++)
5429             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5430           ret->copyStringInfoFrom(*aMax);
5431         }
5432       else
5433         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5434     }
5435   else
5436     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5437   return ret.retn();
5438 }
5439
5440 /*!
5441  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5442  * valid cases.
5443  * 1.  The arrays have same number of tuples and components. Then each value of
5444  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5445  *   _this_ [ i, j ] *= _other_ [ i, j ].
5446  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5447  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5448  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5449  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5450  *
5451  *  \param [in] other - an array to multiply to \a this one.
5452  *  \throw If \a other is NULL.
5453  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5454  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5455  *         \a other has number of both tuples and components not equal to 1.
5456  */
5457 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5458 {
5459   if(!other)
5460     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5461   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5462   checkAllocated();
5463   other->checkAllocated();
5464   int nbOfTuple=getNumberOfTuples();
5465   int nbOfTuple2=other->getNumberOfTuples();
5466   int nbOfComp=getNumberOfComponents();
5467   int nbOfComp2=other->getNumberOfComponents();
5468   if(nbOfTuple==nbOfTuple2)
5469     {
5470       if(nbOfComp==nbOfComp2)
5471         {
5472           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5473         }
5474       else if(nbOfComp2==1)
5475         {
5476           double *ptr=getPointer();
5477           const double *ptrc=other->getConstPointer();
5478           for(int i=0;i<nbOfTuple;i++)
5479             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5480         }
5481       else
5482         throw INTERP_KERNEL::Exception(msg);
5483     }
5484   else if(nbOfTuple2==1)
5485     {
5486       if(nbOfComp2==nbOfComp)
5487         {
5488           double *ptr=getPointer();
5489           const double *ptrc=other->getConstPointer();
5490           for(int i=0;i<nbOfTuple;i++)
5491             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5492         }
5493       else
5494         throw INTERP_KERNEL::Exception(msg);
5495     }
5496   else
5497     throw INTERP_KERNEL::Exception(msg);
5498   declareAsNew();
5499 }
5500
5501 /*!
5502  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5503  * valid cases.
5504  * 1.  The arrays have same number of tuples and components. Then each value of
5505  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5506  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5507  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5508  *   component. Then
5509  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5510  * 3.  The arrays have same number of components and one array, say _a2_, has one
5511  *   tuple. Then
5512  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5513  *
5514  * Info on components is copied either from the first array (in the first case) or from
5515  * the array with maximal number of elements (getNbOfElems()).
5516  *  \warning No check of division by zero is performed!
5517  *  \param [in] a1 - a numerator array.
5518  *  \param [in] a2 - a denominator array.
5519  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5520  *          The caller is to delete this result array using decrRef() as it is no more
5521  *          needed.
5522  *  \throw If either \a a1 or \a a2 is NULL.
5523  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5524  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5525  *         none of them has number of tuples or components equal to 1.
5526  */
5527 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5528 {
5529   if(!a1 || !a2)
5530     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5531   int nbOfTuple1=a1->getNumberOfTuples();
5532   int nbOfTuple2=a2->getNumberOfTuples();
5533   int nbOfComp1=a1->getNumberOfComponents();
5534   int nbOfComp2=a2->getNumberOfComponents();
5535   if(nbOfTuple2==nbOfTuple1)
5536     {
5537       if(nbOfComp1==nbOfComp2)
5538         {
5539           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5540           ret->alloc(nbOfTuple2,nbOfComp1);
5541           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5542           ret->copyStringInfoFrom(*a1);
5543           return ret.retn();
5544         }
5545       else if(nbOfComp2==1)
5546         {
5547           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5548           ret->alloc(nbOfTuple1,nbOfComp1);
5549           const double *a2Ptr=a2->getConstPointer();
5550           const double *a1Ptr=a1->getConstPointer();
5551           double *res=ret->getPointer();
5552           for(int i=0;i<nbOfTuple1;i++)
5553             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5554           ret->copyStringInfoFrom(*a1);
5555           return ret.retn();
5556         }
5557       else
5558         {
5559           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5560           return 0;
5561         }
5562     }
5563   else if(nbOfTuple2==1)
5564     {
5565       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5566       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5567       ret->alloc(nbOfTuple1,nbOfComp1);
5568       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5569       double *pt=ret->getPointer();
5570       for(int i=0;i<nbOfTuple1;i++)
5571         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5572       ret->copyStringInfoFrom(*a1);
5573       return ret.retn();
5574     }
5575   else
5576     {
5577       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5578       return 0;
5579     }
5580 }
5581
5582 /*!
5583  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5584  * valid cases.
5585  * 1.  The arrays have same number of tuples and components. Then each value of
5586  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5587  *   _a_ [ i, j ] /= _other_ [ i, j ].
5588  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5589  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5590  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5591  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5592  *
5593  *  \warning No check of division by zero is performed!
5594  *  \param [in] other - an array to divide \a this one by.
5595  *  \throw If \a other is NULL.
5596  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5597  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5598  *         \a other has number of both tuples and components not equal to 1.
5599  */
5600 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5601 {
5602   if(!other)
5603     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5604   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5605   checkAllocated();
5606   other->checkAllocated();
5607   int nbOfTuple=getNumberOfTuples();
5608   int nbOfTuple2=other->getNumberOfTuples();
5609   int nbOfComp=getNumberOfComponents();
5610   int nbOfComp2=other->getNumberOfComponents();
5611   if(nbOfTuple==nbOfTuple2)
5612     {
5613       if(nbOfComp==nbOfComp2)
5614         {
5615           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5616         }
5617       else if(nbOfComp2==1)
5618         {
5619           double *ptr=getPointer();
5620           const double *ptrc=other->getConstPointer();
5621           for(int i=0;i<nbOfTuple;i++)
5622             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5623         }
5624       else
5625         throw INTERP_KERNEL::Exception(msg);
5626     }
5627   else if(nbOfTuple2==1)
5628     {
5629       if(nbOfComp2==nbOfComp)
5630         {
5631           double *ptr=getPointer();
5632           const double *ptrc=other->getConstPointer();
5633           for(int i=0;i<nbOfTuple;i++)
5634             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5635         }
5636       else
5637         throw INTERP_KERNEL::Exception(msg);
5638     }
5639   else
5640     throw INTERP_KERNEL::Exception(msg);
5641   declareAsNew();
5642 }
5643
5644 /*!
5645  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5646  * valid cases.
5647  *
5648  *  \param [in] a1 - an array to pow up.
5649  *  \param [in] a2 - another array to sum up.
5650  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5651  *          The caller is to delete this result array using decrRef() as it is no more
5652  *          needed.
5653  *  \throw If either \a a1 or \a a2 is NULL.
5654  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5655  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5656  *  \throw If there is a negative value in \a a1.
5657  */
5658 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5659 {
5660   if(!a1 || !a2)
5661     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5662   int nbOfTuple=a1->getNumberOfTuples();
5663   int nbOfTuple2=a2->getNumberOfTuples();
5664   int nbOfComp=a1->getNumberOfComponents();
5665   int nbOfComp2=a2->getNumberOfComponents();
5666   if(nbOfTuple!=nbOfTuple2)
5667     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5668   if(nbOfComp!=1 || nbOfComp2!=1)
5669     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5670   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5671   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5672   double *ptr=ret->getPointer();
5673   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5674     {
5675       if(*ptr1>=0)
5676         {
5677           *ptr=pow(*ptr1,*ptr2);
5678         }
5679       else
5680         {
5681           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5682           throw INTERP_KERNEL::Exception(oss.str().c_str());
5683         }
5684     }
5685   return ret.retn();
5686 }
5687
5688 /*!
5689  * Apply pow on values of another DataArrayDouble to values of \a this one.
5690  *
5691  *  \param [in] other - an array to pow to \a this one.
5692  *  \throw If \a other is NULL.
5693  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5694  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5695  *  \throw If there is a negative value in \a this.
5696  */
5697 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5698 {
5699   if(!other)
5700     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5701   int nbOfTuple=getNumberOfTuples();
5702   int nbOfTuple2=other->getNumberOfTuples();
5703   int nbOfComp=getNumberOfComponents();
5704   int nbOfComp2=other->getNumberOfComponents();
5705   if(nbOfTuple!=nbOfTuple2)
5706     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5707   if(nbOfComp!=1 || nbOfComp2!=1)
5708     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5709   double *ptr=getPointer();
5710   const double *ptrc=other->begin();
5711   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5712     {
5713       if(*ptr>=0)
5714         *ptr=pow(*ptr,*ptrc);
5715       else
5716         {
5717           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5718           throw INTERP_KERNEL::Exception(oss.str().c_str());
5719         }
5720     }
5721   declareAsNew();
5722 }
5723
5724 /*!
5725  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5726  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5727  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5728  *
5729  * \throw if \a this is not allocated.
5730  * \throw if \a this has not exactly one component.
5731  */
5732 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5733 {
5734   checkAllocated();
5735   if(getNumberOfComponents()!=1)
5736     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5737   int nbt(getNumberOfTuples());
5738   std::vector<bool> ret(nbt);
5739   const double *pt(begin());
5740   for(int i=0;i<nbt;i++)
5741     {
5742       if(fabs(pt[i])<eps)
5743         ret[i]=false;
5744       else if(fabs(pt[i]-1.)<eps)
5745         ret[i]=true;
5746       else
5747         {
5748           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5749           throw INTERP_KERNEL::Exception(oss.str().c_str());
5750         }
5751     }
5752   return ret;
5753 }
5754
5755 /*!
5756  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5757  * Server side.
5758  */
5759 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5760 {
5761   tinyInfo.resize(2);
5762   if(isAllocated())
5763     {
5764       tinyInfo[0]=getNumberOfTuples();
5765       tinyInfo[1]=getNumberOfComponents();
5766     }
5767   else
5768     {
5769       tinyInfo[0]=-1;
5770       tinyInfo[1]=-1;
5771     }
5772 }
5773
5774 /*!
5775  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5776  * Server side.
5777  */
5778 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5779 {
5780   if(isAllocated())
5781     {
5782       int nbOfCompo=getNumberOfComponents();
5783       tinyInfo.resize(nbOfCompo+1);
5784       tinyInfo[0]=getName();
5785       for(int i=0;i<nbOfCompo;i++)
5786         tinyInfo[i+1]=getInfoOnComponent(i);
5787     }
5788   else
5789     {
5790       tinyInfo.resize(1);
5791       tinyInfo[0]=getName();
5792     }
5793 }
5794
5795 /*!
5796  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5797  * This method returns if a feeding is needed.
5798  */
5799 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5800 {
5801   int nbOfTuple=tinyInfoI[0];
5802   int nbOfComp=tinyInfoI[1];
5803   if(nbOfTuple!=-1 || nbOfComp!=-1)
5804     {
5805       alloc(nbOfTuple,nbOfComp);
5806       return true;
5807     }
5808   return false;
5809 }
5810
5811 /*!
5812  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5813  */
5814 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5815 {
5816   setName(tinyInfoS[0]);
5817   if(isAllocated())
5818     {
5819       int nbOfCompo=getNumberOfComponents();
5820       for(int i=0;i<nbOfCompo;i++)
5821         setInfoOnComponent(i,tinyInfoS[i+1]);
5822     }
5823 }
5824
5825 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5826 {
5827   if(_da)
5828     {
5829       _da->incrRef();
5830       if(_da->isAllocated())
5831         {
5832           _nb_comp=da->getNumberOfComponents();
5833           _nb_tuple=da->getNumberOfTuples();
5834           _pt=da->getPointer();
5835         }
5836     }
5837 }
5838
5839 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5840 {
5841   if(_da)
5842     _da->decrRef();
5843 }
5844
5845 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5846 {
5847   if(_tuple_id<_nb_tuple)
5848     {
5849       _tuple_id++;
5850       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5851       _pt+=_nb_comp;
5852       return ret;
5853     }
5854   else
5855     return 0;
5856 }
5857
5858 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5859 {
5860 }
5861
5862
5863 std::string DataArrayDoubleTuple::repr() const
5864 {
5865   std::ostringstream oss; oss.precision(17); oss << "(";
5866   for(int i=0;i<_nb_of_compo-1;i++)
5867     oss << _pt[i] << ", ";
5868   oss << _pt[_nb_of_compo-1] << ")";
5869   return oss.str();
5870 }
5871
5872 double DataArrayDoubleTuple::doubleValue() const
5873 {
5874   if(_nb_of_compo==1)
5875     return *_pt;
5876   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5877 }
5878
5879 /*!
5880  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5881  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5882  * 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
5883  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5884  */
5885 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5886 {
5887   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5888     {
5889       DataArrayDouble *ret=DataArrayDouble::New();
5890       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5891       return ret;
5892     }
5893   else
5894     {
5895       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5896       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5897       throw INTERP_KERNEL::Exception(oss.str().c_str());
5898     }
5899 }
5900
5901 /*!
5902  * Returns a new instance of DataArrayInt. The caller is to delete this array
5903  * using decrRef() as it is no more needed. 
5904  */
5905 DataArrayInt *DataArrayInt::New()
5906 {
5907   return new DataArrayInt;
5908 }
5909
5910 /*!
5911  * Checks if raw data is allocated. Read more on the raw data
5912  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5913  *  \return bool - \a true if the raw data is allocated, \a false else.
5914  */
5915 bool DataArrayInt::isAllocated() const
5916 {
5917   return getConstPointer()!=0;
5918 }
5919
5920 /*!
5921  * Checks if raw data is allocated and throws an exception if it is not the case.
5922  *  \throw If the raw data is not allocated.
5923  */
5924 void DataArrayInt::checkAllocated() const
5925 {
5926   if(!isAllocated())
5927     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5928 }
5929
5930 /*!
5931  * This method desallocated \a this without modification of informations relative to the components.
5932  * After call of this method, DataArrayInt::isAllocated will return false.
5933  * If \a this is already not allocated, \a this is let unchanged.
5934  */
5935 void DataArrayInt::desallocate()
5936 {
5937   _mem.destroy();
5938 }
5939
5940 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5941 {
5942   std::size_t sz(_mem.getNbOfElemAllocated());
5943   sz*=sizeof(int);
5944   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5945 }
5946
5947 /*!
5948  * Returns the only one value in \a this, if and only if number of elements
5949  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5950  *  \return double - the sole value stored in \a this array.
5951  *  \throw If at least one of conditions stated above is not fulfilled.
5952  */
5953 int DataArrayInt::intValue() const
5954 {
5955   if(isAllocated())
5956     {
5957       if(getNbOfElems()==1)
5958         {
5959           return *getConstPointer();
5960         }
5961       else
5962         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5963     }
5964   else
5965     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5966 }
5967
5968 /*!
5969  * Returns an integer value characterizing \a this array, which is useful for a quick
5970  * comparison of many instances of DataArrayInt.
5971  *  \return int - the hash value.
5972  *  \throw If \a this is not allocated.
5973  */
5974 int DataArrayInt::getHashCode() const
5975 {
5976   checkAllocated();
5977   std::size_t nbOfElems=getNbOfElems();
5978   int ret=nbOfElems*65536;
5979   int delta=3;
5980   if(nbOfElems>48)
5981     delta=nbOfElems/8;
5982   int ret0=0;
5983   const int *pt=begin();
5984   for(std::size_t i=0;i<nbOfElems;i+=delta)
5985     ret0+=pt[i] & 0x1FFF;
5986   return ret+ret0;
5987 }
5988
5989 /*!
5990  * Checks the number of tuples.
5991  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5992  *  \throw If \a this is not allocated.
5993  */
5994 bool DataArrayInt::empty() const
5995 {
5996   checkAllocated();
5997   return getNumberOfTuples()==0;
5998 }
5999
6000 /*!
6001  * Returns a full copy of \a this. For more info on copying data arrays see
6002  * \ref MEDCouplingArrayBasicsCopyDeep.
6003  *  \return DataArrayInt * - a new instance of DataArrayInt.
6004  */
6005 DataArrayInt *DataArrayInt::deepCpy() const
6006 {
6007   return new DataArrayInt(*this);
6008 }
6009
6010 /*!
6011  * Returns either a \a deep or \a shallow copy of this array. For more info see
6012  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
6013  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
6014  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
6015  *          == \a true) or \a this instance (if \a dCpy == \a false).
6016  */
6017 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
6018 {
6019   if(dCpy)
6020     return deepCpy();
6021   else
6022     {
6023       incrRef();
6024       return const_cast<DataArrayInt *>(this);
6025     }
6026 }
6027
6028 /*!
6029  * Copies all the data from another DataArrayInt. For more info see
6030  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
6031  *  \param [in] other - another instance of DataArrayInt to copy data from.
6032  *  \throw If the \a other is not allocated.
6033  */
6034 void DataArrayInt::cpyFrom(const DataArrayInt& other)
6035 {
6036   other.checkAllocated();
6037   int nbOfTuples=other.getNumberOfTuples();
6038   int nbOfComp=other.getNumberOfComponents();
6039   allocIfNecessary(nbOfTuples,nbOfComp);
6040   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6041   int *pt=getPointer();
6042   const int *ptI=other.getConstPointer();
6043   for(std::size_t i=0;i<nbOfElems;i++)
6044     pt[i]=ptI[i];
6045   copyStringInfoFrom(other);
6046 }
6047
6048 /*!
6049  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6050  * 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.
6051  * If \a this has not already been allocated, number of components is set to one.
6052  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6053  * 
6054  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6055  */
6056 void DataArrayInt::reserve(std::size_t nbOfElems)
6057 {
6058   int nbCompo=getNumberOfComponents();
6059   if(nbCompo==1)
6060     {
6061       _mem.reserve(nbOfElems);
6062     }
6063   else if(nbCompo==0)
6064     {
6065       _mem.reserve(nbOfElems);
6066       _info_on_compo.resize(1);
6067     }
6068   else
6069     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6070 }
6071
6072 /*!
6073  * 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
6074  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6075  *
6076  * \param [in] val the value to be added in \a this
6077  * \throw If \a this has already been allocated with number of components different from one.
6078  * \sa DataArrayInt::pushBackValsSilent
6079  */
6080 void DataArrayInt::pushBackSilent(int val)
6081 {
6082   int nbCompo=getNumberOfComponents();
6083   if(nbCompo==1)
6084     _mem.pushBack(val);
6085   else if(nbCompo==0)
6086     {
6087       _info_on_compo.resize(1);
6088       _mem.pushBack(val);
6089     }
6090   else
6091     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6092 }
6093
6094 /*!
6095  * 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
6096  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6097  *
6098  *  \param [in] valsBg - an array of values to push at the end of \c this.
6099  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6100  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6101  * \throw If \a this has already been allocated with number of components different from one.
6102  * \sa DataArrayInt::pushBackSilent
6103  */
6104 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6105 {
6106   int nbCompo=getNumberOfComponents();
6107   if(nbCompo==1)
6108     _mem.insertAtTheEnd(valsBg,valsEnd);
6109   else if(nbCompo==0)
6110     {
6111       _info_on_compo.resize(1);
6112       _mem.insertAtTheEnd(valsBg,valsEnd);
6113     }
6114   else
6115     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6116 }
6117
6118 /*!
6119  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6120  * \throw If \a this is already empty.
6121  * \throw If \a this has number of components different from one.
6122  */
6123 int DataArrayInt::popBackSilent()
6124 {
6125   if(getNumberOfComponents()==1)
6126     return _mem.popBack();
6127   else
6128     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6129 }
6130
6131 /*!
6132  * 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.
6133  *
6134  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6135  */
6136 void DataArrayInt::pack() const
6137 {
6138   _mem.pack();
6139 }
6140
6141 /*!
6142  * Allocates the raw data in memory. If exactly as same memory as needed already
6143  * allocated, it is not re-allocated.
6144  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6145  *  \param [in] nbOfCompo - number of components of data to allocate.
6146  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6147  */
6148 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6149 {
6150   if(isAllocated())
6151     {
6152       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6153         alloc(nbOfTuple,nbOfCompo);
6154     }
6155   else
6156     alloc(nbOfTuple,nbOfCompo);
6157 }
6158
6159 /*!
6160  * Allocates the raw data in memory. If the memory was already allocated, then it is
6161  * freed and re-allocated. See an example of this method use
6162  * \ref MEDCouplingArraySteps1WC "here".
6163  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6164  *  \param [in] nbOfCompo - number of components of data to allocate.
6165  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6166  */
6167 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6168 {
6169   if(nbOfTuple<0 || nbOfCompo<0)
6170     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6171   _info_on_compo.resize(nbOfCompo);
6172   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6173   declareAsNew();
6174 }
6175
6176 /*!
6177  * Assign zero to all values in \a this array. To know more on filling arrays see
6178  * \ref MEDCouplingArrayFill.
6179  * \throw If \a this is not allocated.
6180  */
6181 void DataArrayInt::fillWithZero()
6182 {
6183   checkAllocated();
6184   _mem.fillWithValue(0);
6185   declareAsNew();
6186 }
6187
6188 /*!
6189  * Assign \a val to all values in \a this array. To know more on filling arrays see
6190  * \ref MEDCouplingArrayFill.
6191  *  \param [in] val - the value to fill with.
6192  *  \throw If \a this is not allocated.
6193  */
6194 void DataArrayInt::fillWithValue(int val)
6195 {
6196   checkAllocated();
6197   _mem.fillWithValue(val);
6198   declareAsNew();
6199 }
6200
6201 /*!
6202  * Set all values in \a this array so that the i-th element equals to \a init + i
6203  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6204  *  \param [in] init - value to assign to the first element of array.
6205  *  \throw If \a this->getNumberOfComponents() != 1
6206  *  \throw If \a this is not allocated.
6207  */
6208 void DataArrayInt::iota(int init)
6209 {
6210   checkAllocated();
6211   if(getNumberOfComponents()!=1)
6212     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6213   int *ptr=getPointer();
6214   int ntuples=getNumberOfTuples();
6215   for(int i=0;i<ntuples;i++)
6216     ptr[i]=init+i;
6217   declareAsNew();
6218 }
6219
6220 /*!
6221  * Returns a textual and human readable representation of \a this instance of
6222  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6223  * \return std::string - text describing \a this DataArrayInt.
6224  * 
6225  * \sa reprNotTooLong, reprZip
6226  */
6227 std::string DataArrayInt::repr() const
6228 {
6229   std::ostringstream ret;
6230   reprStream(ret);
6231   return ret.str();
6232 }
6233
6234 std::string DataArrayInt::reprZip() const
6235 {
6236   std::ostringstream ret;
6237   reprZipStream(ret);
6238   return ret.str();
6239 }
6240
6241 /*!
6242  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
6243  * printed out to avoid to consume too much space in interpretor.
6244  * \sa repr
6245  */
6246 std::string DataArrayInt::reprNotTooLong() const
6247 {
6248   std::ostringstream ret;
6249   reprNotTooLongStream(ret);
6250   return ret.str();
6251 }
6252
6253 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6254 {
6255   static const char SPACE[4]={' ',' ',' ',' '};
6256   checkAllocated();
6257   std::string idt(indent,' ');
6258   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6259   if(byteArr)
6260     {
6261       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6262       if(std::string(type)=="Int32")
6263         {
6264           const char *data(reinterpret_cast<const char *>(begin()));
6265           std::size_t sz(getNbOfElems()*sizeof(int));
6266           byteArr->insertAtTheEnd(data,data+sz);
6267           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6268         }
6269       else if(std::string(type)=="Int8")
6270         {
6271           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6272           std::copy(begin(),end(),(char *)tmp);
6273           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6274           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6275         }
6276       else if(std::string(type)=="UInt8")
6277         {
6278           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6279           std::copy(begin(),end(),(unsigned char *)tmp);
6280           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6281           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6282         }
6283       else
6284         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6285     }
6286   else
6287     {
6288       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6289       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6290     }
6291   ofs << std::endl << idt << "</DataArray>\n";
6292 }
6293
6294 void DataArrayInt::reprStream(std::ostream& stream) const
6295 {
6296   stream << "Name of int array : \"" << _name << "\"\n";
6297   reprWithoutNameStream(stream);
6298 }
6299
6300 void DataArrayInt::reprZipStream(std::ostream& stream) const
6301 {
6302   stream << "Name of int array : \"" << _name << "\"\n";
6303   reprZipWithoutNameStream(stream);
6304 }
6305
6306 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
6307 {
6308   stream << "Name of int array : \"" << _name << "\"\n";
6309   reprNotTooLongWithoutNameStream(stream);
6310 }
6311
6312 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6313 {
6314   DataArray::reprWithoutNameStream(stream);
6315   _mem.repr(getNumberOfComponents(),stream);
6316 }
6317
6318 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6319 {
6320   DataArray::reprWithoutNameStream(stream);
6321   _mem.reprZip(getNumberOfComponents(),stream);
6322 }
6323
6324 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
6325 {
6326   DataArray::reprWithoutNameStream(stream);
6327   stream.precision(17);
6328   _mem.reprNotTooLong(getNumberOfComponents(),stream);
6329 }
6330
6331 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6332 {
6333   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6334   const int *data=getConstPointer();
6335   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6336   if(nbTuples*nbComp>=1)
6337     {
6338       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6339       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6340       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6341       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6342     }
6343   else
6344     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6345   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6346 }
6347
6348 /*!
6349  * Method that gives a quick overvien of \a this for python.
6350  */
6351 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6352 {
6353   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6354   stream << "DataArrayInt C++ instance at " << this << ". ";
6355   if(isAllocated())
6356     {
6357       int nbOfCompo=(int)_info_on_compo.size();
6358       if(nbOfCompo>=1)
6359         {
6360           int nbOfTuples=getNumberOfTuples();
6361           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6362           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6363         }
6364       else
6365         stream << "Number of components : 0.";
6366     }
6367   else
6368     stream << "*** No data allocated ****";
6369 }
6370
6371 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6372 {
6373   const int *data=begin();
6374   int nbOfTuples=getNumberOfTuples();
6375   int nbOfCompo=(int)_info_on_compo.size();
6376   std::ostringstream oss2; oss2 << "[";
6377   std::string oss2Str(oss2.str());
6378   bool isFinished=true;
6379   for(int i=0;i<nbOfTuples && isFinished;i++)
6380     {
6381       if(nbOfCompo>1)
6382         {
6383           oss2 << "(";
6384           for(int j=0;j<nbOfCompo;j++,data++)
6385             {
6386               oss2 << *data;
6387               if(j!=nbOfCompo-1) oss2 << ", ";
6388             }
6389           oss2 << ")";
6390         }
6391       else
6392         oss2 << *data++;
6393       if(i!=nbOfTuples-1) oss2 << ", ";
6394       std::string oss3Str(oss2.str());
6395       if(oss3Str.length()<maxNbOfByteInRepr)
6396         oss2Str=oss3Str;
6397       else
6398         isFinished=false;
6399     }
6400   stream << oss2Str;
6401   if(!isFinished)
6402     stream << "... ";
6403   stream << "]";
6404 }
6405
6406 /*!
6407  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6408  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6409  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6410  *         to \a this array.
6411  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6412  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6413  *  \throw If \a this->getNumberOfComponents() != 1
6414  *  \throw If any value of \a this can't be used as a valid index for 
6415  *         [\a indArrBg, \a indArrEnd).
6416  *
6417  *  \sa replaceOneValByInThis
6418  */
6419 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6420 {
6421   checkAllocated();
6422   if(getNumberOfComponents()!=1)
6423     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6424   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6425   for(int i=0;i<nbOfTuples;i++,pt++)
6426     {
6427       if(*pt>=0 && *pt<nbElemsIn)
6428         *pt=indArrBg[*pt];
6429       else
6430         {
6431           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6432           throw INTERP_KERNEL::Exception(oss.str().c_str());
6433         }
6434     }
6435   declareAsNew();
6436 }
6437
6438 /*!
6439  * 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.
6440  *
6441  * \param [in] valToBeReplaced - the value in \a this to be replaced.
6442  * \param [in] replacedBy - the value taken by each tuple previously equal to \a valToBeReplaced.
6443  *
6444  * \sa DataArrayInt::transformWithIndArr
6445  */
6446 void DataArrayInt::replaceOneValByInThis(int valToBeReplaced, int replacedBy)
6447 {
6448   checkAllocated();
6449   if(getNumberOfComponents()!=1)
6450     throw INTERP_KERNEL::Exception("Call replaceOneValByInThis method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6451   if(valToBeReplaced==replacedBy)
6452     return ;
6453   int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6454   for(int i=0;i<nbOfTuples;i++,pt++)
6455     {
6456       if(*pt==valToBeReplaced)
6457         *pt=replacedBy;
6458     }
6459 }
6460
6461 /*!
6462  * Computes distribution of values of \a this one-dimensional array between given value
6463  * ranges (casts). This method is typically useful for entity number spliting by types,
6464  * for example. 
6465  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6466  *           check of this is be done. If not, the result is not warranted. 
6467  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6468  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6469  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6470  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6471  *         should be more than every value in \a this array.
6472  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6473  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6474  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6475  *         (same number of tuples and components), the caller is to delete 
6476  *         using decrRef() as it is no more needed.
6477  *         This array contains indices of ranges for every value of \a this array. I.e.
6478  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6479  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6480  *         this in which cast it holds.
6481  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6482  *         array, the caller is to delete using decrRef() as it is no more needed.
6483  *         This array contains ranks of values of \a this array within ranges
6484  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6485  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6486  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6487  *         for each tuple its rank inside its cast. The rank is computed as difference
6488  *         between the value and the lowest value of range.
6489  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6490  *         ranges (casts) to which at least one value of \a this array belongs.
6491  *         Or, in other words, this param contains the casts that \a this contains.
6492  *         The caller is to delete this array using decrRef() as it is no more needed.
6493  *
6494  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6495  *            the output of this method will be : 
6496  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6497  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6498  * - \a castsPresent  : [0,1]
6499  *
6500  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6501  * range #1 and its rank within this range is 2; etc.
6502  *
6503  *  \throw If \a this->getNumberOfComponents() != 1.
6504  *  \throw If \a arrEnd - arrBg < 2.
6505  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6506  */
6507 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6508                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6509 {
6510   checkAllocated();
6511   if(getNumberOfComponents()!=1)
6512     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6513   int nbOfTuples=getNumberOfTuples();
6514   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6515   if(nbOfCast<2)
6516     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6517   nbOfCast--;
6518   const int *work=getConstPointer();
6519   typedef std::reverse_iterator<const int *> rintstart;
6520   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6521   rintstart end2(arrBg);
6522   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6523   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6524   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6525   ret1->alloc(nbOfTuples,1);
6526   ret2->alloc(nbOfTuples,1);
6527   int *ret1Ptr=ret1->getPointer();
6528   int *ret2Ptr=ret2->getPointer();
6529   std::set<std::size_t> castsDetected;
6530   for(int i=0;i<nbOfTuples;i++)
6531     {
6532       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6533       std::size_t pos=std::distance(bg,res);
6534       std::size_t pos2=nbOfCast-pos;
6535       if(pos2<nbOfCast)
6536         {
6537           ret1Ptr[i]=(int)pos2;
6538           ret2Ptr[i]=work[i]-arrBg[pos2];
6539           castsDetected.insert(pos2);
6540         }
6541       else
6542         {
6543           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6544           throw INTERP_KERNEL::Exception(oss.str().c_str());
6545         }
6546     }
6547   ret3->alloc((int)castsDetected.size(),1);
6548   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6549   castArr=ret1.retn();
6550   rankInsideCast=ret2.retn();
6551   castsPresent=ret3.retn();
6552 }
6553
6554 /*!
6555  * 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 ).
6556  * 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 ).
6557  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6558  *
6559  * \param [out] strt - the start of the range (included) if true is returned.
6560  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6561  * \param [out] stteepp - the step of the range if true is returned.
6562  * \return the verdict of the check.
6563  *
6564  * \sa DataArray::GetNumberOfItemGivenBES
6565  */
6566 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6567 {
6568   checkAllocated();
6569   if(getNumberOfComponents()!=1)
6570     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6571   int nbTuples(getNumberOfTuples());
6572   if(nbTuples==0)
6573     { strt=0; sttoopp=0; stteepp=1; return true; }
6574   const int *pt(begin());
6575   strt=*pt; 
6576   if(nbTuples==1)
6577     { sttoopp=strt+1; stteepp=1; return true; }
6578   strt=*pt; sttoopp=pt[nbTuples-1];
6579   if(strt==sttoopp)
6580     return false;
6581   if(sttoopp>strt)
6582     {
6583       sttoopp++;
6584       int a(sttoopp-1-strt),tmp(strt);
6585       if(a%(nbTuples-1)!=0)
6586         return false;
6587       stteepp=a/(nbTuples-1);
6588       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6589         if(pt[i]!=tmp)
6590           return false;
6591       return true;
6592     }
6593   else
6594     {
6595       sttoopp--;
6596       int a(strt-sttoopp-1),tmp(strt);
6597       if(a%(nbTuples-1)!=0)
6598         return false;
6599       stteepp=-(a/(nbTuples-1));
6600       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6601         if(pt[i]!=tmp)
6602           return false;
6603       return true;
6604     }
6605 }
6606
6607 /*!
6608  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6609  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6610  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6611  * new value in place \a indArr[ \a v ] is i.
6612  *  \param [in] indArrBg - the array holding indices within the result array to assign
6613  *         indices of values of \a this array pointing to values of \a indArrBg.
6614  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6615  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6616  *  \return DataArrayInt * - the new instance of DataArrayInt.
6617  *          The caller is to delete this result array using decrRef() as it is no more
6618  *          needed.
6619  *  \throw If \a this->getNumberOfComponents() != 1.
6620  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6621  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6622  */
6623 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6624 {
6625   checkAllocated();
6626   if(getNumberOfComponents()!=1)
6627     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6628   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6629   int nbOfTuples=getNumberOfTuples();
6630   const int *pt=getConstPointer();
6631   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6632   ret->alloc(nbOfTuples,1);
6633   ret->fillWithValue(-1);
6634   int *tmp=ret->getPointer();
6635   for(int i=0;i<nbOfTuples;i++,pt++)
6636     {
6637       if(*pt>=0 && *pt<nbElemsIn)
6638         {
6639           int pos=indArrBg[*pt];
6640           if(pos>=0 && pos<nbOfTuples)
6641             tmp[pos]=i;
6642           else
6643             {
6644               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6645               throw INTERP_KERNEL::Exception(oss.str().c_str());
6646             }
6647         }
6648       else
6649         {
6650           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6651           throw INTERP_KERNEL::Exception(oss.str().c_str());
6652         }
6653     }
6654   return ret.retn();
6655 }
6656
6657 /*!
6658  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6659  * from values of \a this array, which is supposed to contain a renumbering map in 
6660  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6661  * To know how to use the renumbering maps see \ref numbering.
6662  *  \param [in] newNbOfElem - the number of tuples in the result array.
6663  *  \return DataArrayInt * - the new instance of DataArrayInt.
6664  *          The caller is to delete this result array using decrRef() as it is no more
6665  *          needed.
6666  * 
6667  *  \if ENABLE_EXAMPLES
6668  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6669  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6670  *  \endif
6671  */
6672 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6673 {
6674   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6675   ret->alloc(newNbOfElem,1);
6676   int nbOfOldNodes=getNumberOfTuples();
6677   const int *old2New=getConstPointer();
6678   int *pt=ret->getPointer();
6679   for(int i=0;i!=nbOfOldNodes;i++)
6680     {
6681       int newp(old2New[i]);
6682       if(newp!=-1)
6683         {
6684           if(newp>=0 && newp<newNbOfElem)
6685             pt[newp]=i;
6686           else
6687             {
6688               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6689               throw INTERP_KERNEL::Exception(oss.str().c_str());
6690             }
6691         }
6692     }
6693   return ret.retn();
6694 }
6695
6696 /*!
6697  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6698  * 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]
6699  */
6700 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6701 {
6702   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6703   ret->alloc(newNbOfElem,1);
6704   int nbOfOldNodes=getNumberOfTuples();
6705   const int *old2New=getConstPointer();
6706   int *pt=ret->getPointer();
6707   for(int i=nbOfOldNodes-1;i>=0;i--)
6708     {
6709       int newp(old2New[i]);
6710       if(newp!=-1)
6711         {
6712           if(newp>=0 && newp<newNbOfElem)
6713             pt[newp]=i;
6714           else
6715             {
6716               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6717               throw INTERP_KERNEL::Exception(oss.str().c_str());
6718             }
6719         }
6720     }
6721   return ret.retn();
6722 }
6723
6724 /*!
6725  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6726  * from values of \a this array, which is supposed to contain a renumbering map in 
6727  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6728  * To know how to use the renumbering maps see \ref numbering.
6729  *  \param [in] newNbOfElem - the number of tuples in the result array.
6730  *  \return DataArrayInt * - the new instance of DataArrayInt.
6731  *          The caller is to delete this result array using decrRef() as it is no more
6732  *          needed.
6733  * 
6734  *  \if ENABLE_EXAMPLES
6735  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6736  *
6737  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6738  *  \endif
6739  */
6740 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6741 {
6742   checkAllocated();
6743   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6744   ret->alloc(oldNbOfElem,1);
6745   const int *new2Old=getConstPointer();
6746   int *pt=ret->getPointer();
6747   std::fill(pt,pt+oldNbOfElem,-1);
6748   int nbOfNewElems=getNumberOfTuples();
6749   for(int i=0;i<nbOfNewElems;i++)
6750     {
6751       int v(new2Old[i]);
6752       if(v>=0 && v<oldNbOfElem)
6753         pt[v]=i;
6754       else
6755         {
6756           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6757           throw INTERP_KERNEL::Exception(oss.str().c_str());
6758         }
6759     }
6760   return ret.retn();
6761 }
6762
6763 /*!
6764  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6765  * mismatch is given.
6766  * 
6767  * \param [in] other the instance to be compared with \a this
6768  * \param [out] reason In case of inequality returns the reason.
6769  * \sa DataArrayInt::isEqual
6770  */
6771 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6772 {
6773   if(!areInfoEqualsIfNotWhy(other,reason))
6774     return false;
6775   return _mem.isEqual(other._mem,0,reason);
6776 }
6777
6778 /*!
6779  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6780  * \ref MEDCouplingArrayBasicsCompare.
6781  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6782  *  \return bool - \a true if the two arrays are equal, \a false else.
6783  */
6784 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6785 {
6786   std::string tmp;
6787   return isEqualIfNotWhy(other,tmp);
6788 }
6789
6790 /*!
6791  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6792  * \ref MEDCouplingArrayBasicsCompare.
6793  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6794  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6795  */
6796 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6797 {
6798   std::string tmp;
6799   return _mem.isEqual(other._mem,0,tmp);
6800 }
6801
6802 /*!
6803  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6804  * performed on sorted value sequences.
6805  * For more info see\ref MEDCouplingArrayBasicsCompare.
6806  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6807  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6808  */
6809 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6810 {
6811   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6812   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6813   a->sort();
6814   b->sort();
6815   return a->isEqualWithoutConsideringStr(*b);
6816 }
6817
6818 /*!
6819  * This method compares content of input vector \a v and \a this.
6820  * 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.
6821  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6822  *
6823  * \param [in] v - the vector of 'flags' to be compared with \a this.
6824  *
6825  * \throw If \a this is not sorted ascendingly.
6826  * \throw If \a this has not exactly one component.
6827  * \throw If \a this is not allocated.
6828  */
6829 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6830 {
6831   checkAllocated();
6832   if(getNumberOfComponents()!=1)
6833     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6834   const int *w(begin()),*end2(end());
6835   int refVal=-std::numeric_limits<int>::max();
6836   int i=0;
6837   std::vector<bool>::const_iterator it(v.begin());
6838   for(;it!=v.end();it++,i++)
6839     {
6840       if(*it)
6841         {
6842           if(w!=end2)
6843             {
6844               if(*w++==i)
6845                 {
6846                   if(i>refVal)
6847                     refVal=i;
6848                   else
6849                     {
6850                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6851                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6852                     }
6853                 }
6854               else
6855                 return false;
6856             }
6857           else
6858             return false;
6859         }
6860     }
6861   return w==end2;
6862 }
6863
6864 /*!
6865  * 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
6866  * put True to the corresponding entry in \a vec.
6867  * \a vec is expected to be with the same size than the number of tuples of \a this.
6868  */
6869 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6870 {
6871   checkAllocated();
6872   if(getNumberOfComponents()!=1)
6873     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6874   int nbOfTuples(getNumberOfTuples());
6875   if(nbOfTuples!=(int)vec.size())
6876     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6877   const int *pt(begin());
6878   for(int i=0;i<nbOfTuples;i++)
6879     if(pt[i]==val)
6880       vec[i]=true;
6881 }
6882
6883 /*!
6884  * Sorts values of the array.
6885  *  \param [in] asc - \a true means ascending order, \a false, descending.
6886  *  \throw If \a this is not allocated.
6887  *  \throw If \a this->getNumberOfComponents() != 1.
6888  */
6889 void DataArrayInt::sort(bool asc)
6890 {
6891   checkAllocated();
6892   if(getNumberOfComponents()!=1)
6893     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6894   _mem.sort(asc);
6895   declareAsNew();
6896 }
6897
6898 /*!
6899  * Computes for each tuple the sum of number of components values in the tuple and return it.
6900  * 
6901  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6902  *          same number of tuples as \a this array and one component.
6903  *          The caller is to delete this result array using decrRef() as it is no more
6904  *          needed.
6905  *  \throw If \a this is not allocated.
6906  */
6907 DataArrayInt *DataArrayInt::sumPerTuple() const
6908 {
6909   checkAllocated();
6910   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6911   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6912   ret->alloc(nbOfTuple,1);
6913   const int *src(getConstPointer());
6914   int *dest(ret->getPointer());
6915   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6916     *dest=std::accumulate(src,src+nbOfComp,0);
6917   return ret.retn();
6918 }
6919
6920 /*!
6921  * Reverse the array values.
6922  *  \throw If \a this->getNumberOfComponents() < 1.
6923  *  \throw If \a this is not allocated.
6924  */
6925 void DataArrayInt::reverse()
6926 {
6927   checkAllocated();
6928   _mem.reverse(getNumberOfComponents());
6929   declareAsNew();
6930 }
6931
6932 /*!
6933  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6934  * If not an exception is thrown.
6935  *  \param [in] increasing - if \a true, the array values should be increasing.
6936  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6937  *         increasing arg.
6938  *  \throw If \a this->getNumberOfComponents() != 1.
6939  *  \throw If \a this is not allocated.
6940  */
6941 void DataArrayInt::checkMonotonic(bool increasing) const
6942 {
6943   if(!isMonotonic(increasing))
6944     {
6945       if (increasing)
6946         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6947       else
6948         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6949     }
6950 }
6951
6952 /*!
6953  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6954  *  \param [in] increasing - if \a true, array values should be increasing.
6955  *  \return bool - \a true if values change in accordance with \a increasing arg.
6956  *  \throw If \a this->getNumberOfComponents() != 1.
6957  *  \throw If \a this is not allocated.
6958  */
6959 bool DataArrayInt::isMonotonic(bool increasing) const
6960 {
6961   checkAllocated();
6962   if(getNumberOfComponents()!=1)
6963     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6964   int nbOfElements=getNumberOfTuples();
6965   const int *ptr=getConstPointer();
6966   if(nbOfElements==0)
6967     return true;
6968   int ref=ptr[0];
6969   if(increasing)
6970     {
6971       for(int i=1;i<nbOfElements;i++)
6972         {
6973           if(ptr[i]>=ref)
6974             ref=ptr[i];
6975           else
6976             return false;
6977         }
6978     }
6979   else
6980     {
6981       for(int i=1;i<nbOfElements;i++)
6982         {
6983           if(ptr[i]<=ref)
6984             ref=ptr[i];
6985           else
6986             return false;
6987         }
6988     }
6989   return true;
6990 }
6991
6992 /*!
6993  * This method check that array consistently INCREASING or DECREASING in value.
6994  */
6995 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6996 {
6997   checkAllocated();
6998   if(getNumberOfComponents()!=1)
6999     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
7000   int nbOfElements=getNumberOfTuples();
7001   const int *ptr=getConstPointer();
7002   if(nbOfElements==0)
7003     return true;
7004   int ref=ptr[0];
7005   if(increasing)
7006     {
7007       for(int i=1;i<nbOfElements;i++)
7008         {
7009           if(ptr[i]>ref)
7010             ref=ptr[i];
7011           else
7012             return false;
7013         }
7014     }
7015   else
7016     {
7017       for(int i=1;i<nbOfElements;i++)
7018         {
7019           if(ptr[i]<ref)
7020             ref=ptr[i];
7021           else
7022             return false;
7023         }
7024     }
7025   return true;
7026 }
7027
7028 /*!
7029  * This method check that array consistently INCREASING or DECREASING in value.
7030  */
7031 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
7032 {
7033   if(!isStrictlyMonotonic(increasing))
7034     {
7035       if (increasing)
7036         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
7037       else
7038         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
7039     }
7040 }
7041
7042 /*!
7043  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
7044  * one-dimensional arrays that must be of the same length. The result array describes
7045  * correspondence between \a this and \a other arrays, so that 
7046  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
7047  * not possible because some element in \a other is not in \a this, an exception is thrown.
7048  *  \param [in] other - an array to compute permutation to.
7049  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
7050  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
7051  * no more needed.
7052  *  \throw If \a this->getNumberOfComponents() != 1.
7053  *  \throw If \a other->getNumberOfComponents() != 1.
7054  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
7055  *  \throw If \a other includes a value which is not in \a this array.
7056  * 
7057  *  \if ENABLE_EXAMPLES
7058  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
7059  *
7060  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
7061  *  \endif
7062  */
7063 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
7064 {
7065   checkAllocated();
7066   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
7067     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
7068   int nbTuple=getNumberOfTuples();
7069   other.checkAllocated();
7070   if(nbTuple!=other.getNumberOfTuples())
7071     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
7072   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7073   ret->alloc(nbTuple,1);
7074   ret->fillWithValue(-1);
7075   const int *pt=getConstPointer();
7076   std::map<int,int> mm;
7077   for(int i=0;i<nbTuple;i++)
7078     mm[pt[i]]=i;
7079   pt=other.getConstPointer();
7080   int *retToFill=ret->getPointer();
7081   for(int i=0;i<nbTuple;i++)
7082     {
7083       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7084       if(it==mm.end())
7085         {
7086           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7087           throw INTERP_KERNEL::Exception(oss.str().c_str());
7088         }
7089       retToFill[i]=(*it).second;
7090     }
7091   return ret.retn();
7092 }
7093
7094 /*!
7095  * Sets a C array to be used as raw data of \a this. The previously set info
7096  *  of components is retained and re-sized. 
7097  * For more info see \ref MEDCouplingArraySteps1.
7098  *  \param [in] array - the C array to be used as raw data of \a this.
7099  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7100  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
7101  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
7102  *                     \c free(\c array ) will be called.
7103  *  \param [in] nbOfTuple - new number of tuples in \a this.
7104  *  \param [in] nbOfCompo - new number of components in \a this.
7105  */
7106 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7107 {
7108   _info_on_compo.resize(nbOfCompo);
7109   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7110   declareAsNew();
7111 }
7112
7113 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7114 {
7115   _info_on_compo.resize(nbOfCompo);
7116   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7117   declareAsNew();
7118 }
7119
7120 /*!
7121  * Returns a new DataArrayInt holding the same values as \a this array but differently
7122  * arranged in memory. If \a this array holds 2 components of 3 values:
7123  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7124  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7125  *  \warning Do not confuse this method with transpose()!
7126  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7127  *          is to delete using decrRef() as it is no more needed.
7128  *  \throw If \a this is not allocated.
7129  */
7130 DataArrayInt *DataArrayInt::fromNoInterlace() const
7131 {
7132   checkAllocated();
7133   if(_mem.isNull())
7134     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7135   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7136   DataArrayInt *ret=DataArrayInt::New();
7137   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7138   return ret;
7139 }
7140
7141 /*!
7142  * Returns a new DataArrayInt holding the same values as \a this array but differently
7143  * arranged in memory. If \a this array holds 2 components of 3 values:
7144  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7145  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7146  *  \warning Do not confuse this method with transpose()!
7147  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7148  *          is to delete using decrRef() as it is no more needed.
7149  *  \throw If \a this is not allocated.
7150  */
7151 DataArrayInt *DataArrayInt::toNoInterlace() const
7152 {
7153   checkAllocated();
7154   if(_mem.isNull())
7155     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7156   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7157   DataArrayInt *ret=DataArrayInt::New();
7158   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7159   return ret;
7160 }
7161
7162 /*!
7163  * Permutes values of \a this array as required by \a old2New array. The values are
7164  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7165  * the same as in \c this one.
7166  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7167  * For more info on renumbering see \ref numbering.
7168  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7169  *     giving a new position for i-th old value.
7170  */
7171 void DataArrayInt::renumberInPlace(const int *old2New)
7172 {
7173   checkAllocated();
7174   int nbTuples=getNumberOfTuples();
7175   int nbOfCompo=getNumberOfComponents();
7176   int *tmp=new int[nbTuples*nbOfCompo];
7177   const int *iptr=getConstPointer();
7178   for(int i=0;i<nbTuples;i++)
7179     {
7180       int v=old2New[i];
7181       if(v>=0 && v<nbTuples)
7182         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7183       else
7184         {
7185           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7186           throw INTERP_KERNEL::Exception(oss.str().c_str());
7187         }
7188     }
7189   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7190   delete [] tmp;
7191   declareAsNew();
7192 }
7193
7194 /*!
7195  * Permutes values of \a this array as required by \a new2Old array. The values are
7196  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7197  * the same as in \c this one.
7198  * For more info on renumbering see \ref numbering.
7199  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7200  *     giving a previous position of i-th new value.
7201  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7202  *          is to delete using decrRef() as it is no more needed.
7203  */
7204 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7205 {
7206   checkAllocated();
7207   int nbTuples=getNumberOfTuples();
7208   int nbOfCompo=getNumberOfComponents();
7209   int *tmp=new int[nbTuples*nbOfCompo];
7210   const int *iptr=getConstPointer();
7211   for(int i=0;i<nbTuples;i++)
7212     {
7213       int v=new2Old[i];
7214       if(v>=0 && v<nbTuples)
7215         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7216       else
7217         {
7218           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7219           throw INTERP_KERNEL::Exception(oss.str().c_str());
7220         }
7221     }
7222   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7223   delete [] tmp;
7224   declareAsNew();
7225 }
7226
7227 /*!
7228  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7229  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7230  * Number of tuples in the result array remains the same as in \c this one.
7231  * If a permutation reduction is needed, renumberAndReduce() should be used.
7232  * For more info on renumbering see \ref numbering.
7233  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7234  *          giving a new position for i-th old value.
7235  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7236  *          is to delete using decrRef() as it is no more needed.
7237  *  \throw If \a this is not allocated.
7238  */
7239 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7240 {
7241   checkAllocated();
7242   int nbTuples=getNumberOfTuples();
7243   int nbOfCompo=getNumberOfComponents();
7244   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7245   ret->alloc(nbTuples,nbOfCompo);
7246   ret->copyStringInfoFrom(*this);
7247   const int *iptr=getConstPointer();
7248   int *optr=ret->getPointer();
7249   for(int i=0;i<nbTuples;i++)
7250     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7251   ret->copyStringInfoFrom(*this);
7252   return ret.retn();
7253 }
7254
7255 /*!
7256  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7257  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7258  * tuples in the result array remains the same as in \c this one.
7259  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7260  * For more info on renumbering see \ref numbering.
7261  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7262  *     giving a previous position of i-th new value.
7263  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7264  *          is to delete using decrRef() as it is no more needed.
7265  */
7266 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7267 {
7268   checkAllocated();
7269   int nbTuples=getNumberOfTuples();
7270   int nbOfCompo=getNumberOfComponents();
7271   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7272   ret->alloc(nbTuples,nbOfCompo);
7273   ret->copyStringInfoFrom(*this);
7274   const int *iptr=getConstPointer();
7275   int *optr=ret->getPointer();
7276   for(int i=0;i<nbTuples;i++)
7277     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7278   ret->copyStringInfoFrom(*this);
7279   return ret.retn();
7280 }
7281
7282 /*!
7283  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7284  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7285  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7286  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7287  * \a old2New[ i ] is negative, is missing from the result array.
7288  * For more info on renumbering see \ref numbering.
7289  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7290  *     giving a new position for i-th old tuple and giving negative position for
7291  *     for i-th old tuple that should be omitted.
7292  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7293  *          is to delete using decrRef() as it is no more needed.
7294  */
7295 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7296 {
7297   checkAllocated();
7298   int nbTuples=getNumberOfTuples();
7299   int nbOfCompo=getNumberOfComponents();
7300   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7301   ret->alloc(newNbOfTuple,nbOfCompo);
7302   const int *iptr=getConstPointer();
7303   int *optr=ret->getPointer();
7304   for(int i=0;i<nbTuples;i++)
7305     {
7306       int w=old2New[i];
7307       if(w>=0)
7308         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7309     }
7310   ret->copyStringInfoFrom(*this);
7311   return ret.retn();
7312 }
7313
7314 /*!
7315  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7316  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7317  * \a new2OldBg array.
7318  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7319  * This method is equivalent to renumberAndReduce() except that convention in input is
7320  * \c new2old and \b not \c old2new.
7321  * For more info on renumbering see \ref numbering.
7322  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7323  *              tuple index in \a this array to fill the i-th tuple in the new array.
7324  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7325  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7326  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7327  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7328  *          is to delete using decrRef() as it is no more needed.
7329  */
7330 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7331 {
7332   checkAllocated();
7333   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7334   int nbComp=getNumberOfComponents();
7335   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7336   ret->copyStringInfoFrom(*this);
7337   int *pt=ret->getPointer();
7338   const int *srcPt=getConstPointer();
7339   int i=0;
7340   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7341     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7342   ret->copyStringInfoFrom(*this);
7343   return ret.retn();
7344 }
7345
7346 /*!
7347  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7348  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7349  * \a new2OldBg array.
7350  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7351  * This method is equivalent to renumberAndReduce() except that convention in input is
7352  * \c new2old and \b not \c old2new.
7353  * This method is equivalent to selectByTupleId() except that it prevents coping data
7354  * from behind the end of \a this array.
7355  * For more info on renumbering see \ref numbering.
7356  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7357  *              tuple index in \a this array to fill the i-th tuple in the new array.
7358  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7359  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7360  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7361  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7362  *          is to delete using decrRef() as it is no more needed.
7363  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7364  */
7365 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7366 {
7367   checkAllocated();
7368   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7369   int nbComp=getNumberOfComponents();
7370   int oldNbOfTuples=getNumberOfTuples();
7371   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7372   ret->copyStringInfoFrom(*this);
7373   int *pt=ret->getPointer();
7374   const int *srcPt=getConstPointer();
7375   int i=0;
7376   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7377     if(*w>=0 && *w<oldNbOfTuples)
7378       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7379     else
7380       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7381   ret->copyStringInfoFrom(*this);
7382   return ret.retn();
7383 }
7384
7385 /*!
7386  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7387  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7388  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7389  * command \c range( \a bg, \a end2, \a step ).
7390  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7391  * not constructed explicitly.
7392  * For more info on renumbering see \ref numbering.
7393  *  \param [in] bg - index of the first tuple to copy from \a this array.
7394  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7395  *  \param [in] step - index increment to get index of the next tuple to copy.
7396  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7397  *          is to delete using decrRef() as it is no more needed.
7398  *  \sa DataArrayInt::substr.
7399  */
7400 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7401 {
7402   checkAllocated();
7403   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7404   int nbComp=getNumberOfComponents();
7405   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7406   ret->alloc(newNbOfTuples,nbComp);
7407   int *pt=ret->getPointer();
7408   const int *srcPt=getConstPointer()+bg*nbComp;
7409   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7410     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7411   ret->copyStringInfoFrom(*this);
7412   return ret.retn();
7413 }
7414
7415 /*!
7416  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7417  * of tuples specified by \a ranges parameter.
7418  * For more info on renumbering see \ref numbering.
7419  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7420  *              of tuples in [\c begin,\c end) format.
7421  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7422  *          is to delete using decrRef() as it is no more needed.
7423  *  \throw If \a end < \a begin.
7424  *  \throw If \a end > \a this->getNumberOfTuples().
7425  *  \throw If \a this is not allocated.
7426  */
7427 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7428 {
7429   checkAllocated();
7430   int nbOfComp=getNumberOfComponents();
7431   int nbOfTuplesThis=getNumberOfTuples();
7432   if(ranges.empty())
7433     {
7434       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7435       ret->alloc(0,nbOfComp);
7436       ret->copyStringInfoFrom(*this);
7437       return ret.retn();
7438     }
7439   int ref=ranges.front().first;
7440   int nbOfTuples=0;
7441   bool isIncreasing=true;
7442   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7443     {
7444       if((*it).first<=(*it).second)
7445         {
7446           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7447             {
7448               nbOfTuples+=(*it).second-(*it).first;
7449               if(isIncreasing)
7450                 isIncreasing=ref<=(*it).first;
7451               ref=(*it).second;
7452             }
7453           else
7454             {
7455               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7456               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7457               throw INTERP_KERNEL::Exception(oss.str().c_str());
7458             }
7459         }
7460       else
7461         {
7462           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7463           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7464           throw INTERP_KERNEL::Exception(oss.str().c_str());
7465         }
7466     }
7467   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7468     return deepCpy();
7469   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7470   ret->alloc(nbOfTuples,nbOfComp);
7471   ret->copyStringInfoFrom(*this);
7472   const int *src=getConstPointer();
7473   int *work=ret->getPointer();
7474   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7475     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7476   return ret.retn();
7477 }
7478
7479 /*!
7480  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7481  * This map, if applied to \a this array, would make it sorted. For example, if
7482  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7483  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7484  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7485  * This method is useful for renumbering (in MED file for example). For more info
7486  * on renumbering see \ref numbering.
7487  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7488  *          array using decrRef() as it is no more needed.
7489  *  \throw If \a this is not allocated.
7490  *  \throw If \a this->getNumberOfComponents() != 1.
7491  *  \throw If there are equal values in \a this array.
7492  */
7493 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7494 {
7495   checkAllocated();
7496   if(getNumberOfComponents()!=1)
7497     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7498   int nbTuples=getNumberOfTuples();
7499   const int *pt=getConstPointer();
7500   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7501   DataArrayInt *ret=DataArrayInt::New();
7502   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7503   return ret;
7504 }
7505
7506 /*!
7507  * 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
7508  * input array \a ids2.
7509  * \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.
7510  * 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
7511  * inversely.
7512  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7513  *
7514  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7515  *          array using decrRef() as it is no more needed.
7516  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7517  * 
7518  */
7519 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7520 {
7521   if(!ids1 || !ids2)
7522     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7523   if(!ids1->isAllocated() || !ids2->isAllocated())
7524     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7525   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7526     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7527   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7528     {
7529       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 !";
7530       throw INTERP_KERNEL::Exception(oss.str().c_str());
7531     }
7532   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7533   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7534   p1->sort(true); p2->sort(true);
7535   if(!p1->isEqualWithoutConsideringStr(*p2))
7536     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7537   p1=ids1->checkAndPreparePermutation();
7538   p2=ids2->checkAndPreparePermutation();
7539   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7540   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7541   return p2.retn();
7542 }
7543
7544 /*!
7545  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7546  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7547  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7548  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7549  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7550  * The first of out arrays returns indices of elements of \a this array, grouped by their
7551  * place in the set \a B. The second out array is the index of the first one; it shows how
7552  * many elements of \a A are mapped into each element of \a B. <br>
7553  * For more info on
7554  * mapping and its usage in renumbering see \ref numbering. <br>
7555  * \b Example:
7556  * - \a this: [0,3,2,3,2,2,1,2]
7557  * - \a targetNb: 4
7558  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7559  * - \a arrI: [0,1,2,6,8]
7560  *
7561  * This result means: <br>
7562  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7563  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7564  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7565  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7566  * \a arrI[ 2+1 ]]); <br> etc.
7567  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7568  *         than the maximal value of \a A.
7569  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7570  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7571  *         this array using decrRef() as it is no more needed.
7572  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7573  *         elements of \a this. The caller is to delete this array using decrRef() as it
7574  *         is no more needed.
7575  *  \throw If \a this is not allocated.
7576  *  \throw If \a this->getNumberOfComponents() != 1.
7577  *  \throw If any value in \a this is more or equal to \a targetNb.
7578  */
7579 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7580 {
7581   checkAllocated();
7582   if(getNumberOfComponents()!=1)
7583     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7584   int nbOfTuples=getNumberOfTuples();
7585   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7586   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7587   retI->alloc(targetNb+1,1);
7588   const int *input=getConstPointer();
7589   std::vector< std::vector<int> > tmp(targetNb);
7590   for(int i=0;i<nbOfTuples;i++)
7591     {
7592       int tmp2=input[i];
7593       if(tmp2>=0 && tmp2<targetNb)
7594         tmp[tmp2].push_back(i);
7595       else
7596         {
7597           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7598           throw INTERP_KERNEL::Exception(oss.str().c_str());
7599         }
7600     }
7601   int *retIPtr=retI->getPointer();
7602   *retIPtr=0;
7603   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7604     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7605   if(nbOfTuples!=retI->getIJ(targetNb,0))
7606     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7607   ret->alloc(nbOfTuples,1);
7608   int *retPtr=ret->getPointer();
7609   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7610     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7611   arr=ret.retn();
7612   arrI=retI.retn();
7613 }
7614
7615
7616 /*!
7617  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7618  * from a zip representation of a surjective format (returned e.g. by
7619  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7620  * for example). The result array minimizes the permutation. <br>
7621  * For more info on renumbering see \ref numbering. <br>
7622  * \b Example: <br>
7623  * - \a nbOfOldTuples: 10 
7624  * - \a arr          : [0,3, 5,7,9]
7625  * - \a arrIBg       : [0,2,5]
7626  * - \a newNbOfTuples: 7
7627  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7628  *
7629  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7630  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7631  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7632  *         (indices of) equal values. Its every element (except the last one) points to
7633  *         the first element of a group of equal values.
7634  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7635  *          arrIBg is \a arrIEnd[ -1 ].
7636  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7637  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7638  *          array using decrRef() as it is no more needed.
7639  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7640  */
7641 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7642 {
7643   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7644   ret->alloc(nbOfOldTuples,1);
7645   int *pt=ret->getPointer();
7646   std::fill(pt,pt+nbOfOldTuples,-1);
7647   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7648   const int *cIPtr=arrIBg;
7649   for(int i=0;i<nbOfGrps;i++)
7650     pt[arr[cIPtr[i]]]=-(i+2);
7651   int newNb=0;
7652   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7653     {
7654       if(pt[iNode]<0)
7655         {
7656           if(pt[iNode]==-1)
7657             pt[iNode]=newNb++;
7658           else
7659             {
7660               int grpId=-(pt[iNode]+2);
7661               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7662                 {
7663                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7664                     pt[arr[j]]=newNb;
7665                   else
7666                     {
7667                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7668                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7669                     }
7670                 }
7671               newNb++;
7672             }
7673         }
7674     }
7675   newNbOfTuples=newNb;
7676   return ret.retn();
7677 }
7678
7679 /*!
7680  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7681  * which if applied to \a this array would make it sorted ascendingly.
7682  * For more info on renumbering see \ref numbering. <br>
7683  * \b Example: <br>
7684  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7685  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7686  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7687  *
7688  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7689  *          array using decrRef() as it is no more needed.
7690  *  \throw If \a this is not allocated.
7691  *  \throw If \a this->getNumberOfComponents() != 1.
7692  */
7693 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7694 {
7695   checkAllocated();
7696   if(getNumberOfComponents()!=1)
7697     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7698   int nbOfTuples=getNumberOfTuples();
7699   const int *pt=getConstPointer();
7700   std::map<int,int> m;
7701   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7702   ret->alloc(nbOfTuples,1);
7703   int *opt=ret->getPointer();
7704   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7705     {
7706       int val=*pt;
7707       std::map<int,int>::iterator it=m.find(val);
7708       if(it!=m.end())
7709         {
7710           *opt=(*it).second;
7711           (*it).second++;
7712         }
7713       else
7714         {
7715           *opt=0;
7716           m.insert(std::pair<int,int>(val,1));
7717         }
7718     }
7719   int sum=0;
7720   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7721     {
7722       int vt=(*it).second;
7723       (*it).second=sum;
7724       sum+=vt;
7725     }
7726   pt=getConstPointer();
7727   opt=ret->getPointer();
7728   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7729     *opt+=m[*pt];
7730   //
7731   return ret.retn();
7732 }
7733
7734 /*!
7735  * Checks if contents of \a this array are equal to that of an array filled with
7736  * iota(). This method is particularly useful for DataArrayInt instances that represent
7737  * a renumbering array to check the real need in renumbering. In this case it is better to use isIdentity2
7738  * method of isIdentity method.
7739  *
7740  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7741  *  \throw If \a this is not allocated.
7742  *  \throw If \a this->getNumberOfComponents() != 1.
7743  *  \sa isIdentity2
7744  */
7745 bool DataArrayInt::isIdentity() const
7746 {
7747   checkAllocated();
7748   if(getNumberOfComponents()!=1)
7749     return false;
7750   int nbOfTuples(getNumberOfTuples());
7751   const int *pt=getConstPointer();
7752   for(int i=0;i<nbOfTuples;i++,pt++)
7753     if(*pt!=i)
7754       return false;
7755   return true;
7756 }
7757
7758 /*!
7759  * This method is stronger than isIdentity method. This method checks than \a this can be considered as an identity function
7760  * of a set having \a sizeExpected elements into itself.
7761  *
7762  * \param [in] sizeExpected - The number of elements
7763  * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) and if \a this has \a sizeExpected tuples in it.
7764  *
7765  *  \throw If \a this is not allocated.
7766  *  \throw If \a this->getNumberOfComponents() != 1.
7767  * \sa isIdentity
7768  */
7769 bool DataArrayInt::isIdentity2(int sizeExpected) const
7770 {
7771   bool ret0(isIdentity());
7772   if(!ret0)
7773     return false;
7774   return getNumberOfTuples()==sizeExpected;
7775 }
7776
7777 /*!
7778  * Checks if all values in \a this array are equal to \a val.
7779  *  \param [in] val - value to check equality of array values to.
7780  *  \return bool - \a true if all values are \a val.
7781  *  \throw If \a this is not allocated.
7782  *  \throw If \a this->getNumberOfComponents() != 1
7783  */
7784 bool DataArrayInt::isUniform(int val) const
7785 {
7786   checkAllocated();
7787   if(getNumberOfComponents()!=1)
7788     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7789   int nbOfTuples=getNumberOfTuples();
7790   const int *w=getConstPointer();
7791   const int *end2=w+nbOfTuples;
7792   for(;w!=end2;w++)
7793     if(*w!=val)
7794       return false;
7795   return true;
7796 }
7797
7798 /*!
7799  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7800  * array to the new one.
7801  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7802  */
7803 DataArrayDouble *DataArrayInt::convertToDblArr() const
7804 {
7805   checkAllocated();
7806   DataArrayDouble *ret=DataArrayDouble::New();
7807   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7808   std::size_t nbOfVals=getNbOfElems();
7809   const int *src=getConstPointer();
7810   double *dest=ret->getPointer();
7811   std::copy(src,src+nbOfVals,dest);
7812   ret->copyStringInfoFrom(*this);
7813   return ret;
7814 }
7815
7816 /*!
7817  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7818  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7819  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7820  * This method is a specialization of selectByTupleId2().
7821  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7822  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7823  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7824  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7825  *          is to delete using decrRef() as it is no more needed.
7826  *  \throw If \a tupleIdBg < 0.
7827  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7828     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7829  *  \sa DataArrayInt::selectByTupleId2
7830  */
7831 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7832 {
7833   checkAllocated();
7834   int nbt=getNumberOfTuples();
7835   if(tupleIdBg<0)
7836     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7837   if(tupleIdBg>nbt)
7838     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7839   int trueEnd=tupleIdEnd;
7840   if(tupleIdEnd!=-1)
7841     {
7842       if(tupleIdEnd>nbt)
7843         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7844     }
7845   else
7846     trueEnd=nbt;
7847   int nbComp=getNumberOfComponents();
7848   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7849   ret->alloc(trueEnd-tupleIdBg,nbComp);
7850   ret->copyStringInfoFrom(*this);
7851   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7852   return ret.retn();
7853 }
7854
7855 /*!
7856  * Changes the number of components within \a this array so that its raw data **does
7857  * not** change, instead splitting this data into tuples changes.
7858  *  \warning This method erases all (name and unit) component info set before!
7859  *  \param [in] newNbOfComp - number of components for \a this array to have.
7860  *  \throw If \a this is not allocated
7861  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7862  *  \throw If \a newNbOfCompo is lower than 1.
7863  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7864  *  \warning This method erases all (name and unit) component info set before!
7865  */
7866 void DataArrayInt::rearrange(int newNbOfCompo)
7867 {
7868   checkAllocated();
7869   if(newNbOfCompo<1)
7870     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7871   std::size_t nbOfElems=getNbOfElems();
7872   if(nbOfElems%newNbOfCompo!=0)
7873     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7874   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7875     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7876   _info_on_compo.clear();
7877   _info_on_compo.resize(newNbOfCompo);
7878   declareAsNew();
7879 }
7880
7881 /*!
7882  * Changes the number of components within \a this array to be equal to its number
7883  * of tuples, and inversely its number of tuples to become equal to its number of 
7884  * components. So that its raw data **does not** change, instead splitting this
7885  * data into tuples changes.
7886  *  \warning This method erases all (name and unit) component info set before!
7887  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7888  *  \throw If \a this is not allocated.
7889  *  \sa rearrange()
7890  */
7891 void DataArrayInt::transpose()
7892 {
7893   checkAllocated();
7894   int nbOfTuples=getNumberOfTuples();
7895   rearrange(nbOfTuples);
7896 }
7897
7898 /*!
7899  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7900  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7901  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7902  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7903  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7904  * components.  
7905  *  \param [in] newNbOfComp - number of components for the new array to have.
7906  *  \param [in] dftValue - value assigned to new values added to the new array.
7907  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7908  *          is to delete using decrRef() as it is no more needed.
7909  *  \throw If \a this is not allocated.
7910  */
7911 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7912 {
7913   checkAllocated();
7914   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7915   ret->alloc(getNumberOfTuples(),newNbOfComp);
7916   const int *oldc=getConstPointer();
7917   int *nc=ret->getPointer();
7918   int nbOfTuples=getNumberOfTuples();
7919   int oldNbOfComp=getNumberOfComponents();
7920   int dim=std::min(oldNbOfComp,newNbOfComp);
7921   for(int i=0;i<nbOfTuples;i++)
7922     {
7923       int j=0;
7924       for(;j<dim;j++)
7925         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7926       for(;j<newNbOfComp;j++)
7927         nc[newNbOfComp*i+j]=dftValue;
7928     }
7929   ret->setName(getName());
7930   for(int i=0;i<dim;i++)
7931     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7932   ret->setName(getName());
7933   return ret.retn();
7934 }
7935
7936 /*!
7937  * Changes number of tuples in the array. If the new number of tuples is smaller
7938  * than the current number the array is truncated, otherwise the array is extended.
7939  *  \param [in] nbOfTuples - new number of tuples. 
7940  *  \throw If \a this is not allocated.
7941  *  \throw If \a nbOfTuples is negative.
7942  */
7943 void DataArrayInt::reAlloc(int nbOfTuples)
7944 {
7945   if(nbOfTuples<0)
7946     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7947   checkAllocated();
7948   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7949   declareAsNew();
7950 }
7951
7952
7953 /*!
7954  * Returns a copy of \a this array composed of selected components.
7955  * The new DataArrayInt has the same number of tuples but includes components
7956  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7957  * can be either less, same or more than \a this->getNbOfElems().
7958  *  \param [in] compoIds - sequence of zero based indices of components to include
7959  *              into the new array.
7960  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7961  *          is to delete using decrRef() as it is no more needed.
7962  *  \throw If \a this is not allocated.
7963  *  \throw If a component index (\a i) is not valid: 
7964  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7965  *
7966  *  \if ENABLE_EXAMPLES
7967  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7968  *  \endif
7969  */
7970 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7971 {
7972   checkAllocated();
7973   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7974   int newNbOfCompo=(int)compoIds.size();
7975   int oldNbOfCompo=getNumberOfComponents();
7976   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7977     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7978   int nbOfTuples=getNumberOfTuples();
7979   ret->alloc(nbOfTuples,newNbOfCompo);
7980   ret->copyPartOfStringInfoFrom(*this,compoIds);
7981   const int *oldc=getConstPointer();
7982   int *nc=ret->getPointer();
7983   for(int i=0;i<nbOfTuples;i++)
7984     for(int j=0;j<newNbOfCompo;j++,nc++)
7985       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7986   return ret.retn();
7987 }
7988
7989 /*!
7990  * Appends components of another array to components of \a this one, tuple by tuple.
7991  * So that the number of tuples of \a this array remains the same and the number of 
7992  * components increases.
7993  *  \param [in] other - the DataArrayInt to append to \a this one.
7994  *  \throw If \a this is not allocated.
7995  *  \throw If \a this and \a other arrays have different number of tuples.
7996  *
7997  *  \if ENABLE_EXAMPLES
7998  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7999  *
8000  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
8001  *  \endif
8002  */
8003 void DataArrayInt::meldWith(const DataArrayInt *other)
8004 {
8005   if(!other)
8006     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
8007   checkAllocated();
8008   other->checkAllocated();
8009   int nbOfTuples=getNumberOfTuples();
8010   if(nbOfTuples!=other->getNumberOfTuples())
8011     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
8012   int nbOfComp1=getNumberOfComponents();
8013   int nbOfComp2=other->getNumberOfComponents();
8014   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
8015   int *w=newArr;
8016   const int *inp1=getConstPointer();
8017   const int *inp2=other->getConstPointer();
8018   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
8019     {
8020       w=std::copy(inp1,inp1+nbOfComp1,w);
8021       w=std::copy(inp2,inp2+nbOfComp2,w);
8022     }
8023   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
8024   std::vector<int> compIds(nbOfComp2);
8025   for(int i=0;i<nbOfComp2;i++)
8026     compIds[i]=nbOfComp1+i;
8027   copyPartOfStringInfoFrom2(compIds,*other);
8028 }
8029
8030 /*!
8031  * Copy all components in a specified order from another DataArrayInt.
8032  * The specified components become the first ones in \a this array.
8033  * Both numerical and textual data is copied. The number of tuples in \a this and
8034  * the other array can be different.
8035  *  \param [in] a - the array to copy data from.
8036  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
8037  *              to be copied.
8038  *  \throw If \a a is NULL.
8039  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
8040  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
8041  *
8042  *  \if ENABLE_EXAMPLES
8043  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
8044  *  \endif
8045  */
8046 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
8047 {
8048   if(!a)
8049     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
8050   checkAllocated();
8051   a->checkAllocated();
8052   copyPartOfStringInfoFrom2(compoIds,*a);
8053   std::size_t partOfCompoSz=compoIds.size();
8054   int nbOfCompo=getNumberOfComponents();
8055   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
8056   const int *ac=a->getConstPointer();
8057   int *nc=getPointer();
8058   for(int i=0;i<nbOfTuples;i++)
8059     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
8060       nc[nbOfCompo*i+compoIds[j]]=*ac;
8061 }
8062
8063 /*!
8064  * Copy all values from another DataArrayInt into specified tuples and components
8065  * of \a this array. Textual data is not copied.
8066  * The tree parameters defining set of indices of tuples and components are similar to
8067  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
8068  *  \param [in] a - the array to copy values from.
8069  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
8070  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8071  *              are located.
8072  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8073  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
8074  *  \param [in] endComp - index of the component before which the components to assign
8075  *              to are located.
8076  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8077  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
8078  *              must be equal to the number of columns to assign to, else an
8079  *              exception is thrown; if \a false, then it is only required that \a
8080  *              a->getNbOfElems() equals to number of values to assign to (this condition
8081  *              must be respected even if \a strictCompoCompare is \a true). The number of 
8082  *              values to assign to is given by following Python expression:
8083  *              \a nbTargetValues = 
8084  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
8085  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8086  *  \throw If \a a is NULL.
8087  *  \throw If \a a is not allocated.
8088  *  \throw If \a this is not allocated.
8089  *  \throw If parameters specifying tuples and components to assign to do not give a
8090  *            non-empty range of increasing indices.
8091  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
8092  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
8093  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8094  *
8095  *  \if ENABLE_EXAMPLES
8096  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
8097  *  \endif
8098  */
8099 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8100 {
8101   if(!a)
8102     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8103   const char msg[]="DataArrayInt::setPartOfValues1";
8104   checkAllocated();
8105   a->checkAllocated();
8106   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8107   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8108   int nbComp=getNumberOfComponents();
8109   int nbOfTuples=getNumberOfTuples();
8110   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8111   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8112   bool assignTech=true;
8113   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8114     {
8115       if(strictCompoCompare)
8116         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8117     }
8118   else
8119     {
8120       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8121       assignTech=false;
8122     }
8123   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8124   const int *srcPt=a->getConstPointer();
8125   if(assignTech)
8126     {
8127       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8128         for(int j=0;j<newNbOfComp;j++,srcPt++)
8129           pt[j*stepComp]=*srcPt;
8130     }
8131   else
8132     {
8133       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8134         {
8135           const int *srcPt2=srcPt;
8136           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8137             pt[j*stepComp]=*srcPt2;
8138         }
8139     }
8140 }
8141
8142 /*!
8143  * Assign a given value to values at specified tuples and components of \a this array.
8144  * The tree parameters defining set of indices of tuples and components are similar to
8145  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8146  *  \param [in] a - the value to assign.
8147  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8148  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8149  *              are located.
8150  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8151  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8152  *  \param [in] endComp - index of the component before which the components to assign
8153  *              to are located.
8154  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8155  *  \throw If \a this is not allocated.
8156  *  \throw If parameters specifying tuples and components to assign to, do not give a
8157  *            non-empty range of increasing indices or indices are out of a valid range
8158  *            for \c this array.
8159  *
8160  *  \if ENABLE_EXAMPLES
8161  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8162  *  \endif
8163  */
8164 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8165 {
8166   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8167   checkAllocated();
8168   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8169   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8170   int nbComp=getNumberOfComponents();
8171   int nbOfTuples=getNumberOfTuples();
8172   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8173   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8174   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8175   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8176     for(int j=0;j<newNbOfComp;j++)
8177       pt[j*stepComp]=a;
8178 }
8179
8180
8181 /*!
8182  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8183  * components of \a this array. Textual data is not copied.
8184  * The tuples and components to assign to are defined by C arrays of indices.
8185  * There are two *modes of usage*:
8186  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8187  *   of \a a is assigned to its own location within \a this array. 
8188  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8189  *   components of every specified tuple of \a this array. In this mode it is required
8190  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8191  * 
8192  *  \param [in] a - the array to copy values from.
8193  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8194  *              assign values of \a a to.
8195  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8196  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8197  *              \a bgTuples <= \a pi < \a endTuples.
8198  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8199  *              assign values of \a a to.
8200  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8201  *              pointer to a component index <em>(pi)</em> varies as this: 
8202  *              \a bgComp <= \a pi < \a endComp.
8203  *  \param [in] strictCompoCompare - this parameter is checked only if the
8204  *               *mode of usage* is the first; if it is \a true (default), 
8205  *               then \a a->getNumberOfComponents() must be equal 
8206  *               to the number of specified columns, else this is not required.
8207  *  \throw If \a a is NULL.
8208  *  \throw If \a a is not allocated.
8209  *  \throw If \a this is not allocated.
8210  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8211  *         out of a valid range for \a this array.
8212  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8213  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8214  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8215  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8216  *
8217  *  \if ENABLE_EXAMPLES
8218  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8219  *  \endif
8220  */
8221 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8222 {
8223   if(!a)
8224     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8225   const char msg[]="DataArrayInt::setPartOfValues2";
8226   checkAllocated();
8227   a->checkAllocated();
8228   int nbComp=getNumberOfComponents();
8229   int nbOfTuples=getNumberOfTuples();
8230   for(const int *z=bgComp;z!=endComp;z++)
8231     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8232   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8233   int newNbOfComp=(int)std::distance(bgComp,endComp);
8234   bool assignTech=true;
8235   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8236     {
8237       if(strictCompoCompare)
8238         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8239     }
8240   else
8241     {
8242       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8243       assignTech=false;
8244     }
8245   int *pt=getPointer();
8246   const int *srcPt=a->getConstPointer();
8247   if(assignTech)
8248     {    
8249       for(const int *w=bgTuples;w!=endTuples;w++)
8250         {
8251           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8252           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8253             {    
8254               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8255             }
8256         }
8257     }
8258   else
8259     {
8260       for(const int *w=bgTuples;w!=endTuples;w++)
8261         {
8262           const int *srcPt2=srcPt;
8263           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8264           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8265             {    
8266               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8267             }
8268         }
8269     }
8270 }
8271
8272 /*!
8273  * Assign a given value to values at specified tuples and components of \a this array.
8274  * The tuples and components to assign to are defined by C arrays of indices.
8275  *  \param [in] a - the value to assign.
8276  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8277  *              assign \a a to.
8278  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8279  *              pointer to a tuple index (\a pi) varies as this: 
8280  *              \a bgTuples <= \a pi < \a endTuples.
8281  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8282  *              assign \a a to.
8283  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8284  *              pointer to a component index (\a pi) varies as this: 
8285  *              \a bgComp <= \a pi < \a endComp.
8286  *  \throw If \a this is not allocated.
8287  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8288  *         out of a valid range for \a this array.
8289  *
8290  *  \if ENABLE_EXAMPLES
8291  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8292  *  \endif
8293  */
8294 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8295 {
8296   checkAllocated();
8297   int nbComp=getNumberOfComponents();
8298   int nbOfTuples=getNumberOfTuples();
8299   for(const int *z=bgComp;z!=endComp;z++)
8300     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8301   int *pt=getPointer();
8302   for(const int *w=bgTuples;w!=endTuples;w++)
8303     for(const int *z=bgComp;z!=endComp;z++)
8304       {
8305         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8306         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8307       }
8308 }
8309
8310 /*!
8311  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8312  * components of \a this array. Textual data is not copied.
8313  * The tuples to assign to are defined by a C array of indices.
8314  * The components to assign to are defined by three values similar to parameters of
8315  * the Python function \c range(\c start,\c stop,\c step).
8316  * There are two *modes of usage*:
8317  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8318  *   of \a a is assigned to its own location within \a this array. 
8319  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8320  *   components of every specified tuple of \a this array. In this mode it is required
8321  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8322  *
8323  *  \param [in] a - the array to copy values from.
8324  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8325  *              assign values of \a a to.
8326  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8327  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8328  *              \a bgTuples <= \a pi < \a endTuples.
8329  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8330  *  \param [in] endComp - index of the component before which the components to assign
8331  *              to are located.
8332  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8333  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8334  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8335  *               then \a a->getNumberOfComponents() must be equal 
8336  *               to the number of specified columns, else this is not required.
8337  *  \throw If \a a is NULL.
8338  *  \throw If \a a is not allocated.
8339  *  \throw If \a this is not allocated.
8340  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8341  *         \a this array.
8342  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8343  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8344  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8345  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8346  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8347  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8348  *  \throw If parameters specifying components to assign to, do not give a
8349  *            non-empty range of increasing indices or indices are out of a valid range
8350  *            for \c this array.
8351  *
8352  *  \if ENABLE_EXAMPLES
8353  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8354  *  \endif
8355  */
8356 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8357 {
8358   if(!a)
8359     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8360   const char msg[]="DataArrayInt::setPartOfValues3";
8361   checkAllocated();
8362   a->checkAllocated();
8363   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8364   int nbComp=getNumberOfComponents();
8365   int nbOfTuples=getNumberOfTuples();
8366   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8367   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8368   bool assignTech=true;
8369   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8370     {
8371       if(strictCompoCompare)
8372         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8373     }
8374   else
8375     {
8376       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8377       assignTech=false;
8378     }
8379   int *pt=getPointer()+bgComp;
8380   const int *srcPt=a->getConstPointer();
8381   if(assignTech)
8382     {
8383       for(const int *w=bgTuples;w!=endTuples;w++)
8384         for(int j=0;j<newNbOfComp;j++,srcPt++)
8385           {
8386             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8387             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8388           }
8389     }
8390   else
8391     {
8392       for(const int *w=bgTuples;w!=endTuples;w++)
8393         {
8394           const int *srcPt2=srcPt;
8395           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8396             {
8397               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8398               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8399             }
8400         }
8401     }
8402 }
8403
8404 /*!
8405  * Assign a given value to values at specified tuples and components of \a this array.
8406  * The tuples to assign to are defined by a C array of indices.
8407  * The components to assign to are defined by three values similar to parameters of
8408  * the Python function \c range(\c start,\c stop,\c step).
8409  *  \param [in] a - the value to assign.
8410  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8411  *              assign \a a to.
8412  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8413  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8414  *              \a bgTuples <= \a pi < \a endTuples.
8415  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8416  *  \param [in] endComp - index of the component before which the components to assign
8417  *              to are located.
8418  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8419  *  \throw If \a this is not allocated.
8420  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8421  *         \a this array.
8422  *  \throw If parameters specifying components to assign to, do not give a
8423  *            non-empty range of increasing indices or indices are out of a valid range
8424  *            for \c this array.
8425  *
8426  *  \if ENABLE_EXAMPLES
8427  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8428  *  \endif
8429  */
8430 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8431 {
8432   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8433   checkAllocated();
8434   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8435   int nbComp=getNumberOfComponents();
8436   int nbOfTuples=getNumberOfTuples();
8437   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8438   int *pt=getPointer()+bgComp;
8439   for(const int *w=bgTuples;w!=endTuples;w++)
8440     for(int j=0;j<newNbOfComp;j++)
8441       {
8442         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8443         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8444       }
8445 }
8446
8447 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8448 {
8449   if(!a)
8450     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8451   const char msg[]="DataArrayInt::setPartOfValues4";
8452   checkAllocated();
8453   a->checkAllocated();
8454   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8455   int newNbOfComp=(int)std::distance(bgComp,endComp);
8456   int nbComp=getNumberOfComponents();
8457   for(const int *z=bgComp;z!=endComp;z++)
8458     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8459   int nbOfTuples=getNumberOfTuples();
8460   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8461   bool assignTech=true;
8462   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8463     {
8464       if(strictCompoCompare)
8465         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8466     }
8467   else
8468     {
8469       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8470       assignTech=false;
8471     }
8472   const int *srcPt=a->getConstPointer();
8473   int *pt=getPointer()+bgTuples*nbComp;
8474   if(assignTech)
8475     {
8476       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8477         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8478           pt[*z]=*srcPt;
8479     }
8480   else
8481     {
8482       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8483         {
8484           const int *srcPt2=srcPt;
8485           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8486             pt[*z]=*srcPt2;
8487         }
8488     }
8489 }
8490
8491 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8492 {
8493   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8494   checkAllocated();
8495   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8496   int nbComp=getNumberOfComponents();
8497   for(const int *z=bgComp;z!=endComp;z++)
8498     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8499   int nbOfTuples=getNumberOfTuples();
8500   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8501   int *pt=getPointer()+bgTuples*nbComp;
8502   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8503     for(const int *z=bgComp;z!=endComp;z++)
8504       pt[*z]=a;
8505 }
8506
8507 /*!
8508  * Copy some tuples from another DataArrayInt into specified tuples
8509  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8510  * components.
8511  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8512  * All components of selected tuples are copied.
8513  *  \param [in] a - the array to copy values from.
8514  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8515  *              target tuples of \a this. \a tuplesSelec has two components, and the
8516  *              first component specifies index of the source tuple and the second
8517  *              one specifies index of the target tuple.
8518  *  \throw If \a this is not allocated.
8519  *  \throw If \a a is NULL.
8520  *  \throw If \a a is not allocated.
8521  *  \throw If \a tuplesSelec is NULL.
8522  *  \throw If \a tuplesSelec is not allocated.
8523  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8524  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8525  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8526  *         the corresponding (\a this or \a a) array.
8527  */
8528 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8529 {
8530   if(!a || !tuplesSelec)
8531     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8532   checkAllocated();
8533   a->checkAllocated();
8534   tuplesSelec->checkAllocated();
8535   int nbOfComp=getNumberOfComponents();
8536   if(nbOfComp!=a->getNumberOfComponents())
8537     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8538   if(tuplesSelec->getNumberOfComponents()!=2)
8539     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8540   int thisNt=getNumberOfTuples();
8541   int aNt=a->getNumberOfTuples();
8542   int *valsToSet=getPointer();
8543   const int *valsSrc=a->getConstPointer();
8544   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8545     {
8546       if(tuple[1]>=0 && tuple[1]<aNt)
8547         {
8548           if(tuple[0]>=0 && tuple[0]<thisNt)
8549             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8550           else
8551             {
8552               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8553               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8554               throw INTERP_KERNEL::Exception(oss.str().c_str());
8555             }
8556         }
8557       else
8558         {
8559           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8560           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8561           throw INTERP_KERNEL::Exception(oss.str().c_str());
8562         }
8563     }
8564 }
8565
8566 /*!
8567  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8568  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8569  * components.
8570  * The tuples to assign to are defined by index of the first tuple, and
8571  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8572  * The tuples to copy are defined by values of a DataArrayInt.
8573  * All components of selected tuples are copied.
8574  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8575  *              values to.
8576  *  \param [in] aBase - the array to copy values from.
8577  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8578  *  \throw If \a this is not allocated.
8579  *  \throw If \a aBase is NULL.
8580  *  \throw If \a aBase is not allocated.
8581  *  \throw If \a tuplesSelec is NULL.
8582  *  \throw If \a tuplesSelec is not allocated.
8583  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8584  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8585  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8586  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8587  *         \a aBase array.
8588  */
8589 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8590 {
8591   if(!aBase || !tuplesSelec)
8592     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8593   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8594   if(!a)
8595     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8596   checkAllocated();
8597   a->checkAllocated();
8598   tuplesSelec->checkAllocated();
8599   int nbOfComp=getNumberOfComponents();
8600   if(nbOfComp!=a->getNumberOfComponents())
8601     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8602   if(tuplesSelec->getNumberOfComponents()!=1)
8603     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8604   int thisNt=getNumberOfTuples();
8605   int aNt=a->getNumberOfTuples();
8606   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8607   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8608   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8609     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8610   const int *valsSrc=a->getConstPointer();
8611   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8612     {
8613       if(*tuple>=0 && *tuple<aNt)
8614         {
8615           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8616         }
8617       else
8618         {
8619           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8620           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8621           throw INTERP_KERNEL::Exception(oss.str().c_str());
8622         }
8623     }
8624 }
8625
8626 /*!
8627  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8628  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8629  * components.
8630  * The tuples to copy are defined by three values similar to parameters of
8631  * the Python function \c range(\c start,\c stop,\c step).
8632  * The tuples to assign to are defined by index of the first tuple, and
8633  * their number is defined by number of tuples to copy.
8634  * All components of selected tuples are copied.
8635  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8636  *              values to.
8637  *  \param [in] aBase - the array to copy values from.
8638  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8639  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8640  *              are located.
8641  *  \param [in] step - index increment to get index of the next tuple to copy.
8642  *  \throw If \a this is not allocated.
8643  *  \throw If \a aBase is NULL.
8644  *  \throw If \a aBase is not allocated.
8645  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8646  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8647  *  \throw If parameters specifying tuples to copy, do not give a
8648  *            non-empty range of increasing indices or indices are out of a valid range
8649  *            for the array \a aBase.
8650  */
8651 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8652 {
8653   if(!aBase)
8654     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8655   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8656   if(!a)
8657     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8658   checkAllocated();
8659   a->checkAllocated();
8660   int nbOfComp=getNumberOfComponents();
8661   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8662   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8663   if(nbOfComp!=a->getNumberOfComponents())
8664     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8665   int thisNt=getNumberOfTuples();
8666   int aNt=a->getNumberOfTuples();
8667   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8668   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8669     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8670   if(end2>aNt)
8671     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8672   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8673   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8674     {
8675       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8676     }
8677 }
8678
8679 /*!
8680  * Returns a value located at specified tuple and component.
8681  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8682  * parameters is checked. So this method is safe but expensive if used to go through
8683  * all values of \a this.
8684  *  \param [in] tupleId - index of tuple of interest.
8685  *  \param [in] compoId - index of component of interest.
8686  *  \return double - value located by \a tupleId and \a compoId.
8687  *  \throw If \a this is not allocated.
8688  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8689  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8690  */
8691 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8692 {
8693   checkAllocated();
8694   if(tupleId<0 || tupleId>=getNumberOfTuples())
8695     {
8696       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8697       throw INTERP_KERNEL::Exception(oss.str().c_str());
8698     }
8699   if(compoId<0 || compoId>=getNumberOfComponents())
8700     {
8701       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8702       throw INTERP_KERNEL::Exception(oss.str().c_str());
8703     }
8704   return _mem[tupleId*_info_on_compo.size()+compoId];
8705 }
8706
8707 /*!
8708  * Returns the first value of \a this. 
8709  *  \return int - the last value of \a this array.
8710  *  \throw If \a this is not allocated.
8711  *  \throw If \a this->getNumberOfComponents() != 1.
8712  *  \throw If \a this->getNumberOfTuples() < 1.
8713  */
8714 int DataArrayInt::front() const
8715 {
8716   checkAllocated();
8717   if(getNumberOfComponents()!=1)
8718     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8719   int nbOfTuples=getNumberOfTuples();
8720   if(nbOfTuples<1)
8721     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8722   return *(getConstPointer());
8723 }
8724
8725 /*!
8726  * Returns the last value of \a this. 
8727  *  \return int - the last value of \a this array.
8728  *  \throw If \a this is not allocated.
8729  *  \throw If \a this->getNumberOfComponents() != 1.
8730  *  \throw If \a this->getNumberOfTuples() < 1.
8731  */
8732 int DataArrayInt::back() const
8733 {
8734   checkAllocated();
8735   if(getNumberOfComponents()!=1)
8736     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8737   int nbOfTuples=getNumberOfTuples();
8738   if(nbOfTuples<1)
8739     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8740   return *(getConstPointer()+nbOfTuples-1);
8741 }
8742
8743 /*!
8744  * Assign pointer to one array to a pointer to another appay. Reference counter of
8745  * \a arrayToSet is incremented / decremented.
8746  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8747  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8748  */
8749 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8750 {
8751   if(newArray!=arrayToSet)
8752     {
8753       if(arrayToSet)
8754         arrayToSet->decrRef();
8755       arrayToSet=newArray;
8756       if(arrayToSet)
8757         arrayToSet->incrRef();
8758     }
8759 }
8760
8761 DataArrayIntIterator *DataArrayInt::iterator()
8762 {
8763   return new DataArrayIntIterator(this);
8764 }
8765
8766 /*!
8767  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8768  * given one. The ids are sorted in the ascending order.
8769  *  \param [in] val - the value to find within \a this.
8770  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8771  *          array using decrRef() as it is no more needed.
8772  *  \throw If \a this is not allocated.
8773  *  \throw If \a this->getNumberOfComponents() != 1.
8774  *  \sa DataArrayInt::getIdsEqualTuple
8775  */
8776 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8777 {
8778   checkAllocated();
8779   if(getNumberOfComponents()!=1)
8780     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8781   const int *cptr(getConstPointer());
8782   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8783   int nbOfTuples=getNumberOfTuples();
8784   for(int i=0;i<nbOfTuples;i++,cptr++)
8785     if(*cptr==val)
8786       ret->pushBackSilent(i);
8787   return ret.retn();
8788 }
8789
8790 /*!
8791  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8792  * equal to a given one. 
8793  *  \param [in] val - the value to ignore within \a this.
8794  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8795  *          array using decrRef() as it is no more needed.
8796  *  \throw If \a this is not allocated.
8797  *  \throw If \a this->getNumberOfComponents() != 1.
8798  */
8799 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8800 {
8801   checkAllocated();
8802   if(getNumberOfComponents()!=1)
8803     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8804   const int *cptr(getConstPointer());
8805   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8806   int nbOfTuples=getNumberOfTuples();
8807   for(int i=0;i<nbOfTuples;i++,cptr++)
8808     if(*cptr!=val)
8809       ret->pushBackSilent(i);
8810   return ret.retn();
8811 }
8812
8813 /*!
8814  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8815  * This method is an extension of  DataArrayInt::getIdsEqual method.
8816  *
8817  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8818  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8819  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8820  *          array using decrRef() as it is no more needed.
8821  *  \throw If \a this is not allocated.
8822  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8823  * \throw If \a this->getNumberOfComponents() is equal to 0.
8824  * \sa DataArrayInt::getIdsEqual
8825  */
8826 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8827 {
8828   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8829   checkAllocated();
8830   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8831     {
8832       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8833       throw INTERP_KERNEL::Exception(oss.str().c_str());
8834     }
8835   if(nbOfCompoExp==0)
8836     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8837   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8838   const int *bg(begin()),*end2(end()),*work(begin());
8839   while(work!=end2)
8840     {
8841       work=std::search(work,end2,tupleBg,tupleEnd);
8842       if(work!=end2)
8843         {
8844           std::size_t pos(std::distance(bg,work));
8845           if(pos%nbOfCompoExp==0)
8846             ret->pushBackSilent(pos/nbOfCompoExp);
8847           work++;
8848         }
8849     }
8850   return ret.retn();
8851 }
8852
8853 /*!
8854  * Assigns \a newValue to all elements holding \a oldValue within \a this
8855  * one-dimensional array.
8856  *  \param [in] oldValue - the value to replace.
8857  *  \param [in] newValue - the value to assign.
8858  *  \return int - number of replacements performed.
8859  *  \throw If \a this is not allocated.
8860  *  \throw If \a this->getNumberOfComponents() != 1.
8861  */
8862 int DataArrayInt::changeValue(int oldValue, int newValue)
8863 {
8864   checkAllocated();
8865   if(getNumberOfComponents()!=1)
8866     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8867   int *start=getPointer();
8868   int *end2=start+getNbOfElems();
8869   int ret=0;
8870   for(int *val=start;val!=end2;val++)
8871     {
8872       if(*val==oldValue)
8873         {
8874           *val=newValue;
8875           ret++;
8876         }
8877     }
8878   return ret;
8879 }
8880
8881 /*!
8882  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8883  * one of given values.
8884  *  \param [in] valsBg - an array of values to find within \a this array.
8885  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8886  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8887  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8888  *          array using decrRef() as it is no more needed.
8889  *  \throw If \a this->getNumberOfComponents() != 1.
8890  */
8891 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8892 {
8893   if(getNumberOfComponents()!=1)
8894     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8895   std::set<int> vals2(valsBg,valsEnd);
8896   const int *cptr=getConstPointer();
8897   std::vector<int> res;
8898   int nbOfTuples=getNumberOfTuples();
8899   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8900   for(int i=0;i<nbOfTuples;i++,cptr++)
8901     if(vals2.find(*cptr)!=vals2.end())
8902       ret->pushBackSilent(i);
8903   return ret.retn();
8904 }
8905
8906 /*!
8907  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8908  * equal to any of given values.
8909  *  \param [in] valsBg - an array of values to ignore within \a this array.
8910  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8911  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8912  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8913  *          array using decrRef() as it is no more needed.
8914  *  \throw If \a this->getNumberOfComponents() != 1.
8915  */
8916 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8917 {
8918   if(getNumberOfComponents()!=1)
8919     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8920   std::set<int> vals2(valsBg,valsEnd);
8921   const int *cptr=getConstPointer();
8922   std::vector<int> res;
8923   int nbOfTuples=getNumberOfTuples();
8924   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8925   for(int i=0;i<nbOfTuples;i++,cptr++)
8926     if(vals2.find(*cptr)==vals2.end())
8927       ret->pushBackSilent(i);
8928   return ret.retn();
8929 }
8930
8931 /*!
8932  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8933  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8934  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8935  * If any the tuple id is returned. If not -1 is returned.
8936  * 
8937  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8938  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8939  *
8940  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8941  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8942  */
8943 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8944 {
8945   checkAllocated();
8946   int nbOfCompo=getNumberOfComponents();
8947   if(nbOfCompo==0)
8948     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8949   if(nbOfCompo!=(int)tupl.size())
8950     {
8951       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8952       throw INTERP_KERNEL::Exception(oss.str().c_str());
8953     }
8954   const int *cptr=getConstPointer();
8955   std::size_t nbOfVals=getNbOfElems();
8956   for(const int *work=cptr;work!=cptr+nbOfVals;)
8957     {
8958       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8959       if(work!=cptr+nbOfVals)
8960         {
8961           if(std::distance(cptr,work)%nbOfCompo!=0)
8962             work++;
8963           else
8964             return std::distance(cptr,work)/nbOfCompo;
8965         }
8966     }
8967   return -1;
8968 }
8969
8970 /*!
8971  * This method searches the sequence specified in input parameter \b vals in \b this.
8972  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8973  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8974  * \sa DataArrayInt::locateTuple
8975  */
8976 int DataArrayInt::search(const std::vector<int>& vals) const
8977 {
8978   checkAllocated();
8979   int nbOfCompo=getNumberOfComponents();
8980   if(nbOfCompo!=1)
8981     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8982   const int *cptr=getConstPointer();
8983   std::size_t nbOfVals=getNbOfElems();
8984   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8985   if(loc!=cptr+nbOfVals)
8986     return std::distance(cptr,loc);
8987   return -1;
8988 }
8989
8990 /*!
8991  * This method expects to be called when number of components of this is equal to one.
8992  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8993  * If not any tuple contains \b value -1 is returned.
8994  * \sa DataArrayInt::presenceOfValue
8995  */
8996 int DataArrayInt::locateValue(int value) const
8997 {
8998   checkAllocated();
8999   if(getNumberOfComponents()!=1)
9000     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9001   const int *cptr=getConstPointer();
9002   int nbOfTuples=getNumberOfTuples();
9003   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
9004   if(ret!=cptr+nbOfTuples)
9005     return std::distance(cptr,ret);
9006   return -1;
9007 }
9008
9009 /*!
9010  * This method expects to be called when number of components of this is equal to one.
9011  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
9012  * If not any tuple contains one of the values contained in 'vals' false is returned.
9013  * \sa DataArrayInt::presenceOfValue
9014  */
9015 int DataArrayInt::locateValue(const std::vector<int>& vals) const
9016 {
9017   checkAllocated();
9018   if(getNumberOfComponents()!=1)
9019     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9020   std::set<int> vals2(vals.begin(),vals.end());
9021   const int *cptr=getConstPointer();
9022   int nbOfTuples=getNumberOfTuples();
9023   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
9024     if(vals2.find(*w)!=vals2.end())
9025       return std::distance(cptr,w);
9026   return -1;
9027 }
9028
9029 /*!
9030  * This method returns the number of values in \a this that are equals to input parameter \a value.
9031  * This method only works for single component array.
9032  *
9033  * \return a value in [ 0, \c this->getNumberOfTuples() )
9034  *
9035  * \throw If \a this is not allocated
9036  *
9037  */
9038 int DataArrayInt::count(int value) const
9039 {
9040   int ret=0;
9041   checkAllocated();
9042   if(getNumberOfComponents()!=1)
9043     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
9044   const int *vals=begin();
9045   int nbOfTuples=getNumberOfTuples();
9046   for(int i=0;i<nbOfTuples;i++,vals++)
9047     if(*vals==value)
9048       ret++;
9049   return ret;
9050 }
9051
9052 /*!
9053  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
9054  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9055  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9056  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9057  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9058  * \sa DataArrayInt::locateTuple
9059  */
9060 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
9061 {
9062   return locateTuple(tupl)!=-1;
9063 }
9064
9065
9066 /*!
9067  * Returns \a true if a given value is present within \a this one-dimensional array.
9068  *  \param [in] value - the value to find within \a this array.
9069  *  \return bool - \a true in case if \a value is present within \a this array.
9070  *  \throw If \a this is not allocated.
9071  *  \throw If \a this->getNumberOfComponents() != 1.
9072  *  \sa locateValue()
9073  */
9074 bool DataArrayInt::presenceOfValue(int value) const
9075 {
9076   return locateValue(value)!=-1;
9077 }
9078
9079 /*!
9080  * This method expects to be called when number of components of this is equal to one.
9081  * This method returns true if it exists a tuple so that the value is contained in \b vals.
9082  * If not any tuple contains one of the values contained in 'vals' false is returned.
9083  * \sa DataArrayInt::locateValue
9084  */
9085 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
9086 {
9087   return locateValue(vals)!=-1;
9088 }
9089
9090 /*!
9091  * Accumulates values of each component of \a this array.
9092  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
9093  *         by the caller, that is filled by this method with sum value for each
9094  *         component.
9095  *  \throw If \a this is not allocated.
9096  */
9097 void DataArrayInt::accumulate(int *res) const
9098 {
9099   checkAllocated();
9100   const int *ptr=getConstPointer();
9101   int nbTuple=getNumberOfTuples();
9102   int nbComps=getNumberOfComponents();
9103   std::fill(res,res+nbComps,0);
9104   for(int i=0;i<nbTuple;i++)
9105     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9106 }
9107
9108 int DataArrayInt::accumulate(int compId) const
9109 {
9110   checkAllocated();
9111   const int *ptr=getConstPointer();
9112   int nbTuple=getNumberOfTuples();
9113   int nbComps=getNumberOfComponents();
9114   if(compId<0 || compId>=nbComps)
9115     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9116   int ret=0;
9117   for(int i=0;i<nbTuple;i++)
9118     ret+=ptr[i*nbComps+compId];
9119   return ret;
9120 }
9121
9122 /*!
9123  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9124  * The returned array will have same number of components than \a this and number of tuples equal to
9125  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9126  *
9127  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9128  *
9129  * \param [in] bgOfIndex - begin (included) of the input index array.
9130  * \param [in] endOfIndex - end (excluded) of the input index array.
9131  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9132  * 
9133  * \throw If bgOfIndex or end is NULL.
9134  * \throw If input index array is not ascendingly sorted.
9135  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9136  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9137  */
9138 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9139 {
9140   if(!bgOfIndex || !endOfIndex)
9141     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9142   checkAllocated();
9143   int nbCompo=getNumberOfComponents();
9144   int nbOfTuples=getNumberOfTuples();
9145   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9146   if(sz<1)
9147     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9148   sz--;
9149   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9150   const int *w=bgOfIndex;
9151   if(*w<0 || *w>=nbOfTuples)
9152     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9153   const int *srcPt=begin()+(*w)*nbCompo;
9154   int *tmp=ret->getPointer();
9155   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9156     {
9157       std::fill(tmp,tmp+nbCompo,0);
9158       if(w[1]>=w[0])
9159         {
9160           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9161             {
9162               if(j>=0 && j<nbOfTuples)
9163                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9164               else
9165                 {
9166                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9167                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9168                 }
9169             }
9170         }
9171       else
9172         {
9173           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9174           throw INTERP_KERNEL::Exception(oss.str().c_str());
9175         }
9176     }
9177   ret->copyStringInfoFrom(*this);
9178   return ret.retn();
9179 }
9180
9181 /*!
9182  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9183  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9184  * offsetA2</em> and (2)
9185  * the number of component in the result array is same as that of each of given arrays.
9186  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9187  * Info on components is copied from the first of the given arrays. Number of components
9188  * in the given arrays must be the same.
9189  *  \param [in] a1 - an array to include in the result array.
9190  *  \param [in] a2 - another array to include in the result array.
9191  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9192  *  \return DataArrayInt * - the new instance of DataArrayInt.
9193  *          The caller is to delete this result array using decrRef() as it is no more
9194  *          needed.
9195  *  \throw If either \a a1 or \a a2 is NULL.
9196  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9197  */
9198 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9199 {
9200   if(!a1 || !a2)
9201     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9202   int nbOfComp=a1->getNumberOfComponents();
9203   if(nbOfComp!=a2->getNumberOfComponents())
9204     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9205   int nbOfTuple1=a1->getNumberOfTuples();
9206   int nbOfTuple2=a2->getNumberOfTuples();
9207   DataArrayInt *ret=DataArrayInt::New();
9208   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9209   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9210   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9211   ret->copyStringInfoFrom(*a1);
9212   return ret;
9213 }
9214
9215 /*!
9216  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9217  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9218  * the number of component in the result array is same as that of each of given arrays.
9219  * Info on components is copied from the first of the given arrays. Number of components
9220  * in the given arrays must be  the same.
9221  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9222  * not the object itself.
9223  *  \param [in] arr - a sequence of arrays to include in the result array.
9224  *  \return DataArrayInt * - the new instance of DataArrayInt.
9225  *          The caller is to delete this result array using decrRef() as it is no more
9226  *          needed.
9227  *  \throw If all arrays within \a arr are NULL.
9228  *  \throw If getNumberOfComponents() of arrays within \a arr.
9229  */
9230 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9231 {
9232   std::vector<const DataArrayInt *> a;
9233   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9234     if(*it4)
9235       a.push_back(*it4);
9236   if(a.empty())
9237     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9238   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9239   int nbOfComp=(*it)->getNumberOfComponents();
9240   int nbt=(*it++)->getNumberOfTuples();
9241   for(int i=1;it!=a.end();it++,i++)
9242     {
9243       if((*it)->getNumberOfComponents()!=nbOfComp)
9244         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9245       nbt+=(*it)->getNumberOfTuples();
9246     }
9247   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9248   ret->alloc(nbt,nbOfComp);
9249   int *pt=ret->getPointer();
9250   for(it=a.begin();it!=a.end();it++)
9251     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9252   ret->copyStringInfoFrom(*(a[0]));
9253   return ret.retn();
9254 }
9255
9256 /*!
9257  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9258  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9259  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9260  * 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.
9261  * 
9262  * \return DataArrayInt * - a new object to be managed by the caller.
9263  */
9264 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9265 {
9266   int retSz=1;
9267   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9268     {
9269       if(*it4)
9270         {
9271           (*it4)->checkAllocated();
9272           if((*it4)->getNumberOfComponents()!=1)
9273             {
9274               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9275               throw INTERP_KERNEL::Exception(oss.str().c_str());
9276             }
9277           int nbTupl=(*it4)->getNumberOfTuples();
9278           if(nbTupl<1)
9279             {
9280               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9281               throw INTERP_KERNEL::Exception(oss.str().c_str());
9282             }
9283           if((*it4)->front()!=0)
9284             {
9285               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9286               throw INTERP_KERNEL::Exception(oss.str().c_str());
9287             }
9288           retSz+=nbTupl-1;
9289         }
9290       else
9291         {
9292           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9293           throw INTERP_KERNEL::Exception(oss.str().c_str());
9294         }
9295     }
9296   if(arrs.empty())
9297     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9298   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9299   ret->alloc(retSz,1);
9300   int *pt=ret->getPointer(); *pt++=0;
9301   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9302     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9303   ret->copyStringInfoFrom(*(arrs[0]));
9304   return ret.retn();
9305 }
9306
9307 /*!
9308  * Returns the maximal value and its location within \a this one-dimensional array.
9309  *  \param [out] tupleId - index of the tuple holding the maximal value.
9310  *  \return int - the maximal value among all values of \a this array.
9311  *  \throw If \a this->getNumberOfComponents() != 1
9312  *  \throw If \a this->getNumberOfTuples() < 1
9313  */
9314 int DataArrayInt::getMaxValue(int& tupleId) const
9315 {
9316   checkAllocated();
9317   if(getNumberOfComponents()!=1)
9318     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9319   int nbOfTuples=getNumberOfTuples();
9320   if(nbOfTuples<=0)
9321     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9322   const int *vals=getConstPointer();
9323   const int *loc=std::max_element(vals,vals+nbOfTuples);
9324   tupleId=(int)std::distance(vals,loc);
9325   return *loc;
9326 }
9327
9328 /*!
9329  * Returns the maximal value within \a this array that is allowed to have more than
9330  *  one component.
9331  *  \return int - the maximal value among all values of \a this array.
9332  *  \throw If \a this is not allocated.
9333  */
9334 int DataArrayInt::getMaxValueInArray() const
9335 {
9336   checkAllocated();
9337   const int *loc=std::max_element(begin(),end());
9338   return *loc;
9339 }
9340
9341 /*!
9342  * Returns the minimal value and its location within \a this one-dimensional array.
9343  *  \param [out] tupleId - index of the tuple holding the minimal value.
9344  *  \return int - the minimal value among all values of \a this array.
9345  *  \throw If \a this->getNumberOfComponents() != 1
9346  *  \throw If \a this->getNumberOfTuples() < 1
9347  */
9348 int DataArrayInt::getMinValue(int& tupleId) const
9349 {
9350   checkAllocated();
9351   if(getNumberOfComponents()!=1)
9352     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9353   int nbOfTuples=getNumberOfTuples();
9354   if(nbOfTuples<=0)
9355     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9356   const int *vals=getConstPointer();
9357   const int *loc=std::min_element(vals,vals+nbOfTuples);
9358   tupleId=(int)std::distance(vals,loc);
9359   return *loc;
9360 }
9361
9362 /*!
9363  * Returns the minimal value within \a this array that is allowed to have more than
9364  *  one component.
9365  *  \return int - the minimal value among all values of \a this array.
9366  *  \throw If \a this is not allocated.
9367  */
9368 int DataArrayInt::getMinValueInArray() const
9369 {
9370   checkAllocated();
9371   const int *loc=std::min_element(begin(),end());
9372   return *loc;
9373 }
9374
9375 /*!
9376  * Returns in a single walk in \a this the min value and the max value in \a this.
9377  * \a this is expected to be single component array.
9378  *
9379  * \param [out] minValue - the min value in \a this.
9380  * \param [out] maxValue - the max value in \a this.
9381  *
9382  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9383  */
9384 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9385 {
9386   checkAllocated();
9387   if(getNumberOfComponents()!=1)
9388     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9389   int nbTuples(getNumberOfTuples());
9390   const int *pt(begin());
9391   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9392   for(int i=0;i<nbTuples;i++,pt++)
9393     {
9394       if(*pt<minValue)
9395         minValue=*pt;
9396       if(*pt>maxValue)
9397         maxValue=*pt;
9398     }
9399 }
9400
9401 /*!
9402  * Converts every value of \a this array to its absolute value.
9403  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9404  * should be called instead.
9405  *
9406  * \throw If \a this is not allocated.
9407  * \sa DataArrayInt::computeAbs
9408  */
9409 void DataArrayInt::abs()
9410 {
9411   checkAllocated();
9412   int *ptr(getPointer());
9413   std::size_t nbOfElems(getNbOfElems());
9414   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9415   declareAsNew();
9416 }
9417
9418 /*!
9419  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9420  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9421  *
9422  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9423  *         same number of tuples and component as \a this array.
9424  *         The caller is to delete this result array using decrRef() as it is no more
9425  *         needed.
9426  * \throw If \a this is not allocated.
9427  * \sa DataArrayInt::abs
9428  */
9429 DataArrayInt *DataArrayInt::computeAbs() const
9430 {
9431   checkAllocated();
9432   DataArrayInt *newArr(DataArrayInt::New());
9433   int nbOfTuples(getNumberOfTuples());
9434   int nbOfComp(getNumberOfComponents());
9435   newArr->alloc(nbOfTuples,nbOfComp);
9436   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9437   newArr->copyStringInfoFrom(*this);
9438   return newArr;
9439 }
9440
9441 /*!
9442  * Apply a liner function to a given component of \a this array, so that
9443  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9444  *  \param [in] a - the first coefficient of the function.
9445  *  \param [in] b - the second coefficient of the function.
9446  *  \param [in] compoId - the index of component to modify.
9447  *  \throw If \a this is not allocated.
9448  */
9449 void DataArrayInt::applyLin(int a, int b, int compoId)
9450 {
9451   checkAllocated();
9452   int *ptr=getPointer()+compoId;
9453   int nbOfComp=getNumberOfComponents();
9454   int nbOfTuple=getNumberOfTuples();
9455   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9456     *ptr=a*(*ptr)+b;
9457   declareAsNew();
9458 }
9459
9460 /*!
9461  * Apply a liner function to all elements of \a this array, so that
9462  * an element _x_ becomes \f$ a * x + b \f$.
9463  *  \param [in] a - the first coefficient of the function.
9464  *  \param [in] b - the second coefficient of the function.
9465  *  \throw If \a this is not allocated.
9466  */
9467 void DataArrayInt::applyLin(int a, int b)
9468 {
9469   checkAllocated();
9470   int *ptr=getPointer();
9471   std::size_t nbOfElems=getNbOfElems();
9472   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9473     *ptr=a*(*ptr)+b;
9474   declareAsNew();
9475 }
9476
9477 /*!
9478  * Returns a full copy of \a this array except that sign of all elements is reversed.
9479  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9480  *          same number of tuples and component as \a this array.
9481  *          The caller is to delete this result array using decrRef() as it is no more
9482  *          needed.
9483  *  \throw If \a this is not allocated.
9484  */
9485 DataArrayInt *DataArrayInt::negate() const
9486 {
9487   checkAllocated();
9488   DataArrayInt *newArr=DataArrayInt::New();
9489   int nbOfTuples=getNumberOfTuples();
9490   int nbOfComp=getNumberOfComponents();
9491   newArr->alloc(nbOfTuples,nbOfComp);
9492   const int *cptr=getConstPointer();
9493   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9494   newArr->copyStringInfoFrom(*this);
9495   return newArr;
9496 }
9497
9498 /*!
9499  * Modify all elements of \a this array, so that
9500  * an element _x_ becomes \f$ numerator / x \f$.
9501  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9502  *           array, all elements processed before detection of the zero element remain
9503  *           modified.
9504  *  \param [in] numerator - the numerator used to modify array elements.
9505  *  \throw If \a this is not allocated.
9506  *  \throw If there is an element equal to 0 in \a this array.
9507  */
9508 void DataArrayInt::applyInv(int numerator)
9509 {
9510   checkAllocated();
9511   int *ptr=getPointer();
9512   std::size_t nbOfElems=getNbOfElems();
9513   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9514     {
9515       if(*ptr!=0)
9516         {
9517           *ptr=numerator/(*ptr);
9518         }
9519       else
9520         {
9521           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9522           oss << " !";
9523           throw INTERP_KERNEL::Exception(oss.str().c_str());
9524         }
9525     }
9526   declareAsNew();
9527 }
9528
9529 /*!
9530  * Modify all elements of \a this array, so that
9531  * an element _x_ becomes \f$ x / val \f$.
9532  *  \param [in] val - the denominator used to modify array elements.
9533  *  \throw If \a this is not allocated.
9534  *  \throw If \a val == 0.
9535  */
9536 void DataArrayInt::applyDivideBy(int val)
9537 {
9538   if(val==0)
9539     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9540   checkAllocated();
9541   int *ptr=getPointer();
9542   std::size_t nbOfElems=getNbOfElems();
9543   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9544   declareAsNew();
9545 }
9546
9547 /*!
9548  * Modify all elements of \a this array, so that
9549  * an element _x_ becomes  <em> x % val </em>.
9550  *  \param [in] val - the divisor used to modify array elements.
9551  *  \throw If \a this is not allocated.
9552  *  \throw If \a val <= 0.
9553  */
9554 void DataArrayInt::applyModulus(int val)
9555 {
9556   if(val<=0)
9557     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9558   checkAllocated();
9559   int *ptr=getPointer();
9560   std::size_t nbOfElems=getNbOfElems();
9561   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9562   declareAsNew();
9563 }
9564
9565 /*!
9566  * This method works only on data array with one component.
9567  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9568  * this[*id] in [\b vmin,\b vmax)
9569  * 
9570  * \param [in] vmin begin of range. This value is included in range (included).
9571  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9572  * \return a newly allocated data array that the caller should deal with.
9573  *
9574  * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative
9575  */
9576 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9577 {
9578   checkAllocated();
9579   if(getNumberOfComponents()!=1)
9580     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9581   const int *cptr(begin());
9582   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9583   int nbOfTuples(getNumberOfTuples());
9584   for(int i=0;i<nbOfTuples;i++,cptr++)
9585     if(*cptr>=vmin && *cptr<vmax)
9586       ret->pushBackSilent(i);
9587   return ret.retn();
9588 }
9589
9590 /*!
9591  * This method works only on data array with one component.
9592  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9593  * this[*id] \b not in [\b vmin,\b vmax)
9594  * 
9595  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9596  * \param [in] vmax end of range. This value is included in range (included).
9597  * \return a newly allocated data array that the caller should deal with.
9598  * 
9599  * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative
9600  */
9601 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9602 {
9603   checkAllocated();
9604   if(getNumberOfComponents()!=1)
9605     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9606   const int *cptr(getConstPointer());
9607   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9608   int nbOfTuples(getNumberOfTuples());
9609   for(int i=0;i<nbOfTuples;i++,cptr++)
9610     if(*cptr<vmin || *cptr>=vmax)
9611       ret->pushBackSilent(i);
9612   return ret.retn();
9613 }
9614
9615 /*!
9616  * 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.
9617  *
9618  * \return a newly allocated data array that the caller should deal with.
9619  * \sa DataArrayInt::getIdsInRange
9620  */
9621 DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const
9622 {
9623   checkAllocated();
9624   if(getNumberOfComponents()!=1)
9625     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !");
9626   const int *cptr(getConstPointer());
9627   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9628   int nbOfTuples(getNumberOfTuples());
9629   for(int i=0;i<nbOfTuples;i++,cptr++)
9630     if(*cptr<0)
9631       ret->pushBackSilent(i);
9632   return ret.retn();
9633 }
9634
9635 /*!
9636  * This method works only on data array with one component.
9637  * 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.
9638  * 
9639  * \param [in] vmin begin of range. This value is included in range (included).
9640  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9641  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9642 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9643 {
9644   checkAllocated();
9645   if(getNumberOfComponents()!=1)
9646     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9647   int nbOfTuples=getNumberOfTuples();
9648   bool ret=true;
9649   const int *cptr=getConstPointer();
9650   for(int i=0;i<nbOfTuples;i++,cptr++)
9651     {
9652       if(*cptr>=vmin && *cptr<vmax)
9653         { ret=ret && *cptr==i; }
9654       else
9655         {
9656           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9657           throw INTERP_KERNEL::Exception(oss.str().c_str());
9658         }
9659     }
9660   return ret;
9661 }
9662
9663 /*!
9664  * Modify all elements of \a this array, so that
9665  * an element _x_ becomes <em> val % x </em>.
9666  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9667  *           array, all elements processed before detection of the zero element remain
9668  *           modified.
9669  *  \param [in] val - the divident used to modify array elements.
9670  *  \throw If \a this is not allocated.
9671  *  \throw If there is an element equal to or less than 0 in \a this array.
9672  */
9673 void DataArrayInt::applyRModulus(int val)
9674 {
9675   checkAllocated();
9676   int *ptr=getPointer();
9677   std::size_t nbOfElems=getNbOfElems();
9678   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9679     {
9680       if(*ptr>0)
9681         {
9682           *ptr=val%(*ptr);
9683         }
9684       else
9685         {
9686           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9687           oss << " !";
9688           throw INTERP_KERNEL::Exception(oss.str().c_str());
9689         }
9690     }
9691   declareAsNew();
9692 }
9693
9694 /*!
9695  * Modify all elements of \a this array, so that
9696  * an element _x_ becomes <em> val ^ x </em>.
9697  *  \param [in] val - the value used to apply pow on all array elements.
9698  *  \throw If \a this is not allocated.
9699  *  \throw If \a val < 0.
9700  */
9701 void DataArrayInt::applyPow(int val)
9702 {
9703   checkAllocated();
9704   if(val<0)
9705     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9706   int *ptr=getPointer();
9707   std::size_t nbOfElems=getNbOfElems();
9708   if(val==0)
9709     {
9710       std::fill(ptr,ptr+nbOfElems,1);
9711       return ;
9712     }
9713   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9714     {
9715       int tmp=1;
9716       for(int j=0;j<val;j++)
9717         tmp*=*ptr;
9718       *ptr=tmp;
9719     }
9720   declareAsNew();
9721 }
9722
9723 /*!
9724  * Modify all elements of \a this array, so that
9725  * an element _x_ becomes \f$ val ^ x \f$.
9726  *  \param [in] val - the value used to apply pow on all array elements.
9727  *  \throw If \a this is not allocated.
9728  *  \throw If there is an element < 0 in \a this array.
9729  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9730  *           array, all elements processed before detection of the zero element remain
9731  *           modified.
9732  */
9733 void DataArrayInt::applyRPow(int val)
9734 {
9735   checkAllocated();
9736   int *ptr=getPointer();
9737   std::size_t nbOfElems=getNbOfElems();
9738   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9739     {
9740       if(*ptr>=0)
9741         {
9742           int tmp=1;
9743           for(int j=0;j<*ptr;j++)
9744             tmp*=val;
9745           *ptr=tmp;
9746         }
9747       else
9748         {
9749           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9750           oss << " !";
9751           throw INTERP_KERNEL::Exception(oss.str().c_str());
9752         }
9753     }
9754   declareAsNew();
9755 }
9756
9757 /*!
9758  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9759  * of components in the result array is a sum of the number of components of given arrays
9760  * and (2) the number of tuples in the result array is same as that of each of given
9761  * arrays. In other words the i-th tuple of result array includes all components of
9762  * i-th tuples of all given arrays.
9763  * Number of tuples in the given arrays must be the same.
9764  *  \param [in] a1 - an array to include in the result array.
9765  *  \param [in] a2 - another array to include in the result array.
9766  *  \return DataArrayInt * - the new instance of DataArrayInt.
9767  *          The caller is to delete this result array using decrRef() as it is no more
9768  *          needed.
9769  *  \throw If both \a a1 and \a a2 are NULL.
9770  *  \throw If any given array is not allocated.
9771  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9772  */
9773 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9774 {
9775   std::vector<const DataArrayInt *> arr(2);
9776   arr[0]=a1; arr[1]=a2;
9777   return Meld(arr);
9778 }
9779
9780 /*!
9781  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9782  * of components in the result array is a sum of the number of components of given arrays
9783  * and (2) the number of tuples in the result array is same as that of each of given
9784  * arrays. In other words the i-th tuple of result array includes all components of
9785  * i-th tuples of all given arrays.
9786  * Number of tuples in the given arrays must be  the same.
9787  *  \param [in] arr - a sequence of arrays to include in the result array.
9788  *  \return DataArrayInt * - the new instance of DataArrayInt.
9789  *          The caller is to delete this result array using decrRef() as it is no more
9790  *          needed.
9791  *  \throw If all arrays within \a arr are NULL.
9792  *  \throw If any given array is not allocated.
9793  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9794  */
9795 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9796 {
9797   std::vector<const DataArrayInt *> a;
9798   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9799     if(*it4)
9800       a.push_back(*it4);
9801   if(a.empty())
9802     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9803   std::vector<const DataArrayInt *>::const_iterator it;
9804   for(it=a.begin();it!=a.end();it++)
9805     (*it)->checkAllocated();
9806   it=a.begin();
9807   int nbOfTuples=(*it)->getNumberOfTuples();
9808   std::vector<int> nbc(a.size());
9809   std::vector<const int *> pts(a.size());
9810   nbc[0]=(*it)->getNumberOfComponents();
9811   pts[0]=(*it++)->getConstPointer();
9812   for(int i=1;it!=a.end();it++,i++)
9813     {
9814       if(nbOfTuples!=(*it)->getNumberOfTuples())
9815         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9816       nbc[i]=(*it)->getNumberOfComponents();
9817       pts[i]=(*it)->getConstPointer();
9818     }
9819   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9820   DataArrayInt *ret=DataArrayInt::New();
9821   ret->alloc(nbOfTuples,totalNbOfComp);
9822   int *retPtr=ret->getPointer();
9823   for(int i=0;i<nbOfTuples;i++)
9824     for(int j=0;j<(int)a.size();j++)
9825       {
9826         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9827         pts[j]+=nbc[j];
9828       }
9829   int k=0;
9830   for(int i=0;i<(int)a.size();i++)
9831     for(int j=0;j<nbc[i];j++,k++)
9832       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9833   return ret;
9834 }
9835
9836 /*!
9837  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9838  * The i-th item of the result array is an ID of a set of elements belonging to a
9839  * unique set of groups, which the i-th element is a part of. This set of elements
9840  * belonging to a unique set of groups is called \a family, so the result array contains
9841  * IDs of families each element belongs to.
9842  *
9843  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9844  * then there are 3 families:
9845  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9846  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9847  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9848  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9849  * stands for the element #3 which is in none of groups.
9850  *
9851  *  \param [in] groups - sequence of groups of element IDs.
9852  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9853  *         in \a groups.
9854  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9855  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9856  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9857  *         delete this array using decrRef() as it is no more needed.
9858  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9859  */
9860 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9861 {
9862   std::vector<const DataArrayInt *> groups2;
9863   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9864     if(*it4)
9865       groups2.push_back(*it4);
9866   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9867   ret->alloc(newNb,1);
9868   int *retPtr=ret->getPointer();
9869   std::fill(retPtr,retPtr+newNb,0);
9870   int fid=1;
9871   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9872     {
9873       const int *ptr=(*iter)->getConstPointer();
9874       std::size_t nbOfElem=(*iter)->getNbOfElems();
9875       int sfid=fid;
9876       for(int j=0;j<sfid;j++)
9877         {
9878           bool found=false;
9879           for(std::size_t i=0;i<nbOfElem;i++)
9880             {
9881               if(ptr[i]>=0 && ptr[i]<newNb)
9882                 {
9883                   if(retPtr[ptr[i]]==j)
9884                     {
9885                       retPtr[ptr[i]]=fid;
9886                       found=true;
9887                     }
9888                 }
9889               else
9890                 {
9891                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9892                   oss << ") !";
9893                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9894                 }
9895             }
9896           if(found)
9897             fid++;
9898         }
9899     }
9900   fidsOfGroups.clear();
9901   fidsOfGroups.resize(groups2.size());
9902   int grId=0;
9903   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9904     {
9905       std::set<int> tmp;
9906       const int *ptr=(*iter)->getConstPointer();
9907       std::size_t nbOfElem=(*iter)->getNbOfElems();
9908       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9909         tmp.insert(retPtr[*p]);
9910       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9911     }
9912   return ret.retn();
9913 }
9914
9915 /*!
9916  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9917  * arrays. The result array does not contain any duplicates and its values
9918  * are sorted in ascending order.
9919  *  \param [in] arr - sequence of DataArrayInt's to unite.
9920  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9921  *         array using decrRef() as it is no more needed.
9922  *  \throw If any \a arr[i] is not allocated.
9923  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9924  */
9925 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9926 {
9927   std::vector<const DataArrayInt *> a;
9928   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9929     if(*it4)
9930       a.push_back(*it4);
9931   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9932     {
9933       (*it)->checkAllocated();
9934       if((*it)->getNumberOfComponents()!=1)
9935         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9936     }
9937   //
9938   std::set<int> r;
9939   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9940     {
9941       const int *pt=(*it)->getConstPointer();
9942       int nbOfTuples=(*it)->getNumberOfTuples();
9943       r.insert(pt,pt+nbOfTuples);
9944     }
9945   DataArrayInt *ret=DataArrayInt::New();
9946   ret->alloc((int)r.size(),1);
9947   std::copy(r.begin(),r.end(),ret->getPointer());
9948   return ret;
9949 }
9950
9951 /*!
9952  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9953  * arrays. The result array does not contain any duplicates and its values
9954  * are sorted in ascending order.
9955  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9956  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9957  *         array using decrRef() as it is no more needed.
9958  *  \throw If any \a arr[i] is not allocated.
9959  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9960  */
9961 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9962 {
9963   std::vector<const DataArrayInt *> a;
9964   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9965     if(*it4)
9966       a.push_back(*it4);
9967   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9968     {
9969       (*it)->checkAllocated();
9970       if((*it)->getNumberOfComponents()!=1)
9971         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9972     }
9973   //
9974   std::set<int> r;
9975   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9976     {
9977       const int *pt=(*it)->getConstPointer();
9978       int nbOfTuples=(*it)->getNumberOfTuples();
9979       std::set<int> s1(pt,pt+nbOfTuples);
9980       if(it!=a.begin())
9981         {
9982           std::set<int> r2;
9983           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9984           r=r2;
9985         }
9986       else
9987         r=s1;
9988     }
9989   DataArrayInt *ret(DataArrayInt::New());
9990   ret->alloc((int)r.size(),1);
9991   std::copy(r.begin(),r.end(),ret->getPointer());
9992   return ret;
9993 }
9994
9995 /// @cond INTERNAL
9996 namespace ParaMEDMEMImpl
9997 {
9998   class OpSwitchedOn
9999   {
10000   public:
10001     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
10002     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
10003   private:
10004     int *_pt;
10005     int _cnt;
10006   };
10007
10008   class OpSwitchedOff
10009   {
10010   public:
10011     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
10012     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
10013   private:
10014     int *_pt;
10015     int _cnt;
10016   };
10017 }
10018 /// @endcond
10019
10020 /*!
10021  * This method returns the list of ids in ascending mode so that v[id]==true.
10022  */
10023 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
10024 {
10025   int sz((int)std::count(v.begin(),v.end(),true));
10026   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10027   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
10028   return ret.retn();
10029 }
10030
10031 /*!
10032  * This method returns the list of ids in ascending mode so that v[id]==false.
10033  */
10034 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
10035 {
10036   int sz((int)std::count(v.begin(),v.end(),false));
10037   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10038   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
10039   return ret.retn();
10040 }
10041
10042 /*!
10043  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
10044  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
10045  *
10046  * \param [in] v the input data structure to be translate into skyline format.
10047  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
10048  * \param [out] dataIndex the second element of the skyline format.
10049  */
10050 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
10051 {
10052   int sz((int)v.size());
10053   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
10054   ret1->alloc(sz+1,1);
10055   int *pt(ret1->getPointer()); *pt=0;
10056   for(int i=0;i<sz;i++,pt++)
10057     pt[1]=pt[0]+(int)v[i].size();
10058   ret0->alloc(ret1->back(),1);
10059   pt=ret0->getPointer();
10060   for(int i=0;i<sz;i++)
10061     pt=std::copy(v[i].begin(),v[i].end(),pt);
10062   data=ret0.retn(); dataIndex=ret1.retn();
10063 }
10064
10065 /*!
10066  * Returns a new DataArrayInt which contains a complement of elements of \a this
10067  * one-dimensional array. I.e. the result array contains all elements from the range [0,
10068  * \a nbOfElement) not present in \a this array.
10069  *  \param [in] nbOfElement - maximal size of the result array.
10070  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10071  *         array using decrRef() as it is no more needed.
10072  *  \throw If \a this is not allocated.
10073  *  \throw If \a this->getNumberOfComponents() != 1.
10074  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
10075  *         nbOfElement ).
10076  */
10077 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
10078 {
10079   checkAllocated();
10080   if(getNumberOfComponents()!=1)
10081     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
10082   std::vector<bool> tmp(nbOfElement);
10083   const int *pt=getConstPointer();
10084   int nbOfTuples=getNumberOfTuples();
10085   for(const int *w=pt;w!=pt+nbOfTuples;w++)
10086     if(*w>=0 && *w<nbOfElement)
10087       tmp[*w]=true;
10088     else
10089       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
10090   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
10091   DataArrayInt *ret=DataArrayInt::New();
10092   ret->alloc(nbOfRetVal,1);
10093   int j=0;
10094   int *retPtr=ret->getPointer();
10095   for(int i=0;i<nbOfElement;i++)
10096     if(!tmp[i])
10097       retPtr[j++]=i;
10098   return ret;
10099 }
10100
10101 /*!
10102  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10103  * from an \a other one-dimensional array.
10104  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10105  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10106  *         caller is to delete this array using decrRef() as it is no more needed.
10107  *  \throw If \a other is NULL.
10108  *  \throw If \a other is not allocated.
10109  *  \throw If \a other->getNumberOfComponents() != 1.
10110  *  \throw If \a this is not allocated.
10111  *  \throw If \a this->getNumberOfComponents() != 1.
10112  *  \sa DataArrayInt::buildSubstractionOptimized()
10113  */
10114 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10115 {
10116   if(!other)
10117     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10118   checkAllocated();
10119   other->checkAllocated();
10120   if(getNumberOfComponents()!=1)
10121     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10122   if(other->getNumberOfComponents()!=1)
10123     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10124   const int *pt=getConstPointer();
10125   int nbOfTuples=getNumberOfTuples();
10126   std::set<int> s1(pt,pt+nbOfTuples);
10127   pt=other->getConstPointer();
10128   nbOfTuples=other->getNumberOfTuples();
10129   std::set<int> s2(pt,pt+nbOfTuples);
10130   std::vector<int> r;
10131   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10132   DataArrayInt *ret=DataArrayInt::New();
10133   ret->alloc((int)r.size(),1);
10134   std::copy(r.begin(),r.end(),ret->getPointer());
10135   return ret;
10136 }
10137
10138 /*!
10139  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10140  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10141  * 
10142  * \param [in] other an array with one component and expected to be sorted ascendingly.
10143  * \ret list of ids in \a this but not in \a other.
10144  * \sa DataArrayInt::buildSubstraction
10145  */
10146 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10147 {
10148   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10149   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10150   checkAllocated(); other->checkAllocated();
10151   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10152   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10153   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10154   const int *work1(pt1Bg),*work2(pt2Bg);
10155   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10156   for(;work1!=pt1End;work1++)
10157     {
10158       if(work2!=pt2End && *work1==*work2)
10159         work2++;
10160       else
10161         ret->pushBackSilent(*work1);
10162     }
10163   return ret.retn();
10164 }
10165
10166
10167 /*!
10168  * Returns a new DataArrayInt which contains all elements of \a this and a given
10169  * one-dimensional arrays. The result array does not contain any duplicates
10170  * and its values are sorted in ascending order.
10171  *  \param [in] other - an array to unite with \a this one.
10172  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10173  *         array using decrRef() as it is no more needed.
10174  *  \throw If \a this or \a other is not allocated.
10175  *  \throw If \a this->getNumberOfComponents() != 1.
10176  *  \throw If \a other->getNumberOfComponents() != 1.
10177  */
10178 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10179 {
10180   std::vector<const DataArrayInt *>arrs(2);
10181   arrs[0]=this; arrs[1]=other;
10182   return BuildUnion(arrs);
10183 }
10184
10185
10186 /*!
10187  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10188  * one-dimensional arrays. The result array does not contain any duplicates
10189  * and its values are sorted in ascending order.
10190  *  \param [in] other - an array to intersect with \a this one.
10191  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10192  *         array using decrRef() as it is no more needed.
10193  *  \throw If \a this or \a other is not allocated.
10194  *  \throw If \a this->getNumberOfComponents() != 1.
10195  *  \throw If \a other->getNumberOfComponents() != 1.
10196  */
10197 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10198 {
10199   std::vector<const DataArrayInt *>arrs(2);
10200   arrs[0]=this; arrs[1]=other;
10201   return BuildIntersection(arrs);
10202 }
10203
10204 /*!
10205  * This method can be applied on allocated with one component DataArrayInt instance.
10206  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10207  * 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]
10208  * 
10209  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10210  * \throw if \a this is not allocated or if \a this has not exactly one component.
10211  * \sa DataArrayInt::buildUniqueNotSorted
10212  */
10213 DataArrayInt *DataArrayInt::buildUnique() const
10214 {
10215   checkAllocated();
10216   if(getNumberOfComponents()!=1)
10217     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10218   int nbOfTuples=getNumberOfTuples();
10219   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
10220   int *data=tmp->getPointer();
10221   int *last=std::unique(data,data+nbOfTuples);
10222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10223   ret->alloc(std::distance(data,last),1);
10224   std::copy(data,last,ret->getPointer());
10225   return ret.retn();
10226 }
10227
10228 /*!
10229  * This method can be applied on allocated with one component DataArrayInt instance.
10230  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10231  *
10232  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10233  *
10234  * \throw if \a this is not allocated or if \a this has not exactly one component.
10235  *
10236  * \sa DataArrayInt::buildUnique
10237  */
10238 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10239 {
10240   checkAllocated();
10241     if(getNumberOfComponents()!=1)
10242       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10243   int minVal,maxVal;
10244   getMinMaxValues(minVal,maxVal);
10245   std::vector<bool> b(maxVal-minVal+1,false);
10246   const int *ptBg(begin()),*endBg(end());
10247   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10248   for(const int *pt=ptBg;pt!=endBg;pt++)
10249     {
10250       if(!b[*pt-minVal])
10251         {
10252           ret->pushBackSilent(*pt);
10253           b[*pt-minVal]=true;
10254         }
10255     }
10256   ret->copyStringInfoFrom(*this);
10257   return ret.retn();
10258 }
10259
10260 /*!
10261  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10262  * "index" array. Such "index" array is returned for example by 
10263  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
10264  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10265  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
10266  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10267  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
10268  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10269  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10270  *          The caller is to delete this array using decrRef() as it is no more needed. 
10271  *  \throw If \a this is not allocated.
10272  *  \throw If \a this->getNumberOfComponents() != 1.
10273  *  \throw If \a this->getNumberOfTuples() < 2.
10274  *
10275  *  \b Example: <br> 
10276  *         - this contains [1,3,6,7,7,9,15]
10277  *         - result array contains [2,3,1,0,2,6],
10278  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10279  *
10280  * \sa DataArrayInt::computeOffsets2
10281  */
10282 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10283 {
10284   checkAllocated();
10285   if(getNumberOfComponents()!=1)
10286     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10287   int nbOfTuples=getNumberOfTuples();
10288   if(nbOfTuples<2)
10289     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10290   const int *ptr=getConstPointer();
10291   DataArrayInt *ret=DataArrayInt::New();
10292   ret->alloc(nbOfTuples-1,1);
10293   int *out=ret->getPointer();
10294   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10295   return ret;
10296 }
10297
10298 /*!
10299  * Modifies \a this one-dimensional array so that value of each element \a x
10300  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10301  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10302  * and components remains the same.<br>
10303  * This method is useful for allToAllV in MPI with contiguous policy. This method
10304  * differs from computeOffsets2() in that the number of tuples is \b not changed by
10305  * this one.
10306  *  \throw If \a this is not allocated.
10307  *  \throw If \a this->getNumberOfComponents() != 1.
10308  *
10309  *  \b Example: <br>
10310  *          - Before \a this contains [3,5,1,2,0,8]
10311  *          - After \a this contains  [0,3,8,9,11,11]<br>
10312  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10313  *          array is retained and thus there is no space to store the last element.
10314  */
10315 void DataArrayInt::computeOffsets()
10316 {
10317   checkAllocated();
10318   if(getNumberOfComponents()!=1)
10319     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10320   int nbOfTuples=getNumberOfTuples();
10321   if(nbOfTuples==0)
10322     return ;
10323   int *work=getPointer();
10324   int tmp=work[0];
10325   work[0]=0;
10326   for(int i=1;i<nbOfTuples;i++)
10327     {
10328       int tmp2=work[i];
10329       work[i]=work[i-1]+tmp;
10330       tmp=tmp2;
10331     }
10332   declareAsNew();
10333 }
10334
10335
10336 /*!
10337  * Modifies \a this one-dimensional array so that value of each element \a x
10338  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10339  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10340  * components remains the same and number of tuples is inceamented by one.<br>
10341  * This method is useful for allToAllV in MPI with contiguous policy. This method
10342  * differs from computeOffsets() in that the number of tuples is changed by this one.
10343  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10344  *  \throw If \a this is not allocated.
10345  *  \throw If \a this->getNumberOfComponents() != 1.
10346  *
10347  *  \b Example: <br>
10348  *          - Before \a this contains [3,5,1,2,0,8]
10349  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10350  * \sa DataArrayInt::deltaShiftIndex
10351  */
10352 void DataArrayInt::computeOffsets2()
10353 {
10354   checkAllocated();
10355   if(getNumberOfComponents()!=1)
10356     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
10357   int nbOfTuples=getNumberOfTuples();
10358   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10359   if(nbOfTuples==0)
10360     return ;
10361   const int *work=getConstPointer();
10362   ret[0]=0;
10363   for(int i=0;i<nbOfTuples;i++)
10364     ret[i+1]=work[i]+ret[i];
10365   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10366   declareAsNew();
10367 }
10368
10369 /*!
10370  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10371  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10372  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10373  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10374  * filling completely one of the ranges in \a this.
10375  *
10376  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10377  * \param [out] rangeIdsFetched the range ids fetched
10378  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10379  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10380  *
10381  * \sa DataArrayInt::computeOffsets2
10382  *
10383  *  \b Example: <br>
10384  *          - \a this : [0,3,7,9,15,18]
10385  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10386  *          - \a rangeIdsFetched result array: [0,2,4]
10387  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10388  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10389  * <br>
10390  */
10391 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10392 {
10393   if(!listOfIds)
10394     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10395   listOfIds->checkAllocated(); checkAllocated();
10396   if(listOfIds->getNumberOfComponents()!=1)
10397     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10398   if(getNumberOfComponents()!=1)
10399     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10400   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10401   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10402   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10403   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10404   while(tupPtr!=tupEnd && offPtr!=offEnd)
10405     {
10406       if(*tupPtr==*offPtr)
10407         {
10408           int i=offPtr[0];
10409           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10410           if(i==offPtr[1])
10411             {
10412               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10413               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10414               offPtr++;
10415             }
10416         }
10417       else
10418         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10419     }
10420   rangeIdsFetched=ret0.retn();
10421   idsInInputListThatFetch=ret1.retn();
10422 }
10423
10424 /*!
10425  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10426  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10427  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10428  * beginning within the "iota" array. And \a this is a one-dimensional array
10429  * considered as a selector of groups described by \a offsets to include into the result array.
10430  *  \throw If \a offsets is NULL.
10431  *  \throw If \a offsets is not allocated.
10432  *  \throw If \a offsets->getNumberOfComponents() != 1.
10433  *  \throw If \a offsets is not monotonically increasing.
10434  *  \throw If \a this is not allocated.
10435  *  \throw If \a this->getNumberOfComponents() != 1.
10436  *  \throw If any element of \a this is not a valid index for \a offsets array.
10437  *
10438  *  \b Example: <br>
10439  *          - \a this: [0,2,3]
10440  *          - \a offsets: [0,3,6,10,14,20]
10441  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10442  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10443  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10444  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10445  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10446  */
10447 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10448 {
10449   if(!offsets)
10450     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10451   checkAllocated();
10452   if(getNumberOfComponents()!=1)
10453     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10454   offsets->checkAllocated();
10455   if(offsets->getNumberOfComponents()!=1)
10456     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10457   int othNbTuples=offsets->getNumberOfTuples()-1;
10458   int nbOfTuples=getNumberOfTuples();
10459   int retNbOftuples=0;
10460   const int *work=getConstPointer();
10461   const int *offPtr=offsets->getConstPointer();
10462   for(int i=0;i<nbOfTuples;i++)
10463     {
10464       int val=work[i];
10465       if(val>=0 && val<othNbTuples)
10466         {
10467           int delta=offPtr[val+1]-offPtr[val];
10468           if(delta>=0)
10469             retNbOftuples+=delta;
10470           else
10471             {
10472               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10473               throw INTERP_KERNEL::Exception(oss.str().c_str());
10474             }
10475         }
10476       else
10477         {
10478           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10479           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10480           throw INTERP_KERNEL::Exception(oss.str().c_str());
10481         }
10482     }
10483   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10484   ret->alloc(retNbOftuples,1);
10485   int *retPtr=ret->getPointer();
10486   for(int i=0;i<nbOfTuples;i++)
10487     {
10488       int val=work[i];
10489       int start=offPtr[val];
10490       int off=offPtr[val+1]-start;
10491       for(int j=0;j<off;j++,retPtr++)
10492         *retPtr=start+j;
10493     }
10494   return ret.retn();
10495 }
10496
10497 /*!
10498  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10499  * scaled array (monotonically increasing).
10500 from that of \a this and \a
10501  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10502  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10503  * beginning within the "iota" array. And \a this is a one-dimensional array
10504  * considered as a selector of groups described by \a offsets to include into the result array.
10505  *  \throw If \a  is NULL.
10506  *  \throw If \a this is not allocated.
10507  *  \throw If \a this->getNumberOfComponents() != 1.
10508  *  \throw If \a this->getNumberOfTuples() == 0.
10509  *  \throw If \a this is not monotonically increasing.
10510  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10511  *
10512  *  \b Example: <br>
10513  *          - \a bg , \a stop and \a step : (0,5,2)
10514  *          - \a this: [0,3,6,10,14,20]
10515  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10516  */
10517 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10518 {
10519   if(!isAllocated())
10520     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10521   if(getNumberOfComponents()!=1)
10522     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10523   int nbOfTuples(getNumberOfTuples());
10524   if(nbOfTuples==0)
10525     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10526   const int *ids(begin());
10527   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10528   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10529     {
10530       if(pos>=0 && pos<nbOfTuples-1)
10531         {
10532           int delta(ids[pos+1]-ids[pos]);
10533           sz+=delta;
10534           if(delta<0)
10535             {
10536               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10537               throw INTERP_KERNEL::Exception(oss.str().c_str());
10538             }          
10539         }
10540       else
10541         {
10542           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10543           throw INTERP_KERNEL::Exception(oss.str().c_str());
10544         }
10545     }
10546   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10547   int *retPtr(ret->getPointer());
10548   pos=bg;
10549   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10550     {
10551       int delta(ids[pos+1]-ids[pos]);
10552       for(int j=0;j<delta;j++,retPtr++)
10553         *retPtr=pos;
10554     }
10555   return ret.retn();
10556 }
10557
10558 /*!
10559  * 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.
10560  * 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
10561  * in tuple **i** of returned DataArrayInt.
10562  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10563  *
10564  * 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)]
10565  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10566  * 
10567  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10568  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10569  * \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
10570  *        is thrown if no ranges in \a ranges contains value in \a this.
10571  * 
10572  * \sa DataArrayInt::findIdInRangeForEachTuple
10573  */
10574 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10575 {
10576   if(!ranges)
10577     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10578   if(ranges->getNumberOfComponents()!=2)
10579     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10580   checkAllocated();
10581   if(getNumberOfComponents()!=1)
10582     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10583   int nbTuples=getNumberOfTuples();
10584   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10585   int nbOfRanges=ranges->getNumberOfTuples();
10586   const int *rangesPtr=ranges->getConstPointer();
10587   int *retPtr=ret->getPointer();
10588   const int *inPtr=getConstPointer();
10589   for(int i=0;i<nbTuples;i++,retPtr++)
10590     {
10591       int val=inPtr[i];
10592       bool found=false;
10593       for(int j=0;j<nbOfRanges && !found;j++)
10594         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10595           { *retPtr=j; found=true; }
10596       if(found)
10597         continue;
10598       else
10599         {
10600           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10601           throw INTERP_KERNEL::Exception(oss.str().c_str());
10602         }
10603     }
10604   return ret.retn();
10605 }
10606
10607 /*!
10608  * 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.
10609  * 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
10610  * in tuple **i** of returned DataArrayInt.
10611  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10612  *
10613  * 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)]
10614  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10615  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10616  * 
10617  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10618  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10619  * \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
10620  *        is thrown if no ranges in \a ranges contains value in \a this.
10621  * \sa DataArrayInt::findRangeIdForEachTuple
10622  */
10623 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10624 {
10625   if(!ranges)
10626     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10627   if(ranges->getNumberOfComponents()!=2)
10628     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10629   checkAllocated();
10630   if(getNumberOfComponents()!=1)
10631     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10632   int nbTuples=getNumberOfTuples();
10633   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10634   int nbOfRanges=ranges->getNumberOfTuples();
10635   const int *rangesPtr=ranges->getConstPointer();
10636   int *retPtr=ret->getPointer();
10637   const int *inPtr=getConstPointer();
10638   for(int i=0;i<nbTuples;i++,retPtr++)
10639     {
10640       int val=inPtr[i];
10641       bool found=false;
10642       for(int j=0;j<nbOfRanges && !found;j++)
10643         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10644           { *retPtr=val-rangesPtr[2*j]; found=true; }
10645       if(found)
10646         continue;
10647       else
10648         {
10649           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10650           throw INTERP_KERNEL::Exception(oss.str().c_str());
10651         }
10652     }
10653   return ret.retn();
10654 }
10655
10656 /*!
10657  * \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).
10658  * 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).
10659  * 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 !
10660  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10661  * This method does nothing if number of tuples is lower of equal to 1.
10662  *
10663  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10664  *
10665  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10666  */
10667 void DataArrayInt::sortEachPairToMakeALinkedList()
10668 {
10669   checkAllocated();
10670   if(getNumberOfComponents()!=2)
10671     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10672   int nbOfTuples(getNumberOfTuples());
10673   if(nbOfTuples<=1)
10674     return ;
10675   int *conn(getPointer());
10676   for(int i=1;i<nbOfTuples;i++,conn+=2)
10677     {
10678       if(i>1)
10679         {
10680           if(conn[2]==conn[3])
10681             {
10682               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10683               throw INTERP_KERNEL::Exception(oss.str().c_str());
10684             }
10685           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10686             std::swap(conn[2],conn[3]);
10687           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10688           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10689             {
10690               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10691               throw INTERP_KERNEL::Exception(oss.str().c_str());
10692             }
10693         }
10694       else
10695         {
10696           if(conn[0]==conn[1] || conn[2]==conn[3])
10697             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10698           int tmp[4];
10699           std::set<int> s;
10700           s.insert(conn,conn+4);
10701           if(s.size()!=3)
10702             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10703           if(std::count(conn,conn+4,conn[0])==2)
10704             {
10705               tmp[0]=conn[1];
10706               tmp[1]=conn[0];
10707               tmp[2]=conn[0];
10708               if(conn[2]==conn[0])
10709                 { tmp[3]=conn[3]; }
10710               else
10711                 { tmp[3]=conn[2];}
10712               std::copy(tmp,tmp+4,conn);
10713             }
10714         }
10715     }
10716 }
10717
10718 /*!
10719  * 
10720  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10721  *             \a nbTimes  should be at least equal to 1.
10722  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10723  * \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.
10724  */
10725 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10726 {
10727   checkAllocated();
10728   if(getNumberOfComponents()!=1)
10729     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10730   if(nbTimes<1)
10731     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10732   int nbTuples=getNumberOfTuples();
10733   const int *inPtr=getConstPointer();
10734   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10735   int *retPtr=ret->getPointer();
10736   for(int i=0;i<nbTuples;i++,inPtr++)
10737     {
10738       int val=*inPtr;
10739       for(int j=0;j<nbTimes;j++,retPtr++)
10740         *retPtr=val;
10741     }
10742   ret->copyStringInfoFrom(*this);
10743   return ret.retn();
10744 }
10745
10746 /*!
10747  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10748  * But the number of components can be different from one.
10749  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10750  */
10751 DataArrayInt *DataArrayInt::getDifferentValues() const
10752 {
10753   checkAllocated();
10754   std::set<int> ret;
10755   ret.insert(begin(),end());
10756   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10757   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10758   return ret2.retn();
10759 }
10760
10761 /*!
10762  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10763  * them it tells which tuple id have this id.
10764  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10765  * This method returns two arrays having same size.
10766  * 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.
10767  * 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]]
10768  */
10769 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10770 {
10771   checkAllocated();
10772   if(getNumberOfComponents()!=1)
10773     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10774   int id=0;
10775   std::map<int,int> m,m2,m3;
10776   for(const int *w=begin();w!=end();w++)
10777     m[*w]++;
10778   differentIds.resize(m.size());
10779   std::vector<DataArrayInt *> ret(m.size());
10780   std::vector<int *> retPtr(m.size());
10781   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10782     {
10783       m2[(*it).first]=id;
10784       ret[id]=DataArrayInt::New();
10785       ret[id]->alloc((*it).second,1);
10786       retPtr[id]=ret[id]->getPointer();
10787       differentIds[id]=(*it).first;
10788     }
10789   id=0;
10790   for(const int *w=begin();w!=end();w++,id++)
10791     {
10792       retPtr[m2[*w]][m3[*w]++]=id;
10793     }
10794   return ret;
10795 }
10796
10797 /*!
10798  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10799  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10800  *
10801  * \param [in] nbOfSlices - number of slices expected.
10802  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10803  * 
10804  * \sa DataArray::GetSlice
10805  * \throw If \a this is not allocated or not with exactly one component.
10806  * \throw If an element in \a this if < 0.
10807  */
10808 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10809 {
10810   if(!isAllocated() || getNumberOfComponents()!=1)
10811     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10812   if(nbOfSlices<=0)
10813     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10814   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10815   int sumPerSlc(sum/nbOfSlices),pos(0);
10816   const int *w(begin());
10817   std::vector< std::pair<int,int> > ret(nbOfSlices);
10818   for(int i=0;i<nbOfSlices;i++)
10819     {
10820       std::pair<int,int> p(pos,-1);
10821       int locSum(0);
10822       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10823       if(i!=nbOfSlices-1)
10824         p.second=pos;
10825       else
10826         p.second=nbOfTuples;
10827       ret[i]=p;
10828     }
10829   return ret;
10830 }
10831
10832 /*!
10833  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10834  * valid cases.
10835  * 1.  The arrays have same number of tuples and components. Then each value of
10836  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10837  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10838  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10839  *   component. Then
10840  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10841  * 3.  The arrays have same number of components and one array, say _a2_, has one
10842  *   tuple. Then
10843  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10844  *
10845  * Info on components is copied either from the first array (in the first case) or from
10846  * the array with maximal number of elements (getNbOfElems()).
10847  *  \param [in] a1 - an array to sum up.
10848  *  \param [in] a2 - another array to sum up.
10849  *  \return DataArrayInt * - the new instance of DataArrayInt.
10850  *          The caller is to delete this result array using decrRef() as it is no more
10851  *          needed.
10852  *  \throw If either \a a1 or \a a2 is NULL.
10853  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10854  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10855  *         none of them has number of tuples or components equal to 1.
10856  */
10857 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10858 {
10859   if(!a1 || !a2)
10860     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10861   int nbOfTuple=a1->getNumberOfTuples();
10862   int nbOfTuple2=a2->getNumberOfTuples();
10863   int nbOfComp=a1->getNumberOfComponents();
10864   int nbOfComp2=a2->getNumberOfComponents();
10865   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10866   if(nbOfTuple==nbOfTuple2)
10867     {
10868       if(nbOfComp==nbOfComp2)
10869         {
10870           ret=DataArrayInt::New();
10871           ret->alloc(nbOfTuple,nbOfComp);
10872           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10873           ret->copyStringInfoFrom(*a1);
10874         }
10875       else
10876         {
10877           int nbOfCompMin,nbOfCompMax;
10878           const DataArrayInt *aMin, *aMax;
10879           if(nbOfComp>nbOfComp2)
10880             {
10881               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10882               aMin=a2; aMax=a1;
10883             }
10884           else
10885             {
10886               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10887               aMin=a1; aMax=a2;
10888             }
10889           if(nbOfCompMin==1)
10890             {
10891               ret=DataArrayInt::New();
10892               ret->alloc(nbOfTuple,nbOfCompMax);
10893               const int *aMinPtr=aMin->getConstPointer();
10894               const int *aMaxPtr=aMax->getConstPointer();
10895               int *res=ret->getPointer();
10896               for(int i=0;i<nbOfTuple;i++)
10897                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10898               ret->copyStringInfoFrom(*aMax);
10899             }
10900           else
10901             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10902         }
10903     }
10904   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10905     {
10906       if(nbOfComp==nbOfComp2)
10907         {
10908           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10909           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10910           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10911           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10912           ret=DataArrayInt::New();
10913           ret->alloc(nbOfTupleMax,nbOfComp);
10914           int *res=ret->getPointer();
10915           for(int i=0;i<nbOfTupleMax;i++)
10916             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10917           ret->copyStringInfoFrom(*aMax);
10918         }
10919       else
10920         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10921     }
10922   else
10923     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10924   return ret.retn();
10925 }
10926
10927 /*!
10928  * Adds values of another DataArrayInt to values of \a this one. There are 3
10929  * valid cases.
10930  * 1.  The arrays have same number of tuples and components. Then each value of
10931  *   \a other array is added to the corresponding value of \a this array, i.e.:
10932  *   _a_ [ i, j ] += _other_ [ i, j ].
10933  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10934  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10935  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10936  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10937  *
10938  *  \param [in] other - an array to add to \a this one.
10939  *  \throw If \a other is NULL.
10940  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10941  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10942  *         \a other has number of both tuples and components not equal to 1.
10943  */
10944 void DataArrayInt::addEqual(const DataArrayInt *other)
10945 {
10946   if(!other)
10947     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10948   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10949   checkAllocated(); other->checkAllocated();
10950   int nbOfTuple=getNumberOfTuples();
10951   int nbOfTuple2=other->getNumberOfTuples();
10952   int nbOfComp=getNumberOfComponents();
10953   int nbOfComp2=other->getNumberOfComponents();
10954   if(nbOfTuple==nbOfTuple2)
10955     {
10956       if(nbOfComp==nbOfComp2)
10957         {
10958           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10959         }
10960       else if(nbOfComp2==1)
10961         {
10962           int *ptr=getPointer();
10963           const int *ptrc=other->getConstPointer();
10964           for(int i=0;i<nbOfTuple;i++)
10965             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10966         }
10967       else
10968         throw INTERP_KERNEL::Exception(msg);
10969     }
10970   else if(nbOfTuple2==1)
10971     {
10972       if(nbOfComp2==nbOfComp)
10973         {
10974           int *ptr=getPointer();
10975           const int *ptrc=other->getConstPointer();
10976           for(int i=0;i<nbOfTuple;i++)
10977             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10978         }
10979       else
10980         throw INTERP_KERNEL::Exception(msg);
10981     }
10982   else
10983     throw INTERP_KERNEL::Exception(msg);
10984   declareAsNew();
10985 }
10986
10987 /*!
10988  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10989  * valid cases.
10990  * 1.  The arrays have same number of tuples and components. Then each value of
10991  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10992  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10993  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10994  *   component. Then
10995  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10996  * 3.  The arrays have same number of components and one array, say _a2_, has one
10997  *   tuple. Then
10998  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10999  *
11000  * Info on components is copied either from the first array (in the first case) or from
11001  * the array with maximal number of elements (getNbOfElems()).
11002  *  \param [in] a1 - an array to subtract from.
11003  *  \param [in] a2 - an array to subtract.
11004  *  \return DataArrayInt * - the new instance of DataArrayInt.
11005  *          The caller is to delete this result array using decrRef() as it is no more
11006  *          needed.
11007  *  \throw If either \a a1 or \a a2 is NULL.
11008  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11009  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11010  *         none of them has number of tuples or components equal to 1.
11011  */
11012 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
11013 {
11014   if(!a1 || !a2)
11015     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
11016   int nbOfTuple1=a1->getNumberOfTuples();
11017   int nbOfTuple2=a2->getNumberOfTuples();
11018   int nbOfComp1=a1->getNumberOfComponents();
11019   int nbOfComp2=a2->getNumberOfComponents();
11020   if(nbOfTuple2==nbOfTuple1)
11021     {
11022       if(nbOfComp1==nbOfComp2)
11023         {
11024           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11025           ret->alloc(nbOfTuple2,nbOfComp1);
11026           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
11027           ret->copyStringInfoFrom(*a1);
11028           return ret.retn();
11029         }
11030       else if(nbOfComp2==1)
11031         {
11032           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11033           ret->alloc(nbOfTuple1,nbOfComp1);
11034           const int *a2Ptr=a2->getConstPointer();
11035           const int *a1Ptr=a1->getConstPointer();
11036           int *res=ret->getPointer();
11037           for(int i=0;i<nbOfTuple1;i++)
11038             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
11039           ret->copyStringInfoFrom(*a1);
11040           return ret.retn();
11041         }
11042       else
11043         {
11044           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11045           return 0;
11046         }
11047     }
11048   else if(nbOfTuple2==1)
11049     {
11050       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11051       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11052       ret->alloc(nbOfTuple1,nbOfComp1);
11053       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11054       int *pt=ret->getPointer();
11055       for(int i=0;i<nbOfTuple1;i++)
11056         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
11057       ret->copyStringInfoFrom(*a1);
11058       return ret.retn();
11059     }
11060   else
11061     {
11062       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
11063       return 0;
11064     }
11065 }
11066
11067 /*!
11068  * Subtract values of another DataArrayInt from values of \a this one. There are 3
11069  * valid cases.
11070  * 1.  The arrays have same number of tuples and components. Then each value of
11071  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
11072  *   _a_ [ i, j ] -= _other_ [ i, j ].
11073  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11074  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
11075  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11076  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
11077  *
11078  *  \param [in] other - an array to subtract from \a this one.
11079  *  \throw If \a other is NULL.
11080  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11081  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11082  *         \a other has number of both tuples and components not equal to 1.
11083  */
11084 void DataArrayInt::substractEqual(const DataArrayInt *other)
11085 {
11086   if(!other)
11087     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
11088   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
11089   checkAllocated(); other->checkAllocated();
11090   int nbOfTuple=getNumberOfTuples();
11091   int nbOfTuple2=other->getNumberOfTuples();
11092   int nbOfComp=getNumberOfComponents();
11093   int nbOfComp2=other->getNumberOfComponents();
11094   if(nbOfTuple==nbOfTuple2)
11095     {
11096       if(nbOfComp==nbOfComp2)
11097         {
11098           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
11099         }
11100       else if(nbOfComp2==1)
11101         {
11102           int *ptr=getPointer();
11103           const int *ptrc=other->getConstPointer();
11104           for(int i=0;i<nbOfTuple;i++)
11105             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11106         }
11107       else
11108         throw INTERP_KERNEL::Exception(msg);
11109     }
11110   else if(nbOfTuple2==1)
11111     {
11112       int *ptr=getPointer();
11113       const int *ptrc=other->getConstPointer();
11114       for(int i=0;i<nbOfTuple;i++)
11115         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11116     }
11117   else
11118     throw INTERP_KERNEL::Exception(msg);
11119   declareAsNew();
11120 }
11121
11122 /*!
11123  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11124  * valid cases.
11125  * 1.  The arrays have same number of tuples and components. Then each value of
11126  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11127  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11128  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11129  *   component. Then
11130  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11131  * 3.  The arrays have same number of components and one array, say _a2_, has one
11132  *   tuple. Then
11133  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11134  *
11135  * Info on components is copied either from the first array (in the first case) or from
11136  * the array with maximal number of elements (getNbOfElems()).
11137  *  \param [in] a1 - a factor array.
11138  *  \param [in] a2 - another factor array.
11139  *  \return DataArrayInt * - the new instance of DataArrayInt.
11140  *          The caller is to delete this result array using decrRef() as it is no more
11141  *          needed.
11142  *  \throw If either \a a1 or \a a2 is NULL.
11143  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11144  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11145  *         none of them has number of tuples or components equal to 1.
11146  */
11147 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11148 {
11149   if(!a1 || !a2)
11150     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11151   int nbOfTuple=a1->getNumberOfTuples();
11152   int nbOfTuple2=a2->getNumberOfTuples();
11153   int nbOfComp=a1->getNumberOfComponents();
11154   int nbOfComp2=a2->getNumberOfComponents();
11155   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
11156   if(nbOfTuple==nbOfTuple2)
11157     {
11158       if(nbOfComp==nbOfComp2)
11159         {
11160           ret=DataArrayInt::New();
11161           ret->alloc(nbOfTuple,nbOfComp);
11162           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11163           ret->copyStringInfoFrom(*a1);
11164         }
11165       else
11166         {
11167           int nbOfCompMin,nbOfCompMax;
11168           const DataArrayInt *aMin, *aMax;
11169           if(nbOfComp>nbOfComp2)
11170             {
11171               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11172               aMin=a2; aMax=a1;
11173             }
11174           else
11175             {
11176               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11177               aMin=a1; aMax=a2;
11178             }
11179           if(nbOfCompMin==1)
11180             {
11181               ret=DataArrayInt::New();
11182               ret->alloc(nbOfTuple,nbOfCompMax);
11183               const int *aMinPtr=aMin->getConstPointer();
11184               const int *aMaxPtr=aMax->getConstPointer();
11185               int *res=ret->getPointer();
11186               for(int i=0;i<nbOfTuple;i++)
11187                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11188               ret->copyStringInfoFrom(*aMax);
11189             }
11190           else
11191             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11192         }
11193     }
11194   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11195     {
11196       if(nbOfComp==nbOfComp2)
11197         {
11198           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11199           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11200           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11201           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11202           ret=DataArrayInt::New();
11203           ret->alloc(nbOfTupleMax,nbOfComp);
11204           int *res=ret->getPointer();
11205           for(int i=0;i<nbOfTupleMax;i++)
11206             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11207           ret->copyStringInfoFrom(*aMax);
11208         }
11209       else
11210         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11211     }
11212   else
11213     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11214   return ret.retn();
11215 }
11216
11217
11218 /*!
11219  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11220  * valid cases.
11221  * 1.  The arrays have same number of tuples and components. Then each value of
11222  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11223  *   _a_ [ i, j ] *= _other_ [ i, j ].
11224  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11225  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11226  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11227  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11228  *
11229  *  \param [in] other - an array to multiply to \a this one.
11230  *  \throw If \a other is NULL.
11231  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11232  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11233  *         \a other has number of both tuples and components not equal to 1.
11234  */
11235 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11236 {
11237   if(!other)
11238     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11239   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11240   checkAllocated(); other->checkAllocated();
11241   int nbOfTuple=getNumberOfTuples();
11242   int nbOfTuple2=other->getNumberOfTuples();
11243   int nbOfComp=getNumberOfComponents();
11244   int nbOfComp2=other->getNumberOfComponents();
11245   if(nbOfTuple==nbOfTuple2)
11246     {
11247       if(nbOfComp==nbOfComp2)
11248         {
11249           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11250         }
11251       else if(nbOfComp2==1)
11252         {
11253           int *ptr=getPointer();
11254           const int *ptrc=other->getConstPointer();
11255           for(int i=0;i<nbOfTuple;i++)
11256             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11257         }
11258       else
11259         throw INTERP_KERNEL::Exception(msg);
11260     }
11261   else if(nbOfTuple2==1)
11262     {
11263       if(nbOfComp2==nbOfComp)
11264         {
11265           int *ptr=getPointer();
11266           const int *ptrc=other->getConstPointer();
11267           for(int i=0;i<nbOfTuple;i++)
11268             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11269         }
11270       else
11271         throw INTERP_KERNEL::Exception(msg);
11272     }
11273   else
11274     throw INTERP_KERNEL::Exception(msg);
11275   declareAsNew();
11276 }
11277
11278
11279 /*!
11280  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11281  * valid cases.
11282  * 1.  The arrays have same number of tuples and components. Then each value of
11283  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11284  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11285  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11286  *   component. Then
11287  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11288  * 3.  The arrays have same number of components and one array, say _a2_, has one
11289  *   tuple. Then
11290  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11291  *
11292  * Info on components is copied either from the first array (in the first case) or from
11293  * the array with maximal number of elements (getNbOfElems()).
11294  *  \warning No check of division by zero is performed!
11295  *  \param [in] a1 - a numerator array.
11296  *  \param [in] a2 - a denominator array.
11297  *  \return DataArrayInt * - the new instance of DataArrayInt.
11298  *          The caller is to delete this result array using decrRef() as it is no more
11299  *          needed.
11300  *  \throw If either \a a1 or \a a2 is NULL.
11301  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11302  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11303  *         none of them has number of tuples or components equal to 1.
11304  */
11305 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11306 {
11307   if(!a1 || !a2)
11308     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11309   int nbOfTuple1=a1->getNumberOfTuples();
11310   int nbOfTuple2=a2->getNumberOfTuples();
11311   int nbOfComp1=a1->getNumberOfComponents();
11312   int nbOfComp2=a2->getNumberOfComponents();
11313   if(nbOfTuple2==nbOfTuple1)
11314     {
11315       if(nbOfComp1==nbOfComp2)
11316         {
11317           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11318           ret->alloc(nbOfTuple2,nbOfComp1);
11319           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11320           ret->copyStringInfoFrom(*a1);
11321           return ret.retn();
11322         }
11323       else if(nbOfComp2==1)
11324         {
11325           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11326           ret->alloc(nbOfTuple1,nbOfComp1);
11327           const int *a2Ptr=a2->getConstPointer();
11328           const int *a1Ptr=a1->getConstPointer();
11329           int *res=ret->getPointer();
11330           for(int i=0;i<nbOfTuple1;i++)
11331             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11332           ret->copyStringInfoFrom(*a1);
11333           return ret.retn();
11334         }
11335       else
11336         {
11337           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11338           return 0;
11339         }
11340     }
11341   else if(nbOfTuple2==1)
11342     {
11343       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11344       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11345       ret->alloc(nbOfTuple1,nbOfComp1);
11346       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11347       int *pt=ret->getPointer();
11348       for(int i=0;i<nbOfTuple1;i++)
11349         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11350       ret->copyStringInfoFrom(*a1);
11351       return ret.retn();
11352     }
11353   else
11354     {
11355       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11356       return 0;
11357     }
11358 }
11359
11360 /*!
11361  * Divide values of \a this array by values of another DataArrayInt. There are 3
11362  * valid cases.
11363  * 1.  The arrays have same number of tuples and components. Then each value of
11364  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11365  *   _a_ [ i, j ] /= _other_ [ i, j ].
11366  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11367  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11368  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11369  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11370  *
11371  *  \warning No check of division by zero is performed!
11372  *  \param [in] other - an array to divide \a this one by.
11373  *  \throw If \a other is NULL.
11374  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11375  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11376  *         \a other has number of both tuples and components not equal to 1.
11377  */
11378 void DataArrayInt::divideEqual(const DataArrayInt *other)
11379 {
11380   if(!other)
11381     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11382   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11383   checkAllocated(); other->checkAllocated();
11384   int nbOfTuple=getNumberOfTuples();
11385   int nbOfTuple2=other->getNumberOfTuples();
11386   int nbOfComp=getNumberOfComponents();
11387   int nbOfComp2=other->getNumberOfComponents();
11388   if(nbOfTuple==nbOfTuple2)
11389     {
11390       if(nbOfComp==nbOfComp2)
11391         {
11392           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11393         }
11394       else if(nbOfComp2==1)
11395         {
11396           int *ptr=getPointer();
11397           const int *ptrc=other->getConstPointer();
11398           for(int i=0;i<nbOfTuple;i++)
11399             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11400         }
11401       else
11402         throw INTERP_KERNEL::Exception(msg);
11403     }
11404   else if(nbOfTuple2==1)
11405     {
11406       if(nbOfComp2==nbOfComp)
11407         {
11408           int *ptr=getPointer();
11409           const int *ptrc=other->getConstPointer();
11410           for(int i=0;i<nbOfTuple;i++)
11411             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11412         }
11413       else
11414         throw INTERP_KERNEL::Exception(msg);
11415     }
11416   else
11417     throw INTERP_KERNEL::Exception(msg);
11418   declareAsNew();
11419 }
11420
11421
11422 /*!
11423  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11424  * valid cases.
11425  * 1.  The arrays have same number of tuples and components. Then each value of
11426  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11427  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11428  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11429  *   component. Then
11430  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11431  * 3.  The arrays have same number of components and one array, say _a2_, has one
11432  *   tuple. Then
11433  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11434  *
11435  * Info on components is copied either from the first array (in the first case) or from
11436  * the array with maximal number of elements (getNbOfElems()).
11437  *  \warning No check of division by zero is performed!
11438  *  \param [in] a1 - a dividend array.
11439  *  \param [in] a2 - a divisor array.
11440  *  \return DataArrayInt * - the new instance of DataArrayInt.
11441  *          The caller is to delete this result array using decrRef() as it is no more
11442  *          needed.
11443  *  \throw If either \a a1 or \a a2 is NULL.
11444  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11445  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11446  *         none of them has number of tuples or components equal to 1.
11447  */
11448 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11449 {
11450   if(!a1 || !a2)
11451     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11452   int nbOfTuple1=a1->getNumberOfTuples();
11453   int nbOfTuple2=a2->getNumberOfTuples();
11454   int nbOfComp1=a1->getNumberOfComponents();
11455   int nbOfComp2=a2->getNumberOfComponents();
11456   if(nbOfTuple2==nbOfTuple1)
11457     {
11458       if(nbOfComp1==nbOfComp2)
11459         {
11460           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11461           ret->alloc(nbOfTuple2,nbOfComp1);
11462           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11463           ret->copyStringInfoFrom(*a1);
11464           return ret.retn();
11465         }
11466       else if(nbOfComp2==1)
11467         {
11468           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11469           ret->alloc(nbOfTuple1,nbOfComp1);
11470           const int *a2Ptr=a2->getConstPointer();
11471           const int *a1Ptr=a1->getConstPointer();
11472           int *res=ret->getPointer();
11473           for(int i=0;i<nbOfTuple1;i++)
11474             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11475           ret->copyStringInfoFrom(*a1);
11476           return ret.retn();
11477         }
11478       else
11479         {
11480           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11481           return 0;
11482         }
11483     }
11484   else if(nbOfTuple2==1)
11485     {
11486       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11487       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11488       ret->alloc(nbOfTuple1,nbOfComp1);
11489       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11490       int *pt=ret->getPointer();
11491       for(int i=0;i<nbOfTuple1;i++)
11492         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11493       ret->copyStringInfoFrom(*a1);
11494       return ret.retn();
11495     }
11496   else
11497     {
11498       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11499       return 0;
11500     }
11501 }
11502
11503 /*!
11504  * Modify \a this array so that each value becomes a modulus of division of this value by
11505  * a value of another DataArrayInt. There are 3 valid cases.
11506  * 1.  The arrays have same number of tuples and components. Then each value of
11507  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11508  *   _a_ [ i, j ] %= _other_ [ i, j ].
11509  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11510  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11511  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11512  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11513  *
11514  *  \warning No check of division by zero is performed!
11515  *  \param [in] other - a divisor array.
11516  *  \throw If \a other is NULL.
11517  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11518  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11519  *         \a other has number of both tuples and components not equal to 1.
11520  */
11521 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11522 {
11523   if(!other)
11524     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11525   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11526   checkAllocated(); other->checkAllocated();
11527   int nbOfTuple=getNumberOfTuples();
11528   int nbOfTuple2=other->getNumberOfTuples();
11529   int nbOfComp=getNumberOfComponents();
11530   int nbOfComp2=other->getNumberOfComponents();
11531   if(nbOfTuple==nbOfTuple2)
11532     {
11533       if(nbOfComp==nbOfComp2)
11534         {
11535           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11536         }
11537       else if(nbOfComp2==1)
11538         {
11539           if(nbOfComp2==nbOfComp)
11540             {
11541               int *ptr=getPointer();
11542               const int *ptrc=other->getConstPointer();
11543               for(int i=0;i<nbOfTuple;i++)
11544                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11545             }
11546           else
11547             throw INTERP_KERNEL::Exception(msg);
11548         }
11549       else
11550         throw INTERP_KERNEL::Exception(msg);
11551     }
11552   else if(nbOfTuple2==1)
11553     {
11554       int *ptr=getPointer();
11555       const int *ptrc=other->getConstPointer();
11556       for(int i=0;i<nbOfTuple;i++)
11557         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11558     }
11559   else
11560     throw INTERP_KERNEL::Exception(msg);
11561   declareAsNew();
11562 }
11563
11564 /*!
11565  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11566  * valid cases.
11567  *
11568  *  \param [in] a1 - an array to pow up.
11569  *  \param [in] a2 - another array to sum up.
11570  *  \return DataArrayInt * - the new instance of DataArrayInt.
11571  *          The caller is to delete this result array using decrRef() as it is no more
11572  *          needed.
11573  *  \throw If either \a a1 or \a a2 is NULL.
11574  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11575  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11576  *  \throw If there is a negative value in \a a2.
11577  */
11578 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11579 {
11580   if(!a1 || !a2)
11581     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11582   int nbOfTuple=a1->getNumberOfTuples();
11583   int nbOfTuple2=a2->getNumberOfTuples();
11584   int nbOfComp=a1->getNumberOfComponents();
11585   int nbOfComp2=a2->getNumberOfComponents();
11586   if(nbOfTuple!=nbOfTuple2)
11587     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11588   if(nbOfComp!=1 || nbOfComp2!=1)
11589     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11590   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11591   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11592   int *ptr=ret->getPointer();
11593   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11594     {
11595       if(*ptr2>=0)
11596         {
11597           int tmp=1;
11598           for(int j=0;j<*ptr2;j++)
11599             tmp*=*ptr1;
11600           *ptr=tmp;
11601         }
11602       else
11603         {
11604           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11605           throw INTERP_KERNEL::Exception(oss.str().c_str());
11606         }
11607     }
11608   return ret.retn();
11609 }
11610
11611 /*!
11612  * Apply pow on values of another DataArrayInt to values of \a this one.
11613  *
11614  *  \param [in] other - an array to pow to \a this one.
11615  *  \throw If \a other is NULL.
11616  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11617  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11618  *  \throw If there is a negative value in \a other.
11619  */
11620 void DataArrayInt::powEqual(const DataArrayInt *other)
11621 {
11622   if(!other)
11623     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11624   int nbOfTuple=getNumberOfTuples();
11625   int nbOfTuple2=other->getNumberOfTuples();
11626   int nbOfComp=getNumberOfComponents();
11627   int nbOfComp2=other->getNumberOfComponents();
11628   if(nbOfTuple!=nbOfTuple2)
11629     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11630   if(nbOfComp!=1 || nbOfComp2!=1)
11631     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11632   int *ptr=getPointer();
11633   const int *ptrc=other->begin();
11634   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11635     {
11636       if(*ptrc>=0)
11637         {
11638           int tmp=1;
11639           for(int j=0;j<*ptrc;j++)
11640             tmp*=*ptr;
11641           *ptr=tmp;
11642         }
11643       else
11644         {
11645           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11646           throw INTERP_KERNEL::Exception(oss.str().c_str());
11647         }
11648     }
11649   declareAsNew();
11650 }
11651
11652 /*!
11653  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11654  * This map, if applied to \a start array, would make it sorted. For example, if
11655  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11656  * [5,6,0,3,2,7,1,4].
11657  *  \param [in] start - pointer to the first element of the array for which the
11658  *         permutation map is computed.
11659  *  \param [in] end - pointer specifying the end of the array \a start, so that
11660  *         the last value of \a start is \a end[ -1 ].
11661  *  \return int * - the result permutation array that the caller is to delete as it is no
11662  *         more needed.
11663  *  \throw If there are equal values in the input array.
11664  */
11665 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11666 {
11667   std::size_t sz=std::distance(start,end);
11668   int *ret=(int *)malloc(sz*sizeof(int));
11669   int *work=new int[sz];
11670   std::copy(start,end,work);
11671   std::sort(work,work+sz);
11672   if(std::unique(work,work+sz)!=work+sz)
11673     {
11674       delete [] work;
11675       free(ret);
11676       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11677     }
11678   std::map<int,int> m;
11679   for(int *workPt=work;workPt!=work+sz;workPt++)
11680     m[*workPt]=(int)std::distance(work,workPt);
11681   int *iter2=ret;
11682   for(const int *iter=start;iter!=end;iter++,iter2++)
11683     *iter2=m[*iter];
11684   delete [] work;
11685   return ret;
11686 }
11687
11688 /*!
11689  * Returns a new DataArrayInt containing an arithmetic progression
11690  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11691  * function.
11692  *  \param [in] begin - the start value of the result sequence.
11693  *  \param [in] end - limiting value, so that every value of the result array is less than
11694  *              \a end.
11695  *  \param [in] step - specifies the increment or decrement.
11696  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11697  *          array using decrRef() as it is no more needed.
11698  *  \throw If \a step == 0.
11699  *  \throw If \a end < \a begin && \a step > 0.
11700  *  \throw If \a end > \a begin && \a step < 0.
11701  */
11702 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11703 {
11704   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11705   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11706   ret->alloc(nbOfTuples,1);
11707   int *ptr=ret->getPointer();
11708   if(step>0)
11709     {
11710       for(int i=begin;i<end;i+=step,ptr++)
11711         *ptr=i;
11712     }
11713   else
11714     {
11715       for(int i=begin;i>end;i+=step,ptr++)
11716         *ptr=i;
11717     }
11718   return ret.retn();
11719 }
11720
11721 /*!
11722  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11723  * Server side.
11724  */
11725 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11726 {
11727   tinyInfo.resize(2);
11728   if(isAllocated())
11729     {
11730       tinyInfo[0]=getNumberOfTuples();
11731       tinyInfo[1]=getNumberOfComponents();
11732     }
11733   else
11734     {
11735       tinyInfo[0]=-1;
11736       tinyInfo[1]=-1;
11737     }
11738 }
11739
11740 /*!
11741  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11742  * Server side.
11743  */
11744 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11745 {
11746   if(isAllocated())
11747     {
11748       int nbOfCompo=getNumberOfComponents();
11749       tinyInfo.resize(nbOfCompo+1);
11750       tinyInfo[0]=getName();
11751       for(int i=0;i<nbOfCompo;i++)
11752         tinyInfo[i+1]=getInfoOnComponent(i);
11753     }
11754   else
11755     {
11756       tinyInfo.resize(1);
11757       tinyInfo[0]=getName();
11758     }
11759 }
11760
11761 /*!
11762  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11763  * This method returns if a feeding is needed.
11764  */
11765 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11766 {
11767   int nbOfTuple=tinyInfoI[0];
11768   int nbOfComp=tinyInfoI[1];
11769   if(nbOfTuple!=-1 || nbOfComp!=-1)
11770     {
11771       alloc(nbOfTuple,nbOfComp);
11772       return true;
11773     }
11774   return false;
11775 }
11776
11777 /*!
11778  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11779  * This method returns if a feeding is needed.
11780  */
11781 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11782 {
11783   setName(tinyInfoS[0]);
11784   if(isAllocated())
11785     {
11786       int nbOfCompo=tinyInfoI[1];
11787       for(int i=0;i<nbOfCompo;i++)
11788         setInfoOnComponent(i,tinyInfoS[i+1]);
11789     }
11790 }
11791
11792 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11793 {
11794   if(_da)
11795     {
11796       _da->incrRef();
11797       if(_da->isAllocated())
11798         {
11799           _nb_comp=da->getNumberOfComponents();
11800           _nb_tuple=da->getNumberOfTuples();
11801           _pt=da->getPointer();
11802         }
11803     }
11804 }
11805
11806 DataArrayIntIterator::~DataArrayIntIterator()
11807 {
11808   if(_da)
11809     _da->decrRef();
11810 }
11811
11812 DataArrayIntTuple *DataArrayIntIterator::nextt()
11813 {
11814   if(_tuple_id<_nb_tuple)
11815     {
11816       _tuple_id++;
11817       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11818       _pt+=_nb_comp;
11819       return ret;
11820     }
11821   else
11822     return 0;
11823 }
11824
11825 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11826 {
11827 }
11828
11829 std::string DataArrayIntTuple::repr() const
11830 {
11831   std::ostringstream oss; oss << "(";
11832   for(int i=0;i<_nb_of_compo-1;i++)
11833     oss << _pt[i] << ", ";
11834   oss << _pt[_nb_of_compo-1] << ")";
11835   return oss.str();
11836 }
11837
11838 int DataArrayIntTuple::intValue() const
11839 {
11840   if(_nb_of_compo==1)
11841     return *_pt;
11842   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11843 }
11844
11845 /*!
11846  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11847  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11848  * 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
11849  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11850  */
11851 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11852 {
11853   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11854     {
11855       DataArrayInt *ret=DataArrayInt::New();
11856       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11857       return ret;
11858     }
11859   else
11860     {
11861       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11862       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11863       throw INTERP_KERNEL::Exception(oss.str().c_str());
11864     }
11865 }