Salome HOME
More check in MEDCouplingRemapper to help aggressive users of transferField, transfer...
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildren() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const std::string& name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const std::string& varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * This method put in info format the result of the merge of \a var and \a unit.
427  * The standard format for that is "var [unit]".
428  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
429  */
430 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
431 {
432   std::ostringstream oss;
433   oss << var << " [" << unit << "]";
434   return oss.str();
435 }
436
437 /*!
438  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
439  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
440  * the number of component in the result array is same as that of each of given arrays.
441  * Info on components is copied from the first of the given arrays. Number of components
442  * in the given arrays must be  the same.
443  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
444  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
445  *          The caller is to delete this result array using decrRef() as it is no more
446  *          needed.
447  *  \throw If all arrays within \a arrs are NULL.
448  *  \throw If all not null arrays in \a arrs have not the same type.
449  *  \throw If getNumberOfComponents() of arrays within \a arrs.
450  */
451 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
452 {
453   std::vector<const DataArray *> arr2;
454   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
455     if(*it)
456       arr2.push_back(*it);
457   if(arr2.empty())
458     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
459   std::vector<const DataArrayDouble *> arrd;
460   std::vector<const DataArrayInt *> arri;
461   std::vector<const DataArrayChar *> arrc;
462   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
463     {
464       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
465       if(a)
466         { arrd.push_back(a); continue; }
467       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
468       if(b)
469         { arri.push_back(b); continue; }
470       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
471       if(c)
472         { arrc.push_back(c); continue; }
473       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
474     }
475   if(arr2.size()==arrd.size())
476     return DataArrayDouble::Aggregate(arrd);
477   if(arr2.size()==arri.size())
478     return DataArrayInt::Aggregate(arri);
479   if(arr2.size()==arrc.size())
480     return DataArrayChar::Aggregate(arrc);
481   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
482 }
483
484 /*!
485  * Sets information on a component specified by an index.
486  * To know more on format of this information
487  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
488  *  \warning Don't pass NULL as \a info!
489  *  \param [in] i - the index (zero based) of the component of interest.
490  *  \param [in] info - the string containing the information.
491  *  \throw If \a i is not a valid component index.
492  */
493 void DataArray::setInfoOnComponent(int i, const std::string& info)
494 {
495   if(i<(int)_info_on_compo.size() && i>=0)
496     _info_on_compo[i]=info;
497   else
498     {
499       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
500       throw INTERP_KERNEL::Exception(oss.str().c_str());
501     }
502 }
503
504 /*!
505  * Sets information on all components. This method can change number of components
506  * at certain conditions; if the conditions are not respected, an exception is thrown.
507  * The number of components can be changed in \a this only if \a this is not allocated.
508  * The condition of number of components must not be changed.
509  *
510  * To know more on format of the component information see
511  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
512  *  \param [in] info - a vector of component infos.
513  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
514  */
515 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
516 {
517   if(getNumberOfComponents()!=(int)info.size())
518     {
519       if(!isAllocated())
520         _info_on_compo=info;
521       else
522         {
523           std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
524           throw INTERP_KERNEL::Exception(oss.str().c_str());
525         }
526     }
527   else
528     _info_on_compo=info;
529 }
530
531 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
532 {
533   if(getNumberOfTuples()!=nbOfTuples)
534     {
535       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538 }
539
540 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
541 {
542   if(getNumberOfComponents()!=nbOfCompo)
543     {
544       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547 }
548
549 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
550 {
551   if(getNbOfElems()!=nbOfElems)
552     {
553       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
554       throw INTERP_KERNEL::Exception(oss.str().c_str());
555     }
556 }
557
558 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
559 {
560   if(getNumberOfTuples()!=other.getNumberOfTuples())
561     {
562       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
563       throw INTERP_KERNEL::Exception(oss.str().c_str());
564     }
565   if(getNumberOfComponents()!=other.getNumberOfComponents())
566     {
567       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570 }
571
572 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
573 {
574   checkNbOfTuples(nbOfTuples,msg);
575   checkNbOfComps(nbOfCompo,msg);
576 }
577
578 /*!
579  * Simply this method checks that \b value is in [0,\b ref).
580  */
581 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
582 {
583   if(value<0 || value>=ref)
584     {
585       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588 }
589
590 /*!
591  * This method checks that [\b start, \b end) is compliant with ref length \b value.
592  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
593  */
594 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
595 {
596   if(start<0 || start>=value)
597     {
598       if(value!=start || end!=start)
599         {
600           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
601           throw INTERP_KERNEL::Exception(oss.str().c_str());
602         }
603     }
604   if(end<0 || end>value)
605     {
606       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
607       throw INTERP_KERNEL::Exception(oss.str().c_str());
608     }
609 }
610
611 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
612 {
613   if(value<0 || value>ref)
614     {
615       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
616       throw INTERP_KERNEL::Exception(oss.str().c_str());
617     }
618 }
619
620 /*!
621  * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, 
622  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
623  *
624  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
625  *
626  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
627  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
628  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
629  * \param [in] sliceId - the slice id considered
630  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
631  * \param [out] startSlice - the start of the slice considered
632  * \param [out] stopSlice - the stop of the slice consided
633  * 
634  * \throw If \a step == 0
635  * \throw If \a nbOfSlices not > 0
636  * \throw If \a sliceId not in [0,nbOfSlices)
637  */
638 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
639 {
640   if(nbOfSlices<=0)
641     {
642       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
643       throw INTERP_KERNEL::Exception(oss.str().c_str());
644     }
645   if(sliceId<0 || sliceId>=nbOfSlices)
646     {
647       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
648       throw INTERP_KERNEL::Exception(oss.str().c_str());
649     }
650   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
651   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
652   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
653   if(sliceId<nbOfSlices-1)
654     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
655   else
656     stopSlice=stop;
657 }
658
659 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
660 {
661   if(end<begin)
662     {
663       std::ostringstream oss; oss << msg << " : end before begin !";
664       throw INTERP_KERNEL::Exception(oss.str().c_str());
665     }
666   if(end==begin)
667     return 0;
668   if(step<=0)
669     {
670       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   return (end-1-begin)/step+1;
674 }
675
676 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
677 {
678   if(step==0)
679     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
680   if(end<begin && step>0)
681     {
682       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   if(begin<end && step<0)
686     {
687       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   if(begin!=end)
691     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
692   else
693     return 0;
694 }
695
696 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
697 {
698   if(step!=0)
699     {
700       if(step>0)
701         {
702           if(begin<=value && value<end)
703             {
704               if((value-begin)%step==0)
705                 return (value-begin)/step;
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712       else
713         {
714           if(begin>=value && value>end)
715             {
716               if((begin-value)%(-step)==0)
717                 return (begin-value)/(-step);
718               else
719                 return -1;
720             }
721           else
722             return -1;
723         }
724     }
725   else
726     return -1;
727 }
728
729 /*!
730  * Returns a new instance of DataArrayDouble. The caller is to delete this array
731  * using decrRef() as it is no more needed. 
732  */
733 DataArrayDouble *DataArrayDouble::New()
734 {
735   return new DataArrayDouble;
736 }
737
738 /*!
739  * Checks if raw data is allocated. Read more on the raw data
740  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
741  *  \return bool - \a true if the raw data is allocated, \a false else.
742  */
743 bool DataArrayDouble::isAllocated() const
744 {
745   return getConstPointer()!=0;
746 }
747
748 /*!
749  * Checks if raw data is allocated and throws an exception if it is not the case.
750  *  \throw If the raw data is not allocated.
751  */
752 void DataArrayDouble::checkAllocated() const
753 {
754   if(!isAllocated())
755     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
756 }
757
758 /*!
759  * This method desallocated \a this without modification of informations relative to the components.
760  * After call of this method, DataArrayDouble::isAllocated will return false.
761  * If \a this is already not allocated, \a this is let unchanged.
762  */
763 void DataArrayDouble::desallocate()
764 {
765   _mem.destroy();
766 }
767
768 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
769 {
770   std::size_t sz(_mem.getNbOfElemAllocated());
771   sz*=sizeof(double);
772   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
773 }
774
775 /*!
776  * Returns the only one value in \a this, if and only if number of elements
777  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
778  *  \return double - the sole value stored in \a this array.
779  *  \throw If at least one of conditions stated above is not fulfilled.
780  */
781 double DataArrayDouble::doubleValue() const
782 {
783   if(isAllocated())
784     {
785       if(getNbOfElems()==1)
786         {
787           return *getConstPointer();
788         }
789       else
790         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
791     }
792   else
793     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
794 }
795
796 /*!
797  * Checks the number of tuples.
798  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
799  *  \throw If \a this is not allocated.
800  */
801 bool DataArrayDouble::empty() const
802 {
803   checkAllocated();
804   return getNumberOfTuples()==0;
805 }
806
807 /*!
808  * Returns a full copy of \a this. For more info on copying data arrays see
809  * \ref MEDCouplingArrayBasicsCopyDeep.
810  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
811  *          delete this array using decrRef() as it is no more needed. 
812  */
813 DataArrayDouble *DataArrayDouble::deepCpy() const
814 {
815   return new DataArrayDouble(*this);
816 }
817
818 /*!
819  * Returns either a \a deep or \a shallow copy of this array. For more info see
820  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
821  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
822  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
823  *          == \a true) or \a this instance (if \a dCpy == \a false).
824  */
825 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
826 {
827   if(dCpy)
828     return deepCpy();
829   else
830     {
831       incrRef();
832       return const_cast<DataArrayDouble *>(this);
833     }
834 }
835
836 /*!
837  * Copies all the data from another DataArrayDouble. For more info see
838  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
839  *  \param [in] other - another instance of DataArrayDouble to copy data from.
840  *  \throw If the \a other is not allocated.
841  */
842 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
843 {
844   other.checkAllocated();
845   int nbOfTuples=other.getNumberOfTuples();
846   int nbOfComp=other.getNumberOfComponents();
847   allocIfNecessary(nbOfTuples,nbOfComp);
848   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
849   double *pt=getPointer();
850   const double *ptI=other.getConstPointer();
851   for(std::size_t i=0;i<nbOfElems;i++)
852     pt[i]=ptI[i];
853   copyStringInfoFrom(other);
854 }
855
856 /*!
857  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
858  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
859  * If \a this has not already been allocated, number of components is set to one.
860  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
861  * 
862  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
863  */
864 void DataArrayDouble::reserve(std::size_t nbOfElems)
865 {
866   int nbCompo=getNumberOfComponents();
867   if(nbCompo==1)
868     {
869       _mem.reserve(nbOfElems);
870     }
871   else if(nbCompo==0)
872     {
873       _mem.reserve(nbOfElems);
874       _info_on_compo.resize(1);
875     }
876   else
877     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
878 }
879
880 /*!
881  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
882  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
883  *
884  * \param [in] val the value to be added in \a this
885  * \throw If \a this has already been allocated with number of components different from one.
886  * \sa DataArrayDouble::pushBackValsSilent
887  */
888 void DataArrayDouble::pushBackSilent(double val)
889 {
890   int nbCompo=getNumberOfComponents();
891   if(nbCompo==1)
892     _mem.pushBack(val);
893   else if(nbCompo==0)
894     {
895       _info_on_compo.resize(1);
896       _mem.pushBack(val);
897     }
898   else
899     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
900 }
901
902 /*!
903  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
904  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
905  *
906  *  \param [in] valsBg - an array of values to push at the end of \this.
907  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
908  *              the last value of \a valsBg is \a valsEnd[ -1 ].
909  * \throw If \a this has already been allocated with number of components different from one.
910  * \sa DataArrayDouble::pushBackSilent
911  */
912 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
913 {
914   int nbCompo=getNumberOfComponents();
915   if(nbCompo==1)
916     _mem.insertAtTheEnd(valsBg,valsEnd);
917   else if(nbCompo==0)
918     {
919       _info_on_compo.resize(1);
920       _mem.insertAtTheEnd(valsBg,valsEnd);
921     }
922   else
923     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
924 }
925
926 /*!
927  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
928  * \throw If \a this is already empty.
929  * \throw If \a this has number of components different from one.
930  */
931 double DataArrayDouble::popBackSilent()
932 {
933   if(getNumberOfComponents()==1)
934     return _mem.popBack();
935   else
936     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
937 }
938
939 /*!
940  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
941  *
942  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
943  */
944 void DataArrayDouble::pack() const
945 {
946   _mem.pack();
947 }
948
949 /*!
950  * Allocates the raw data in memory. If exactly same memory as needed already
951  * allocated, it is not re-allocated.
952  *  \param [in] nbOfTuple - number of tuples of data to allocate.
953  *  \param [in] nbOfCompo - number of components of data to allocate.
954  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
955  */
956 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
957 {
958   if(isAllocated())
959     {
960       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
961         alloc(nbOfTuple,nbOfCompo);
962     }
963   else
964     alloc(nbOfTuple,nbOfCompo);
965 }
966
967 /*!
968  * Allocates the raw data in memory. If the memory was already allocated, then it is
969  * freed and re-allocated. See an example of this method use
970  * \ref MEDCouplingArraySteps1WC "here".
971  *  \param [in] nbOfTuple - number of tuples of data to allocate.
972  *  \param [in] nbOfCompo - number of components of data to allocate.
973  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
974  */
975 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
976 {
977   if(nbOfTuple<0 || nbOfCompo<0)
978     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
979   _info_on_compo.resize(nbOfCompo);
980   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign zero to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  * \throw If \a this is not allocated.
988  */
989 void DataArrayDouble::fillWithZero()
990 {
991   checkAllocated();
992   _mem.fillWithValue(0.);
993   declareAsNew();
994 }
995
996 /*!
997  * Assign \a val to all values in \a this array. To know more on filling arrays see
998  * \ref MEDCouplingArrayFill.
999  *  \param [in] val - the value to fill with.
1000  *  \throw If \a this is not allocated.
1001  */
1002 void DataArrayDouble::fillWithValue(double val)
1003 {
1004   checkAllocated();
1005   _mem.fillWithValue(val);
1006   declareAsNew();
1007 }
1008
1009 /*!
1010  * Set all values in \a this array so that the i-th element equals to \a init + i
1011  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1012  *  \param [in] init - value to assign to the first element of array.
1013  *  \throw If \a this->getNumberOfComponents() != 1
1014  *  \throw If \a this is not allocated.
1015  */
1016 void DataArrayDouble::iota(double init)
1017 {
1018   checkAllocated();
1019   if(getNumberOfComponents()!=1)
1020     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1021   double *ptr=getPointer();
1022   int ntuples=getNumberOfTuples();
1023   for(int i=0;i<ntuples;i++)
1024     ptr[i]=init+double(i);
1025   declareAsNew();
1026 }
1027
1028 /*!
1029  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1030  *  \param [in] val - value to check equality of array values to.
1031  *  \param [in] eps - precision to check the equality.
1032  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1033  *                 \a false else.
1034  *  \throw If \a this->getNumberOfComponents() != 1
1035  *  \throw If \a this is not allocated.
1036  */
1037 bool DataArrayDouble::isUniform(double val, double eps) const
1038 {
1039   checkAllocated();
1040   if(getNumberOfComponents()!=1)
1041     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1042   int nbOfTuples=getNumberOfTuples();
1043   const double *w=getConstPointer();
1044   const double *end2=w+nbOfTuples;
1045   const double vmin=val-eps;
1046   const double vmax=val+eps;
1047   for(;w!=end2;w++)
1048     if(*w<vmin || *w>vmax)
1049       return false;
1050   return true;
1051 }
1052
1053 /*!
1054  * Sorts values of the array.
1055  *  \param [in] asc - \a true means ascending order, \a false, descending.
1056  *  \throw If \a this is not allocated.
1057  *  \throw If \a this->getNumberOfComponents() != 1.
1058  */
1059 void DataArrayDouble::sort(bool asc)
1060 {
1061   checkAllocated();
1062   if(getNumberOfComponents()!=1)
1063     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1064   _mem.sort(asc);
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Reverse the array values.
1070  *  \throw If \a this->getNumberOfComponents() < 1.
1071  *  \throw If \a this is not allocated.
1072  */
1073 void DataArrayDouble::reverse()
1074 {
1075   checkAllocated();
1076   _mem.reverse(getNumberOfComponents());
1077   declareAsNew();
1078 }
1079
1080 /*!
1081  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1082  * with at least absolute difference value of |\a eps| at each step.
1083  * If not an exception is thrown.
1084  *  \param [in] increasing - if \a true, the array values should be increasing.
1085  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1086  *                    the values are considered different.
1087  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1088  *         increasing arg.
1089  *  \throw If \a this->getNumberOfComponents() != 1.
1090  *  \throw If \a this is not allocated.
1091  */
1092 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1093 {
1094   if(!isMonotonic(increasing,eps))
1095     {
1096       if (increasing)
1097         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1098       else
1099         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1100     }
1101 }
1102
1103 /*!
1104  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1105  * with at least absolute difference value of |\a eps| at each step.
1106  *  \param [in] increasing - if \a true, array values should be increasing.
1107  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1108  *                    the values are considered different.
1109  *  \return bool - \a true if values change in accordance with \a increasing arg.
1110  *  \throw If \a this->getNumberOfComponents() != 1.
1111  *  \throw If \a this is not allocated.
1112  */
1113 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1114 {
1115   checkAllocated();
1116   if(getNumberOfComponents()!=1)
1117     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1118   int nbOfElements=getNumberOfTuples();
1119   const double *ptr=getConstPointer();
1120   if(nbOfElements==0)
1121     return true;
1122   double ref=ptr[0];
1123   double absEps=fabs(eps);
1124   if(increasing)
1125     {
1126       for(int i=1;i<nbOfElements;i++)
1127         {
1128           if(ptr[i]<(ref+absEps))
1129             return false;
1130           ref=ptr[i];
1131         }
1132       return true;
1133     }
1134   else
1135     {
1136       for(int i=1;i<nbOfElements;i++)
1137         {
1138           if(ptr[i]>(ref-absEps))
1139             return false;
1140           ref=ptr[i];
1141         }
1142       return true;
1143     }
1144 }
1145
1146 /*!
1147  * Returns a textual and human readable representation of \a this instance of
1148  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1149  *  \return std::string - text describing \a this DataArrayDouble.
1150  */
1151 std::string DataArrayDouble::repr() const
1152 {
1153   std::ostringstream ret;
1154   reprStream(ret);
1155   return ret.str();
1156 }
1157
1158 std::string DataArrayDouble::reprZip() const
1159 {
1160   std::ostringstream ret;
1161   reprZipStream(ret);
1162   return ret.str();
1163 }
1164
1165 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1166 {
1167   static const char SPACE[4]={' ',' ',' ',' '};
1168   checkAllocated();
1169   std::string idt(indent,' ');
1170   ofs.precision(17);
1171   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1172   if(byteArr)
1173     {
1174       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1175       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1176       float *pt(tmp);
1177       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1178       for(const double *src=begin();src!=end();src++,pt++)
1179         *pt=float(*src);
1180       const char *data(reinterpret_cast<const char *>((float *)tmp));
1181       std::size_t sz(getNbOfElems()*sizeof(float));
1182       byteArr->insertAtTheEnd(data,data+sz);
1183       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1184     }
1185   else
1186     {
1187       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1188       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1189     }
1190   ofs << std::endl << idt << "</DataArray>\n";
1191 }
1192
1193 void DataArrayDouble::reprStream(std::ostream& stream) const
1194 {
1195   stream << "Name of double array : \"" << _name << "\"\n";
1196   reprWithoutNameStream(stream);
1197 }
1198
1199 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1200 {
1201   stream << "Name of double array : \"" << _name << "\"\n";
1202   reprZipWithoutNameStream(stream);
1203 }
1204
1205 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1206 {
1207   DataArray::reprWithoutNameStream(stream);
1208   stream.precision(17);
1209   _mem.repr(getNumberOfComponents(),stream);
1210 }
1211
1212 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1213 {
1214   DataArray::reprWithoutNameStream(stream);
1215   stream.precision(17);
1216   _mem.reprZip(getNumberOfComponents(),stream);
1217 }
1218
1219 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1220 {
1221   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1222   const double *data=getConstPointer();
1223   stream.precision(17);
1224   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1225   if(nbTuples*nbComp>=1)
1226     {
1227       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1228       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1229       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1230       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1231     }
1232   else
1233     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1234   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1235 }
1236
1237 /*!
1238  * Method that gives a quick overvien of \a this for python.
1239  */
1240 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1241 {
1242   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1243   stream << "DataArrayDouble C++ instance at " << this << ". ";
1244   if(isAllocated())
1245     {
1246       int nbOfCompo=(int)_info_on_compo.size();
1247       if(nbOfCompo>=1)
1248         {
1249           int nbOfTuples=getNumberOfTuples();
1250           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1251           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1252         }
1253       else
1254         stream << "Number of components : 0.";
1255     }
1256   else
1257     stream << "*** No data allocated ****";
1258 }
1259
1260 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1261 {
1262   const double *data=begin();
1263   int nbOfTuples=getNumberOfTuples();
1264   int nbOfCompo=(int)_info_on_compo.size();
1265   std::ostringstream oss2; oss2 << "[";
1266   oss2.precision(17);
1267   std::string oss2Str(oss2.str());
1268   bool isFinished=true;
1269   for(int i=0;i<nbOfTuples && isFinished;i++)
1270     {
1271       if(nbOfCompo>1)
1272         {
1273           oss2 << "(";
1274           for(int j=0;j<nbOfCompo;j++,data++)
1275             {
1276               oss2 << *data;
1277               if(j!=nbOfCompo-1) oss2 << ", ";
1278             }
1279           oss2 << ")";
1280         }
1281       else
1282         oss2 << *data++;
1283       if(i!=nbOfTuples-1) oss2 << ", ";
1284       std::string oss3Str(oss2.str());
1285       if(oss3Str.length()<maxNbOfByteInRepr)
1286         oss2Str=oss3Str;
1287       else
1288         isFinished=false;
1289     }
1290   stream << oss2Str;
1291   if(!isFinished)
1292     stream << "... ";
1293   stream << "]";
1294 }
1295
1296 /*!
1297  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1298  * mismatch is given.
1299  * 
1300  * \param [in] other the instance to be compared with \a this
1301  * \param [in] prec the precision to compare numeric data of the arrays.
1302  * \param [out] reason In case of inequality returns the reason.
1303  * \sa DataArrayDouble::isEqual
1304  */
1305 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1306 {
1307   if(!areInfoEqualsIfNotWhy(other,reason))
1308     return false;
1309   return _mem.isEqual(other._mem,prec,reason);
1310 }
1311
1312 /*!
1313  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1314  * \ref MEDCouplingArrayBasicsCompare.
1315  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1316  *  \param [in] prec - precision value to compare numeric data of the arrays.
1317  *  \return bool - \a true if the two arrays are equal, \a false else.
1318  */
1319 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1320 {
1321   std::string tmp;
1322   return isEqualIfNotWhy(other,prec,tmp);
1323 }
1324
1325 /*!
1326  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1327  * \ref MEDCouplingArrayBasicsCompare.
1328  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1329  *  \param [in] prec - precision value to compare numeric data of the arrays.
1330  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1331  */
1332 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1333 {
1334   std::string tmp;
1335   return _mem.isEqual(other._mem,prec,tmp);
1336 }
1337
1338 /*!
1339  * Changes number of tuples in the array. If the new number of tuples is smaller
1340  * than the current number the array is truncated, otherwise the array is extended.
1341  *  \param [in] nbOfTuples - new number of tuples. 
1342  *  \throw If \a this is not allocated.
1343  *  \throw If \a nbOfTuples is negative.
1344  */
1345 void DataArrayDouble::reAlloc(int nbOfTuples)
1346 {
1347   if(nbOfTuples<0)
1348     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1349   checkAllocated();
1350   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1351   declareAsNew();
1352 }
1353
1354 /*!
1355  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1356  * array to the new one.
1357  *  \return DataArrayInt * - the new instance of DataArrayInt.
1358  */
1359 DataArrayInt *DataArrayDouble::convertToIntArr() const
1360 {
1361   DataArrayInt *ret=DataArrayInt::New();
1362   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1363   int *dest=ret->getPointer();
1364   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1365   for(const double *src=begin();src!=end();src++,dest++)
1366     *dest=(int)*src;
1367   ret->copyStringInfoFrom(*this);
1368   return ret;
1369 }
1370
1371 /*!
1372  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1373  * arranged in memory. If \a this array holds 2 components of 3 values:
1374  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1375  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1376  *  \warning Do not confuse this method with transpose()!
1377  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1378  *          is to delete using decrRef() as it is no more needed.
1379  *  \throw If \a this is not allocated.
1380  */
1381 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1382 {
1383   if(_mem.isNull())
1384     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1385   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1386   DataArrayDouble *ret=DataArrayDouble::New();
1387   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1388   return ret;
1389 }
1390
1391 /*!
1392  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1393  * arranged in memory. If \a this array holds 2 components of 3 values:
1394  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1395  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1396  *  \warning Do not confuse this method with transpose()!
1397  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1398  *          is to delete using decrRef() as it is no more needed.
1399  *  \throw If \a this is not allocated.
1400  */
1401 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1402 {
1403   if(_mem.isNull())
1404     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1405   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1406   DataArrayDouble *ret=DataArrayDouble::New();
1407   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1408   return ret;
1409 }
1410
1411 /*!
1412  * Permutes values of \a this array as required by \a old2New array. The values are
1413  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1414  * the same as in \this one.
1415  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1416  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1417  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1418  *     giving a new position for i-th old value.
1419  */
1420 void DataArrayDouble::renumberInPlace(const int *old2New)
1421 {
1422   checkAllocated();
1423   int nbTuples=getNumberOfTuples();
1424   int nbOfCompo=getNumberOfComponents();
1425   double *tmp=new double[nbTuples*nbOfCompo];
1426   const double *iptr=getConstPointer();
1427   for(int i=0;i<nbTuples;i++)
1428     {
1429       int v=old2New[i];
1430       if(v>=0 && v<nbTuples)
1431         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1432       else
1433         {
1434           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1435           throw INTERP_KERNEL::Exception(oss.str().c_str());
1436         }
1437     }
1438   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1439   delete [] tmp;
1440   declareAsNew();
1441 }
1442
1443 /*!
1444  * Permutes values of \a this array as required by \a new2Old array. The values are
1445  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1446  * the same as in \this one.
1447  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1448  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1449  *     giving a previous position of i-th new value.
1450  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1451  *          is to delete using decrRef() as it is no more needed.
1452  */
1453 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1454 {
1455   checkAllocated();
1456   int nbTuples=getNumberOfTuples();
1457   int nbOfCompo=getNumberOfComponents();
1458   double *tmp=new double[nbTuples*nbOfCompo];
1459   const double *iptr=getConstPointer();
1460   for(int i=0;i<nbTuples;i++)
1461     {
1462       int v=new2Old[i];
1463       if(v>=0 && v<nbTuples)
1464         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1465       else
1466         {
1467           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1468           throw INTERP_KERNEL::Exception(oss.str().c_str());
1469         }
1470     }
1471   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1472   delete [] tmp;
1473   declareAsNew();
1474 }
1475
1476 /*!
1477  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1478  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1479  * Number of tuples in the result array remains the same as in \this one.
1480  * If a permutation reduction is needed, renumberAndReduce() should be used.
1481  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1482  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1483  *          giving a new position for i-th old value.
1484  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1485  *          is to delete using decrRef() as it is no more needed.
1486  *  \throw If \a this is not allocated.
1487  */
1488 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1489 {
1490   checkAllocated();
1491   int nbTuples=getNumberOfTuples();
1492   int nbOfCompo=getNumberOfComponents();
1493   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1494   ret->alloc(nbTuples,nbOfCompo);
1495   ret->copyStringInfoFrom(*this);
1496   const double *iptr=getConstPointer();
1497   double *optr=ret->getPointer();
1498   for(int i=0;i<nbTuples;i++)
1499     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1500   ret->copyStringInfoFrom(*this);
1501   return ret.retn();
1502 }
1503
1504 /*!
1505  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1506  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1507  * tuples in the result array remains the same as in \this one.
1508  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1509  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1510  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1511  *     giving a previous position of i-th new value.
1512  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1513  *          is to delete using decrRef() as it is no more needed.
1514  */
1515 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1516 {
1517   checkAllocated();
1518   int nbTuples=getNumberOfTuples();
1519   int nbOfCompo=getNumberOfComponents();
1520   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1521   ret->alloc(nbTuples,nbOfCompo);
1522   ret->copyStringInfoFrom(*this);
1523   const double *iptr=getConstPointer();
1524   double *optr=ret->getPointer();
1525   for(int i=0;i<nbTuples;i++)
1526     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1527   ret->copyStringInfoFrom(*this);
1528   return ret.retn();
1529 }
1530
1531 /*!
1532  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1533  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1534  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1535  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1536  * \a old2New[ i ] is negative, is missing from the result array.
1537  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1538  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1539  *     giving a new position for i-th old tuple and giving negative position for
1540  *     for i-th old tuple that should be omitted.
1541  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1542  *          is to delete using decrRef() as it is no more needed.
1543  */
1544 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1545 {
1546   checkAllocated();
1547   int nbTuples=getNumberOfTuples();
1548   int nbOfCompo=getNumberOfComponents();
1549   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1550   ret->alloc(newNbOfTuple,nbOfCompo);
1551   const double *iptr=getConstPointer();
1552   double *optr=ret->getPointer();
1553   for(int i=0;i<nbTuples;i++)
1554     {
1555       int w=old2New[i];
1556       if(w>=0)
1557         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1558     }
1559   ret->copyStringInfoFrom(*this);
1560   return ret.retn();
1561 }
1562
1563 /*!
1564  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1565  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1566  * \a new2OldBg array.
1567  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1568  * This method is equivalent to renumberAndReduce() except that convention in input is
1569  * \c new2old and \b not \c old2new.
1570  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1571  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1572  *              tuple index in \a this array to fill the i-th tuple in the new array.
1573  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1574  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1575  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1576  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1577  *          is to delete using decrRef() as it is no more needed.
1578  */
1579 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1580 {
1581   checkAllocated();
1582   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1583   int nbComp=getNumberOfComponents();
1584   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1585   ret->copyStringInfoFrom(*this);
1586   double *pt=ret->getPointer();
1587   const double *srcPt=getConstPointer();
1588   int i=0;
1589   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1590     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1591   ret->copyStringInfoFrom(*this);
1592   return ret.retn();
1593 }
1594
1595 /*!
1596  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1597  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1598  * \a new2OldBg array.
1599  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1600  * This method is equivalent to renumberAndReduce() except that convention in input is
1601  * \c new2old and \b not \c old2new.
1602  * This method is equivalent to selectByTupleId() except that it prevents coping data
1603  * from behind the end of \a this array.
1604  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1605  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1606  *              tuple index in \a this array to fill the i-th tuple in the new array.
1607  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1608  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1609  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1610  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1611  *          is to delete using decrRef() as it is no more needed.
1612  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1613  */
1614 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1615 {
1616   checkAllocated();
1617   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1618   int nbComp=getNumberOfComponents();
1619   int oldNbOfTuples=getNumberOfTuples();
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     if(*w>=0 && *w<oldNbOfTuples)
1627       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1628     else
1629       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1630   ret->copyStringInfoFrom(*this);
1631   return ret.retn();
1632 }
1633
1634 /*!
1635  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1636  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1637  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1638  * command \c range( \a bg, \a end2, \a step ).
1639  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1640  * not constructed explicitly.
1641  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1642  *  \param [in] bg - index of the first tuple to copy from \a this array.
1643  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1644  *  \param [in] step - index increment to get index of the next tuple to copy.
1645  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1646  *          is to delete using decrRef() as it is no more needed.
1647  *  \sa DataArrayDouble::substr.
1648  */
1649 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1650 {
1651   checkAllocated();
1652   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1653   int nbComp=getNumberOfComponents();
1654   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1655   ret->alloc(newNbOfTuples,nbComp);
1656   double *pt=ret->getPointer();
1657   const double *srcPt=getConstPointer()+bg*nbComp;
1658   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1659     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1660   ret->copyStringInfoFrom(*this);
1661   return ret.retn();
1662 }
1663
1664 /*!
1665  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1666  * of tuples specified by \a ranges parameter.
1667  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1668  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1669  *              of tuples in [\c begin,\c end) format.
1670  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1671  *          is to delete using decrRef() as it is no more needed.
1672  *  \throw If \a end < \a begin.
1673  *  \throw If \a end > \a this->getNumberOfTuples().
1674  *  \throw If \a this is not allocated.
1675  */
1676 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1677 {
1678   checkAllocated();
1679   int nbOfComp=getNumberOfComponents();
1680   int nbOfTuplesThis=getNumberOfTuples();
1681   if(ranges.empty())
1682     {
1683       DataArrayDouble *ret=DataArrayDouble::New();
1684       ret->alloc(0,nbOfComp);
1685       ret->copyStringInfoFrom(*this);
1686       return ret;
1687     }
1688   int ref=ranges.front().first;
1689   int nbOfTuples=0;
1690   bool isIncreasing=true;
1691   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1692     {
1693       if((*it).first<=(*it).second)
1694         {
1695           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1696             {
1697               nbOfTuples+=(*it).second-(*it).first;
1698               if(isIncreasing)
1699                 isIncreasing=ref<=(*it).first;
1700               ref=(*it).second;
1701             }
1702           else
1703             {
1704               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1705               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1706               throw INTERP_KERNEL::Exception(oss.str().c_str());
1707             }
1708         }
1709       else
1710         {
1711           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1712           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1713           throw INTERP_KERNEL::Exception(oss.str().c_str());
1714         }
1715     }
1716   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1717     return deepCpy();
1718   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1719   ret->alloc(nbOfTuples,nbOfComp);
1720   ret->copyStringInfoFrom(*this);
1721   const double *src=getConstPointer();
1722   double *work=ret->getPointer();
1723   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1724     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1725   return ret.retn();
1726 }
1727
1728 /*!
1729  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1730  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1731  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1732  * This method is a specialization of selectByTupleId2().
1733  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1734  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1735  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1736  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1737  *          is to delete using decrRef() as it is no more needed.
1738  *  \throw If \a tupleIdBg < 0.
1739  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1740     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1741  *  \sa DataArrayDouble::selectByTupleId2
1742  */
1743 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1744 {
1745   checkAllocated();
1746   int nbt=getNumberOfTuples();
1747   if(tupleIdBg<0)
1748     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1749   if(tupleIdBg>nbt)
1750     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1751   int trueEnd=tupleIdEnd;
1752   if(tupleIdEnd!=-1)
1753     {
1754       if(tupleIdEnd>nbt)
1755         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1756     }
1757   else
1758     trueEnd=nbt;
1759   int nbComp=getNumberOfComponents();
1760   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1761   ret->alloc(trueEnd-tupleIdBg,nbComp);
1762   ret->copyStringInfoFrom(*this);
1763   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1764   return ret.retn();
1765 }
1766
1767 /*!
1768  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1769  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1770  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1771  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1772  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1773  * components.  
1774  *  \param [in] newNbOfComp - number of components for the new array to have.
1775  *  \param [in] dftValue - value assigned to new values added to the new array.
1776  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1777  *          is to delete using decrRef() as it is no more needed.
1778  *  \throw If \a this is not allocated.
1779  */
1780 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1781 {
1782   checkAllocated();
1783   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1784   ret->alloc(getNumberOfTuples(),newNbOfComp);
1785   const double *oldc=getConstPointer();
1786   double *nc=ret->getPointer();
1787   int nbOfTuples=getNumberOfTuples();
1788   int oldNbOfComp=getNumberOfComponents();
1789   int dim=std::min(oldNbOfComp,newNbOfComp);
1790   for(int i=0;i<nbOfTuples;i++)
1791     {
1792       int j=0;
1793       for(;j<dim;j++)
1794         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1795       for(;j<newNbOfComp;j++)
1796         nc[newNbOfComp*i+j]=dftValue;
1797     }
1798   ret->setName(getName());
1799   for(int i=0;i<dim;i++)
1800     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1801   ret->setName(getName());
1802   return ret.retn();
1803 }
1804
1805 /*!
1806  * Changes the number of components within \a this array so that its raw data **does
1807  * not** change, instead splitting this data into tuples changes.
1808  *  \warning This method erases all (name and unit) component info set before!
1809  *  \param [in] newNbOfComp - number of components for \a this array to have.
1810  *  \throw If \a this is not allocated
1811  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1812  *  \throw If \a newNbOfCompo is lower than 1.
1813  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1814  *  \warning This method erases all (name and unit) component info set before!
1815  */
1816 void DataArrayDouble::rearrange(int newNbOfCompo)
1817 {
1818   checkAllocated();
1819   if(newNbOfCompo<1)
1820     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1821   std::size_t nbOfElems=getNbOfElems();
1822   if(nbOfElems%newNbOfCompo!=0)
1823     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1824   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1825     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1826   _info_on_compo.clear();
1827   _info_on_compo.resize(newNbOfCompo);
1828   declareAsNew();
1829 }
1830
1831 /*!
1832  * Changes the number of components within \a this array to be equal to its number
1833  * of tuples, and inversely its number of tuples to become equal to its number of 
1834  * components. So that its raw data **does not** change, instead splitting this
1835  * data into tuples changes.
1836  *  \warning This method erases all (name and unit) component info set before!
1837  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1838  *  \throw If \a this is not allocated.
1839  *  \sa rearrange()
1840  */
1841 void DataArrayDouble::transpose()
1842 {
1843   checkAllocated();
1844   int nbOfTuples=getNumberOfTuples();
1845   rearrange(nbOfTuples);
1846 }
1847
1848 /*!
1849  * Returns a copy of \a this array composed of selected components.
1850  * The new DataArrayDouble has the same number of tuples but includes components
1851  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1852  * can be either less, same or more than \a this->getNbOfElems().
1853  *  \param [in] compoIds - sequence of zero based indices of components to include
1854  *              into the new array.
1855  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1856  *          is to delete using decrRef() as it is no more needed.
1857  *  \throw If \a this is not allocated.
1858  *  \throw If a component index (\a i) is not valid: 
1859  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1860  *
1861  *  \if ENABLE_EXAMPLES
1862  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1863  *  \endif
1864  */
1865 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1866 {
1867   checkAllocated();
1868   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1869   std::size_t newNbOfCompo=compoIds.size();
1870   int oldNbOfCompo=getNumberOfComponents();
1871   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1872     if((*it)<0 || (*it)>=oldNbOfCompo)
1873       {
1874         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1875         throw INTERP_KERNEL::Exception(oss.str().c_str());
1876       }
1877   int nbOfTuples=getNumberOfTuples();
1878   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1879   ret->copyPartOfStringInfoFrom(*this,compoIds);
1880   const double *oldc=getConstPointer();
1881   double *nc=ret->getPointer();
1882   for(int i=0;i<nbOfTuples;i++)
1883     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1884       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1885   return ret.retn();
1886 }
1887
1888 /*!
1889  * Appends components of another array to components of \a this one, tuple by tuple.
1890  * So that the number of tuples of \a this array remains the same and the number of 
1891  * components increases.
1892  *  \param [in] other - the DataArrayDouble to append to \a this one.
1893  *  \throw If \a this is not allocated.
1894  *  \throw If \a this and \a other arrays have different number of tuples.
1895  *
1896  *  \if ENABLE_EXAMPLES
1897  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1898  *
1899  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1900  *  \endif
1901  */
1902 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1903 {
1904   checkAllocated();
1905   other->checkAllocated();
1906   int nbOfTuples=getNumberOfTuples();
1907   if(nbOfTuples!=other->getNumberOfTuples())
1908     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1909   int nbOfComp1=getNumberOfComponents();
1910   int nbOfComp2=other->getNumberOfComponents();
1911   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1912   double *w=newArr;
1913   const double *inp1=getConstPointer();
1914   const double *inp2=other->getConstPointer();
1915   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1916     {
1917       w=std::copy(inp1,inp1+nbOfComp1,w);
1918       w=std::copy(inp2,inp2+nbOfComp2,w);
1919     }
1920   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1921   std::vector<int> compIds(nbOfComp2);
1922   for(int i=0;i<nbOfComp2;i++)
1923     compIds[i]=nbOfComp1+i;
1924   copyPartOfStringInfoFrom2(compIds,*other);
1925 }
1926
1927 /*!
1928  * This method checks that all tuples in \a other are in \a this.
1929  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1930  * 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.
1931  *
1932  * \param [in] other - the array having the same number of components than \a this.
1933  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1934  * \sa DataArrayDouble::findCommonTuples
1935  */
1936 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1937 {
1938   if(!other)
1939     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1940   checkAllocated(); other->checkAllocated();
1941   if(getNumberOfComponents()!=other->getNumberOfComponents())
1942     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1943   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1944   DataArrayInt *c=0,*ci=0;
1945   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1946   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1947   int newNbOfTuples=-1;
1948   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1949   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1950   tupleIds=ret1.retn();
1951   return newNbOfTuples==getNumberOfTuples();
1952 }
1953
1954 /*!
1955  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1956  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1957  * distance separating two points is computed with the infinite norm.
1958  *
1959  * Indices of coincident tuples are stored in output arrays.
1960  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1961  *
1962  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1963  * MEDCouplingUMesh::mergeNodes().
1964  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1965  *              considered not coincident.
1966  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1967  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1968  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1969  *               \a comm->getNumberOfComponents() == 1. 
1970  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1971  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1972  *               groups of (indices of) coincident tuples. Its every value is a tuple
1973  *               index where a next group of tuples begins. For example the second
1974  *               group of tuples in \a comm is described by following range of indices:
1975  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1976  *               gives the number of groups of coincident tuples.
1977  *  \throw If \a this is not allocated.
1978  *  \throw If the number of components is not in [1,2,3,4].
1979  *
1980  *  \if ENABLE_EXAMPLES
1981  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1982  *
1983  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1984  *  \endif
1985  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1986  */
1987 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1988 {
1989   checkAllocated();
1990   int nbOfCompo=getNumberOfComponents();
1991   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1992     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1993
1994   int nbOfTuples=getNumberOfTuples();
1995   //
1996   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1997   switch(nbOfCompo)
1998   {
1999     case 4:
2000       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2001       break;
2002     case 3:
2003       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2004       break;
2005     case 2:
2006       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2007       break;
2008     case 1:
2009       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2010       break;
2011     default:
2012       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2013   }
2014   comm=c.retn();
2015   commIndex=cI.retn();
2016 }
2017
2018 /*!
2019  * 
2020  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2021  *             \a nbTimes  should be at least equal to 1.
2022  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2023  * \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.
2024  */
2025 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2026 {
2027   checkAllocated();
2028   if(getNumberOfComponents()!=1)
2029     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2030   if(nbTimes<1)
2031     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2032   int nbTuples=getNumberOfTuples();
2033   const double *inPtr=getConstPointer();
2034   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2035   double *retPtr=ret->getPointer();
2036   for(int i=0;i<nbTuples;i++,inPtr++)
2037     {
2038       double val=*inPtr;
2039       for(int j=0;j<nbTimes;j++,retPtr++)
2040         *retPtr=val;
2041     }
2042   ret->copyStringInfoFrom(*this);
2043   return ret.retn();
2044 }
2045
2046 /*!
2047  * This methods returns the minimal distance between the two set of points \a this and \a other.
2048  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2049  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2050  *
2051  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2052  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2053  * \return the minimal distance between the two set of points \a this and \a other.
2054  * \sa DataArrayDouble::findClosestTupleId
2055  */
2056 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2057 {
2058   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2059   int nbOfCompo(getNumberOfComponents());
2060   int otherNbTuples(other->getNumberOfTuples());
2061   const double *thisPt(begin()),*otherPt(other->begin());
2062   const int *part1Pt(part1->begin());
2063   double ret=std::numeric_limits<double>::max();
2064   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2065     {
2066       double tmp(0.);
2067       for(int j=0;j<nbOfCompo;j++)
2068         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2069       if(tmp<ret)
2070         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2071     }
2072   return sqrt(ret);
2073 }
2074
2075 /*!
2076  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2077  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2078  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2079  *
2080  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2081  * \sa DataArrayDouble::minimalDistanceTo
2082  */
2083 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2084 {
2085   if(!other)
2086     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2087   checkAllocated(); other->checkAllocated();
2088   int nbOfCompo=getNumberOfComponents();
2089   if(nbOfCompo!=other->getNumberOfComponents())
2090     {
2091       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2092       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2093       throw INTERP_KERNEL::Exception(oss.str().c_str());
2094     }
2095   int nbOfTuples=other->getNumberOfTuples();
2096   int thisNbOfTuples=getNumberOfTuples();
2097   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2098   double bounds[6];
2099   getMinMaxPerComponent(bounds);
2100   switch(nbOfCompo)
2101   {
2102     case 3:
2103       {
2104         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2105         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2106         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2107         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2108         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2109         break;
2110       }
2111     case 2:
2112       {
2113         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2114         double delta=std::max(xDelta,yDelta);
2115         double characSize=sqrt(delta/(double)thisNbOfTuples);
2116         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2117         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2118         break;
2119       }
2120     case 1:
2121       {
2122         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2123         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2124         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2125         break;
2126       }
2127     default:
2128       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2129   }
2130   return ret.retn();
2131 }
2132
2133 /*!
2134  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2135  * 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
2136  * how many bounding boxes in \a otherBBoxFrmt.
2137  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2138  *
2139  * \param [in] otherBBoxFrmt - It is an array .
2140  * \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.
2141  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2142  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2143  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2144  */
2145 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2146 {
2147   if(!otherBBoxFrmt)
2148     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2149   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2150     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2151   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2152   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2153     {
2154       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2155       throw INTERP_KERNEL::Exception(oss.str().c_str());
2156     }
2157   if(nbOfComp%2!=0)
2158     {
2159       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2160       throw INTERP_KERNEL::Exception(oss.str().c_str());
2161     }
2162   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2163   const double *thisBBPtr(begin());
2164   int *retPtr(ret->getPointer());
2165   switch(nbOfComp/2)
2166   {
2167     case 3:
2168       {
2169         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2170         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2171           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2172         break;
2173       }
2174     case 2:
2175       {
2176         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2177         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2178           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2179         break;
2180       }
2181     case 1:
2182       {
2183         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2184         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2185           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2186         break;
2187       }
2188     default:
2189       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2190   }
2191
2192   return ret.retn();
2193 }
2194
2195 /*!
2196  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2197  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2198  * space. The distance between tuples is computed using norm2. If several tuples are
2199  * not far each from other than \a prec, only one of them remains in the result
2200  * array. The order of tuples in the result array is same as in \a this one except
2201  * that coincident tuples are excluded.
2202  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2203  *              considered not coincident.
2204  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2205  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2206  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2207  *          is to delete using decrRef() as it is no more needed.
2208  *  \throw If \a this is not allocated.
2209  *  \throw If the number of components is not in [1,2,3,4].
2210  *
2211  *  \if ENABLE_EXAMPLES
2212  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2213  *  \endif
2214  */
2215 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2216 {
2217   checkAllocated();
2218   DataArrayInt *c0=0,*cI0=0;
2219   findCommonTuples(prec,limitTupleId,c0,cI0);
2220   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2221   int newNbOfTuples=-1;
2222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2223   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2224 }
2225
2226 /*!
2227  * Copy all components in a specified order from another DataArrayDouble.
2228  * Both numerical and textual data is copied. The number of tuples in \a this and
2229  * the other array can be different.
2230  *  \param [in] a - the array to copy data from.
2231  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2232  *              to be copied.
2233  *  \throw If \a a is NULL.
2234  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2235  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2236  *
2237  *  \if ENABLE_EXAMPLES
2238  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2239  *  \endif
2240  */
2241 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2242 {
2243   if(!a)
2244     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2245   checkAllocated();
2246   copyPartOfStringInfoFrom2(compoIds,*a);
2247   std::size_t partOfCompoSz=compoIds.size();
2248   int nbOfCompo=getNumberOfComponents();
2249   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2250   const double *ac=a->getConstPointer();
2251   double *nc=getPointer();
2252   for(int i=0;i<nbOfTuples;i++)
2253     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2254       nc[nbOfCompo*i+compoIds[j]]=*ac;
2255 }
2256
2257 /*!
2258  * Copy all values from another DataArrayDouble into specified tuples and components
2259  * of \a this array. Textual data is not copied.
2260  * The tree parameters defining set of indices of tuples and components are similar to
2261  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2262  *  \param [in] a - the array to copy values from.
2263  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2264  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2265  *              are located.
2266  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2267  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2268  *  \param [in] endComp - index of the component before which the components to assign
2269  *              to are located.
2270  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2271  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2272  *              must be equal to the number of columns to assign to, else an
2273  *              exception is thrown; if \a false, then it is only required that \a
2274  *              a->getNbOfElems() equals to number of values to assign to (this condition
2275  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2276  *              values to assign to is given by following Python expression:
2277  *              \a nbTargetValues = 
2278  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2279  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2280  *  \throw If \a a is NULL.
2281  *  \throw If \a a is not allocated.
2282  *  \throw If \a this is not allocated.
2283  *  \throw If parameters specifying tuples and components to assign to do not give a
2284  *            non-empty range of increasing indices.
2285  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2286  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2287  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2288  *
2289  *  \if ENABLE_EXAMPLES
2290  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2291  *  \endif
2292  */
2293 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2294 {
2295   if(!a)
2296     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2297   const char msg[]="DataArrayDouble::setPartOfValues1";
2298   checkAllocated();
2299   a->checkAllocated();
2300   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2301   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2302   int nbComp=getNumberOfComponents();
2303   int nbOfTuples=getNumberOfTuples();
2304   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2305   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2306   bool assignTech=true;
2307   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2308     {
2309       if(strictCompoCompare)
2310         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2311     }
2312   else
2313     {
2314       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2315       assignTech=false;
2316     }
2317   const double *srcPt=a->getConstPointer();
2318   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2319   if(assignTech)
2320     {
2321       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2322         for(int j=0;j<newNbOfComp;j++,srcPt++)
2323           pt[j*stepComp]=*srcPt;
2324     }
2325   else
2326     {
2327       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2328         {
2329           const double *srcPt2=srcPt;
2330           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2331             pt[j*stepComp]=*srcPt2;
2332         }
2333     }
2334 }
2335
2336 /*!
2337  * Assign a given value to values at specified tuples and components of \a this array.
2338  * The tree parameters defining set of indices of tuples and components are similar to
2339  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2340  *  \param [in] a - the value to assign.
2341  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2342  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2343  *              are located.
2344  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2345  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2346  *  \param [in] endComp - index of the component before which the components to assign
2347  *              to are located.
2348  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2349  *  \throw If \a this is not allocated.
2350  *  \throw If parameters specifying tuples and components to assign to, do not give a
2351  *            non-empty range of increasing indices or indices are out of a valid range
2352  *            for \this array.
2353  *
2354  *  \if ENABLE_EXAMPLES
2355  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2356  *  \endif
2357  */
2358 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2359 {
2360   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2361   checkAllocated();
2362   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2363   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2364   int nbComp=getNumberOfComponents();
2365   int nbOfTuples=getNumberOfTuples();
2366   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2367   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2368   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2369   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2370     for(int j=0;j<newNbOfComp;j++)
2371       pt[j*stepComp]=a;
2372 }
2373
2374 /*!
2375  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2376  * components of \a this array. Textual data is not copied.
2377  * The tuples and components to assign to are defined by C arrays of indices.
2378  * There are two *modes of usage*:
2379  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2380  *   of \a a is assigned to its own location within \a this array. 
2381  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2382  *   components of every specified tuple of \a this array. In this mode it is required
2383  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2384  *
2385  *  \param [in] a - the array to copy values from.
2386  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2387  *              assign values of \a a to.
2388  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2389  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2390  *              \a bgTuples <= \a pi < \a endTuples.
2391  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2392  *              assign values of \a a to.
2393  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2394  *              pointer to a component index <em>(pi)</em> varies as this: 
2395  *              \a bgComp <= \a pi < \a endComp.
2396  *  \param [in] strictCompoCompare - this parameter is checked only if the
2397  *               *mode of usage* is the first; if it is \a true (default), 
2398  *               then \a a->getNumberOfComponents() must be equal 
2399  *               to the number of specified columns, else this is not required.
2400  *  \throw If \a a is NULL.
2401  *  \throw If \a a is not allocated.
2402  *  \throw If \a this is not allocated.
2403  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2404  *         out of a valid range for \a this array.
2405  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2406  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2407  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2408  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2409  *
2410  *  \if ENABLE_EXAMPLES
2411  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2412  *  \endif
2413  */
2414 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2415 {
2416   if(!a)
2417     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2418   const char msg[]="DataArrayDouble::setPartOfValues2";
2419   checkAllocated();
2420   a->checkAllocated();
2421   int nbComp=getNumberOfComponents();
2422   int nbOfTuples=getNumberOfTuples();
2423   for(const int *z=bgComp;z!=endComp;z++)
2424     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2425   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2426   int newNbOfComp=(int)std::distance(bgComp,endComp);
2427   bool assignTech=true;
2428   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2429     {
2430       if(strictCompoCompare)
2431         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2432     }
2433   else
2434     {
2435       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2436       assignTech=false;
2437     }
2438   double *pt=getPointer();
2439   const double *srcPt=a->getConstPointer();
2440   if(assignTech)
2441     {    
2442       for(const int *w=bgTuples;w!=endTuples;w++)
2443         {
2444           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2445           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2446             {    
2447               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2448             }
2449         }
2450     }
2451   else
2452     {
2453       for(const int *w=bgTuples;w!=endTuples;w++)
2454         {
2455           const double *srcPt2=srcPt;
2456           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2457           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2458             {    
2459               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2460             }
2461         }
2462     }
2463 }
2464
2465 /*!
2466  * Assign a given value to values at specified tuples and components of \a this array.
2467  * The tuples and components to assign to are defined by C arrays of indices.
2468  *  \param [in] a - the value to assign.
2469  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2470  *              assign \a a to.
2471  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2472  *              pointer to a tuple index (\a pi) varies as this: 
2473  *              \a bgTuples <= \a pi < \a endTuples.
2474  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2475  *              assign \a a to.
2476  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2477  *              pointer to a component index (\a pi) varies as this: 
2478  *              \a bgComp <= \a pi < \a endComp.
2479  *  \throw If \a this is not allocated.
2480  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2481  *         out of a valid range for \a this array.
2482  *
2483  *  \if ENABLE_EXAMPLES
2484  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2485  *  \endif
2486  */
2487 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2488 {
2489   checkAllocated();
2490   int nbComp=getNumberOfComponents();
2491   int nbOfTuples=getNumberOfTuples();
2492   for(const int *z=bgComp;z!=endComp;z++)
2493     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2494   double *pt=getPointer();
2495   for(const int *w=bgTuples;w!=endTuples;w++)
2496     for(const int *z=bgComp;z!=endComp;z++)
2497       {
2498         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2499         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2500       }
2501 }
2502
2503 /*!
2504  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2505  * components of \a this array. Textual data is not copied.
2506  * The tuples to assign to are defined by a C array of indices.
2507  * The components to assign to are defined by three values similar to parameters of
2508  * the Python function \c range(\c start,\c stop,\c step).
2509  * There are two *modes of usage*:
2510  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2511  *   of \a a is assigned to its own location within \a this array. 
2512  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2513  *   components of every specified tuple of \a this array. In this mode it is required
2514  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2515  *
2516  *  \param [in] a - the array to copy values from.
2517  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2518  *              assign values of \a a to.
2519  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2520  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2521  *              \a bgTuples <= \a pi < \a endTuples.
2522  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2523  *  \param [in] endComp - index of the component before which the components to assign
2524  *              to are located.
2525  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2526  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2527  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2528  *               then \a a->getNumberOfComponents() must be equal 
2529  *               to the number of specified columns, else this is not required.
2530  *  \throw If \a a is NULL.
2531  *  \throw If \a a is not allocated.
2532  *  \throw If \a this is not allocated.
2533  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2534  *         \a this array.
2535  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2536  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2537  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2538  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2539  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2540  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2541  *  \throw If parameters specifying components to assign to, do not give a
2542  *            non-empty range of increasing indices or indices are out of a valid range
2543  *            for \this array.
2544  *
2545  *  \if ENABLE_EXAMPLES
2546  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2547  *  \endif
2548  */
2549 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2550 {
2551   if(!a)
2552     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2553   const char msg[]="DataArrayDouble::setPartOfValues3";
2554   checkAllocated();
2555   a->checkAllocated();
2556   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2557   int nbComp=getNumberOfComponents();
2558   int nbOfTuples=getNumberOfTuples();
2559   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2560   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2561   bool assignTech=true;
2562   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2563     {
2564       if(strictCompoCompare)
2565         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2566     }
2567   else
2568     {
2569       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2570       assignTech=false;
2571     }
2572   double *pt=getPointer()+bgComp;
2573   const double *srcPt=a->getConstPointer();
2574   if(assignTech)
2575     {
2576       for(const int *w=bgTuples;w!=endTuples;w++)
2577         for(int j=0;j<newNbOfComp;j++,srcPt++)
2578           {
2579             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2580             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2581           }
2582     }
2583   else
2584     {
2585       for(const int *w=bgTuples;w!=endTuples;w++)
2586         {
2587           const double *srcPt2=srcPt;
2588           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2589             {
2590               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2591               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2592             }
2593         }
2594     }
2595 }
2596
2597 /*!
2598  * Assign a given value to values at specified tuples and components of \a this array.
2599  * The tuples to assign to are defined by a C array of indices.
2600  * The components to assign to are defined by three values similar to parameters of
2601  * the Python function \c range(\c start,\c stop,\c step).
2602  *  \param [in] a - the value to assign.
2603  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2604  *              assign \a a to.
2605  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2606  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2607  *              \a bgTuples <= \a pi < \a endTuples.
2608  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2609  *  \param [in] endComp - index of the component before which the components to assign
2610  *              to are located.
2611  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2612  *  \throw If \a this is not allocated.
2613  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2614  *         \a this array.
2615  *  \throw If parameters specifying components to assign to, do not give a
2616  *            non-empty range of increasing indices or indices are out of a valid range
2617  *            for \this array.
2618  *
2619  *  \if ENABLE_EXAMPLES
2620  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2621  *  \endif
2622  */
2623 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2624 {
2625   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2626   checkAllocated();
2627   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2628   int nbComp=getNumberOfComponents();
2629   int nbOfTuples=getNumberOfTuples();
2630   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2631   double *pt=getPointer()+bgComp;
2632   for(const int *w=bgTuples;w!=endTuples;w++)
2633     for(int j=0;j<newNbOfComp;j++)
2634       {
2635         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2636         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2637       }
2638 }
2639
2640 /*!
2641  * Copy all values from another DataArrayDouble into specified tuples and components
2642  * of \a this array. Textual data is not copied.
2643  * The tree parameters defining set of indices of tuples and components are similar to
2644  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2645  *  \param [in] a - the array to copy values from.
2646  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2647  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2648  *              are located.
2649  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2650  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2651  *              assign \a a to.
2652  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2653  *              pointer to a component index (\a pi) varies as this: 
2654  *              \a bgComp <= \a pi < \a endComp.
2655  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2656  *              must be equal to the number of columns to assign to, else an
2657  *              exception is thrown; if \a false, then it is only required that \a
2658  *              a->getNbOfElems() equals to number of values to assign to (this condition
2659  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2660  *              values to assign to is given by following Python expression:
2661  *              \a nbTargetValues = 
2662  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2663  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2664  *  \throw If \a a is NULL.
2665  *  \throw If \a a is not allocated.
2666  *  \throw If \a this is not allocated.
2667  *  \throw If parameters specifying tuples and components to assign to do not give a
2668  *            non-empty range of increasing indices.
2669  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2670  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2671  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2672  *
2673  */
2674 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2675 {
2676   if(!a)
2677     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2678   const char msg[]="DataArrayDouble::setPartOfValues4";
2679   checkAllocated();
2680   a->checkAllocated();
2681   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2682   int newNbOfComp=(int)std::distance(bgComp,endComp);
2683   int nbComp=getNumberOfComponents();
2684   for(const int *z=bgComp;z!=endComp;z++)
2685     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2686   int nbOfTuples=getNumberOfTuples();
2687   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2688   bool assignTech=true;
2689   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2690     {
2691       if(strictCompoCompare)
2692         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2693     }
2694   else
2695     {
2696       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2697       assignTech=false;
2698     }
2699   const double *srcPt=a->getConstPointer();
2700   double *pt=getPointer()+bgTuples*nbComp;
2701   if(assignTech)
2702     {
2703       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2704         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2705           pt[*z]=*srcPt;
2706     }
2707   else
2708     {
2709       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2710         {
2711           const double *srcPt2=srcPt;
2712           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2713             pt[*z]=*srcPt2;
2714         }
2715     }
2716 }
2717
2718 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2719 {
2720   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2721   checkAllocated();
2722   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2723   int nbComp=getNumberOfComponents();
2724   for(const int *z=bgComp;z!=endComp;z++)
2725     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2726   int nbOfTuples=getNumberOfTuples();
2727   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2728   double *pt=getPointer()+bgTuples*nbComp;
2729   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2730     for(const int *z=bgComp;z!=endComp;z++)
2731       pt[*z]=a;
2732 }
2733
2734 /*!
2735  * Copy some tuples from another DataArrayDouble into specified tuples
2736  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2737  * components.
2738  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2739  * All components of selected tuples are copied.
2740  *  \param [in] a - the array to copy values from.
2741  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2742  *              target tuples of \a this. \a tuplesSelec has two components, and the
2743  *              first component specifies index of the source tuple and the second
2744  *              one specifies index of the target tuple.
2745  *  \throw If \a this is not allocated.
2746  *  \throw If \a a is NULL.
2747  *  \throw If \a a is not allocated.
2748  *  \throw If \a tuplesSelec is NULL.
2749  *  \throw If \a tuplesSelec is not allocated.
2750  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2751  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2752  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2753  *         the corresponding (\a this or \a a) array.
2754  */
2755 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2756 {
2757   if(!a || !tuplesSelec)
2758     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2759   checkAllocated();
2760   a->checkAllocated();
2761   tuplesSelec->checkAllocated();
2762   int nbOfComp=getNumberOfComponents();
2763   if(nbOfComp!=a->getNumberOfComponents())
2764     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2765   if(tuplesSelec->getNumberOfComponents()!=2)
2766     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2767   int thisNt=getNumberOfTuples();
2768   int aNt=a->getNumberOfTuples();
2769   double *valsToSet=getPointer();
2770   const double *valsSrc=a->getConstPointer();
2771   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2772     {
2773       if(tuple[1]>=0 && tuple[1]<aNt)
2774         {
2775           if(tuple[0]>=0 && tuple[0]<thisNt)
2776             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2777           else
2778             {
2779               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2780               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2781               throw INTERP_KERNEL::Exception(oss.str().c_str());
2782             }
2783         }
2784       else
2785         {
2786           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2787           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2788           throw INTERP_KERNEL::Exception(oss.str().c_str());
2789         }
2790     }
2791 }
2792
2793 /*!
2794  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2795  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2796  * components.
2797  * The tuples to assign to are defined by index of the first tuple, and
2798  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2799  * The tuples to copy are defined by values of a DataArrayInt.
2800  * All components of selected tuples are copied.
2801  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2802  *              values to.
2803  *  \param [in] aBase - the array to copy values from.
2804  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2805  *  \throw If \a this is not allocated.
2806  *  \throw If \a aBase is NULL.
2807  *  \throw If \a aBase is not allocated.
2808  *  \throw If \a tuplesSelec is NULL.
2809  *  \throw If \a tuplesSelec is not allocated.
2810  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2811  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2812  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2813  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2814  *         \a aBase array.
2815  */
2816 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2817 {
2818   if(!aBase || !tuplesSelec)
2819     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2820   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2821   if(!a)
2822     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2823   checkAllocated();
2824   a->checkAllocated();
2825   tuplesSelec->checkAllocated();
2826   int nbOfComp=getNumberOfComponents();
2827   if(nbOfComp!=a->getNumberOfComponents())
2828     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2829   if(tuplesSelec->getNumberOfComponents()!=1)
2830     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2831   int thisNt=getNumberOfTuples();
2832   int aNt=a->getNumberOfTuples();
2833   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2834   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2835   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2836     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2837   const double *valsSrc=a->getConstPointer();
2838   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2839     {
2840       if(*tuple>=0 && *tuple<aNt)
2841         {
2842           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2843         }
2844       else
2845         {
2846           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2847           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2848           throw INTERP_KERNEL::Exception(oss.str().c_str());
2849         }
2850     }
2851 }
2852
2853 /*!
2854  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2855  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2856  * components.
2857  * The tuples to copy are defined by three values similar to parameters of
2858  * the Python function \c range(\c start,\c stop,\c step).
2859  * The tuples to assign to are defined by index of the first tuple, and
2860  * their number is defined by number of tuples to copy.
2861  * All components of selected tuples are copied.
2862  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2863  *              values to.
2864  *  \param [in] aBase - the array to copy values from.
2865  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2866  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2867  *              are located.
2868  *  \param [in] step - index increment to get index of the next tuple to copy.
2869  *  \throw If \a this is not allocated.
2870  *  \throw If \a aBase is NULL.
2871  *  \throw If \a aBase is not allocated.
2872  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2873  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2874  *  \throw If parameters specifying tuples to copy, do not give a
2875  *            non-empty range of increasing indices or indices are out of a valid range
2876  *            for the array \a aBase.
2877  */
2878 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2879 {
2880   if(!aBase)
2881     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2882   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2883   if(!a)
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2885   checkAllocated();
2886   a->checkAllocated();
2887   int nbOfComp=getNumberOfComponents();
2888   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2889   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2890   if(nbOfComp!=a->getNumberOfComponents())
2891     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2892   int thisNt=getNumberOfTuples();
2893   int aNt=a->getNumberOfTuples();
2894   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2895   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2896     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2897   if(end2>aNt)
2898     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2899   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2900   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2901     {
2902       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2903     }
2904 }
2905
2906 /*!
2907  * Returns a value located at specified tuple and component.
2908  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2909  * parameters is checked. So this method is safe but expensive if used to go through
2910  * all values of \a this.
2911  *  \param [in] tupleId - index of tuple of interest.
2912  *  \param [in] compoId - index of component of interest.
2913  *  \return double - value located by \a tupleId and \a compoId.
2914  *  \throw If \a this is not allocated.
2915  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2916  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2917  */
2918 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2919 {
2920   checkAllocated();
2921   if(tupleId<0 || tupleId>=getNumberOfTuples())
2922     {
2923       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2924       throw INTERP_KERNEL::Exception(oss.str().c_str());
2925     }
2926   if(compoId<0 || compoId>=getNumberOfComponents())
2927     {
2928       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2929       throw INTERP_KERNEL::Exception(oss.str().c_str());
2930     }
2931   return _mem[tupleId*_info_on_compo.size()+compoId];
2932 }
2933
2934 /*!
2935  * Returns the first value of \a this. 
2936  *  \return double - the last value of \a this array.
2937  *  \throw If \a this is not allocated.
2938  *  \throw If \a this->getNumberOfComponents() != 1.
2939  *  \throw If \a this->getNumberOfTuples() < 1.
2940  */
2941 double DataArrayDouble::front() const
2942 {
2943   checkAllocated();
2944   if(getNumberOfComponents()!=1)
2945     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2946   int nbOfTuples=getNumberOfTuples();
2947   if(nbOfTuples<1)
2948     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2949   return *(getConstPointer());
2950 }
2951
2952 /*!
2953  * Returns the last value of \a this. 
2954  *  \return double - the last value of \a this array.
2955  *  \throw If \a this is not allocated.
2956  *  \throw If \a this->getNumberOfComponents() != 1.
2957  *  \throw If \a this->getNumberOfTuples() < 1.
2958  */
2959 double DataArrayDouble::back() const
2960 {
2961   checkAllocated();
2962   if(getNumberOfComponents()!=1)
2963     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2964   int nbOfTuples=getNumberOfTuples();
2965   if(nbOfTuples<1)
2966     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2967   return *(getConstPointer()+nbOfTuples-1);
2968 }
2969
2970 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2971 {
2972   if(newArray!=arrayToSet)
2973     {
2974       if(arrayToSet)
2975         arrayToSet->decrRef();
2976       arrayToSet=newArray;
2977       if(arrayToSet)
2978         arrayToSet->incrRef();
2979     }
2980 }
2981
2982 /*!
2983  * Sets a C array to be used as raw data of \a this. The previously set info
2984  *  of components is retained and re-sized. 
2985  * For more info see \ref MEDCouplingArraySteps1.
2986  *  \param [in] array - the C array to be used as raw data of \a this.
2987  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2988  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2989  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2990  *                     \c free(\c array ) will be called.
2991  *  \param [in] nbOfTuple - new number of tuples in \a this.
2992  *  \param [in] nbOfCompo - new number of components in \a this.
2993  */
2994 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2995 {
2996   _info_on_compo.resize(nbOfCompo);
2997   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2998   declareAsNew();
2999 }
3000
3001 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3002 {
3003   _info_on_compo.resize(nbOfCompo);
3004   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3005   declareAsNew();
3006 }
3007
3008 /*!
3009  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3010  * is thrown.
3011  * \throw If zero is found in \a this array.
3012  */
3013 void DataArrayDouble::checkNoNullValues() const
3014 {
3015   const double *tmp=getConstPointer();
3016   std::size_t nbOfElems=getNbOfElems();
3017   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3018   if(where!=tmp+nbOfElems)
3019     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3020 }
3021
3022 /*!
3023  * Computes minimal and maximal value in each component. An output array is filled
3024  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3025  * enough memory before calling this method.
3026  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3027  *               It is filled as follows:<br>
3028  *               \a bounds[0] = \c min_of_component_0 <br>
3029  *               \a bounds[1] = \c max_of_component_0 <br>
3030  *               \a bounds[2] = \c min_of_component_1 <br>
3031  *               \a bounds[3] = \c max_of_component_1 <br>
3032  *               ...
3033  */
3034 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3035 {
3036   checkAllocated();
3037   int dim=getNumberOfComponents();
3038   for (int idim=0; idim<dim; idim++)
3039     {
3040       bounds[idim*2]=std::numeric_limits<double>::max();
3041       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3042     } 
3043   const double *ptr=getConstPointer();
3044   int nbOfTuples=getNumberOfTuples();
3045   for(int i=0;i<nbOfTuples;i++)
3046     {
3047       for(int idim=0;idim<dim;idim++)
3048         {
3049           if(bounds[idim*2]>ptr[i*dim+idim])
3050             {
3051               bounds[idim*2]=ptr[i*dim+idim];
3052             }
3053           if(bounds[idim*2+1]<ptr[i*dim+idim])
3054             {
3055               bounds[idim*2+1]=ptr[i*dim+idim];
3056             }
3057         }
3058     }
3059 }
3060
3061 /*!
3062  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3063  * to store both the min and max per component of each tuples. 
3064  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3065  *
3066  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3067  *
3068  * \throw If \a this is not allocated yet.
3069  */
3070 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3071 {
3072   checkAllocated();
3073   const double *dataPtr=getConstPointer();
3074   int nbOfCompo=getNumberOfComponents();
3075   int nbTuples=getNumberOfTuples();
3076   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3077   bbox->alloc(nbTuples,2*nbOfCompo);
3078   double *bboxPtr=bbox->getPointer();
3079   for(int i=0;i<nbTuples;i++)
3080     {
3081       for(int j=0;j<nbOfCompo;j++)
3082         {
3083           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3084           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3085         }
3086     }
3087   return bbox.retn();
3088 }
3089
3090 /*!
3091  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3092  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3093  * 
3094  * \param [in] other a DataArrayDouble having same number of components than \a this.
3095  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3096  * \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.
3097  *             \a cI allows to extract information in \a c.
3098  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3099  *
3100  * \throw In case of:
3101  *  - \a this is not allocated
3102  *  - \a other is not allocated or null
3103  *  - \a this and \a other do not have the same number of components
3104  *  - if number of components of \a this is not in [1,2,3]
3105  *
3106  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3107  */
3108 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3109 {
3110   if(!other)
3111     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3112   checkAllocated();
3113   other->checkAllocated();
3114   int nbOfCompo=getNumberOfComponents();
3115   int otherNbOfCompo=other->getNumberOfComponents();
3116   if(nbOfCompo!=otherNbOfCompo)
3117     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3118   int nbOfTuplesOther=other->getNumberOfTuples();
3119   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3120   switch(nbOfCompo)
3121   {
3122     case 3:
3123       {
3124         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3125         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3126         break;
3127       }
3128     case 2:
3129       {
3130         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3131         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3132         break;
3133       }
3134     case 1:
3135       {
3136         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3137         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3138         break;
3139       }
3140     default:
3141       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3142   }
3143   c=cArr.retn(); cI=cIArr.retn();
3144 }
3145
3146 /*!
3147  * 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
3148  * around origin of 'radius' 1.
3149  * 
3150  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3151  */
3152 void DataArrayDouble::recenterForMaxPrecision(double eps)
3153 {
3154   checkAllocated();
3155   int dim=getNumberOfComponents();
3156   std::vector<double> bounds(2*dim);
3157   getMinMaxPerComponent(&bounds[0]);
3158   for(int i=0;i<dim;i++)
3159     {
3160       double delta=bounds[2*i+1]-bounds[2*i];
3161       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3162       if(delta>eps)
3163         applyLin(1./delta,-offset/delta,i);
3164       else
3165         applyLin(1.,-offset,i);
3166     }
3167 }
3168
3169 /*!
3170  * Returns the maximal value and its location within \a this one-dimensional array.
3171  *  \param [out] tupleId - index of the tuple holding the maximal value.
3172  *  \return double - the maximal value among all values of \a this array.
3173  *  \throw If \a this->getNumberOfComponents() != 1
3174  *  \throw If \a this->getNumberOfTuples() < 1
3175  */
3176 double DataArrayDouble::getMaxValue(int& tupleId) const
3177 {
3178   checkAllocated();
3179   if(getNumberOfComponents()!=1)
3180     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 !");
3181   int nbOfTuples=getNumberOfTuples();
3182   if(nbOfTuples<=0)
3183     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3184   const double *vals=getConstPointer();
3185   const double *loc=std::max_element(vals,vals+nbOfTuples);
3186   tupleId=(int)std::distance(vals,loc);
3187   return *loc;
3188 }
3189
3190 /*!
3191  * Returns the maximal value within \a this array that is allowed to have more than
3192  *  one component.
3193  *  \return double - the maximal value among all values of \a this array.
3194  *  \throw If \a this is not allocated.
3195  */
3196 double DataArrayDouble::getMaxValueInArray() const
3197 {
3198   checkAllocated();
3199   const double *loc=std::max_element(begin(),end());
3200   return *loc;
3201 }
3202
3203 /*!
3204  * Returns the maximal value and all its locations within \a this one-dimensional array.
3205  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3206  *               tuples holding the maximal value. The caller is to delete it using
3207  *               decrRef() as it is no more needed.
3208  *  \return double - the maximal value among all values of \a this array.
3209  *  \throw If \a this->getNumberOfComponents() != 1
3210  *  \throw If \a this->getNumberOfTuples() < 1
3211  */
3212 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3213 {
3214   int tmp;
3215   tupleIds=0;
3216   double ret=getMaxValue(tmp);
3217   tupleIds=getIdsInRange(ret,ret);
3218   return ret;
3219 }
3220
3221 /*!
3222  * Returns the minimal value and its location within \a this one-dimensional array.
3223  *  \param [out] tupleId - index of the tuple holding the minimal value.
3224  *  \return double - the minimal value among all values of \a this array.
3225  *  \throw If \a this->getNumberOfComponents() != 1
3226  *  \throw If \a this->getNumberOfTuples() < 1
3227  */
3228 double DataArrayDouble::getMinValue(int& tupleId) const
3229 {
3230   checkAllocated();
3231   if(getNumberOfComponents()!=1)
3232     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3233   int nbOfTuples=getNumberOfTuples();
3234   if(nbOfTuples<=0)
3235     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3236   const double *vals=getConstPointer();
3237   const double *loc=std::min_element(vals,vals+nbOfTuples);
3238   tupleId=(int)std::distance(vals,loc);
3239   return *loc;
3240 }
3241
3242 /*!
3243  * Returns the minimal value within \a this array that is allowed to have more than
3244  *  one component.
3245  *  \return double - the minimal value among all values of \a this array.
3246  *  \throw If \a this is not allocated.
3247  */
3248 double DataArrayDouble::getMinValueInArray() const
3249 {
3250   checkAllocated();
3251   const double *loc=std::min_element(begin(),end());
3252   return *loc;
3253 }
3254
3255 /*!
3256  * Returns the minimal value and all its locations within \a this one-dimensional array.
3257  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3258  *               tuples holding the minimal value. The caller is to delete it using
3259  *               decrRef() as it is no more needed.
3260  *  \return double - the minimal value among all values of \a this array.
3261  *  \throw If \a this->getNumberOfComponents() != 1
3262  *  \throw If \a this->getNumberOfTuples() < 1
3263  */
3264 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3265 {
3266   int tmp;
3267   tupleIds=0;
3268   double ret=getMinValue(tmp);
3269   tupleIds=getIdsInRange(ret,ret);
3270   return ret;
3271 }
3272
3273 /*!
3274  * 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.
3275  * This method only works for single component array.
3276  *
3277  * \return a value in [ 0, \c this->getNumberOfTuples() )
3278  *
3279  * \throw If \a this is not allocated
3280  *
3281  */
3282 int DataArrayDouble::count(double value, double eps) const
3283 {
3284   int ret=0;
3285   checkAllocated();
3286   if(getNumberOfComponents()!=1)
3287     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3288   const double *vals=begin();
3289   int nbOfTuples=getNumberOfTuples();
3290   for(int i=0;i<nbOfTuples;i++,vals++)
3291     if(fabs(*vals-value)<=eps)
3292       ret++;
3293   return ret;
3294 }
3295
3296 /*!
3297  * Returns the average value of \a this one-dimensional array.
3298  *  \return double - the average value over all values of \a this array.
3299  *  \throw If \a this->getNumberOfComponents() != 1
3300  *  \throw If \a this->getNumberOfTuples() < 1
3301  */
3302 double DataArrayDouble::getAverageValue() const
3303 {
3304   if(getNumberOfComponents()!=1)
3305     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3306   int nbOfTuples=getNumberOfTuples();
3307   if(nbOfTuples<=0)
3308     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3309   const double *vals=getConstPointer();
3310   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3311   return ret/nbOfTuples;
3312 }
3313
3314 /*!
3315  * Returns the Euclidean norm of the vector defined by \a this array.
3316  *  \return double - the value of the Euclidean norm, i.e.
3317  *          the square root of the inner product of vector.
3318  *  \throw If \a this is not allocated.
3319  */
3320 double DataArrayDouble::norm2() const
3321 {
3322   checkAllocated();
3323   double ret=0.;
3324   std::size_t nbOfElems=getNbOfElems();
3325   const double *pt=getConstPointer();
3326   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3327     ret+=(*pt)*(*pt);
3328   return sqrt(ret);
3329 }
3330
3331 /*!
3332  * Returns the maximum norm of the vector defined by \a this array.
3333  * This method works even if the number of components is diferent from one.
3334  * If the number of elements in \a this is 0, -1. is returned.
3335  *  \return double - the value of the maximum norm, i.e.
3336  *          the maximal absolute value among values of \a this array (whatever its number of components).
3337  *  \throw If \a this is not allocated.
3338  */
3339 double DataArrayDouble::normMax() const
3340 {
3341   checkAllocated();
3342   double ret(-1.);
3343   std::size_t nbOfElems(getNbOfElems());
3344   const double *pt(getConstPointer());
3345   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3346     {
3347       double val(std::abs(*pt));
3348       if(val>ret)
3349         ret=val;
3350     }
3351   return ret;
3352 }
3353
3354 /*!
3355  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3356  * This method works even if the number of components is diferent from one.
3357  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3358  *  \return double - the value of the minimum norm, i.e.
3359  *          the minimal absolute value among values of \a this array (whatever its number of components).
3360  *  \throw If \a this is not allocated.
3361  */
3362 double DataArrayDouble::normMin() const
3363 {
3364   checkAllocated();
3365   double ret(std::numeric_limits<double>::max());
3366   std::size_t nbOfElems(getNbOfElems());
3367   const double *pt(getConstPointer());
3368   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3369     {
3370       double val(std::abs(*pt));
3371       if(val<ret)
3372         ret=val;
3373     }
3374   return ret;
3375 }
3376
3377 /*!
3378  * Accumulates values of each component of \a this array.
3379  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3380  *         by the caller, that is filled by this method with sum value for each
3381  *         component.
3382  *  \throw If \a this is not allocated.
3383  */
3384 void DataArrayDouble::accumulate(double *res) const
3385 {
3386   checkAllocated();
3387   const double *ptr=getConstPointer();
3388   int nbTuple=getNumberOfTuples();
3389   int nbComps=getNumberOfComponents();
3390   std::fill(res,res+nbComps,0.);
3391   for(int i=0;i<nbTuple;i++)
3392     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3393 }
3394
3395 /*!
3396  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3397  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3398  *
3399  *
3400  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3401  * \a tupleEnd. If not an exception will be thrown.
3402  *
3403  * \param [in] tupleBg start pointer (included) of input external tuple
3404  * \param [in] tupleEnd end pointer (not included) of input external tuple
3405  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3406  * \return the min distance.
3407  * \sa MEDCouplingUMesh::distanceToPoint
3408  */
3409 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3410 {
3411   checkAllocated();
3412   int nbTuple=getNumberOfTuples();
3413   int nbComps=getNumberOfComponents();
3414   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3415     { 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()); }
3416   if(nbTuple==0)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3418   double ret0=std::numeric_limits<double>::max();
3419   tupleId=-1;
3420   const double *work=getConstPointer();
3421   for(int i=0;i<nbTuple;i++)
3422     {
3423       double val=0.;
3424       for(int j=0;j<nbComps;j++,work++) 
3425         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3426       if(val>=ret0)
3427         continue;
3428       else
3429         { ret0=val; tupleId=i; }
3430     }
3431   return sqrt(ret0);
3432 }
3433
3434 /*!
3435  * Accumulate values of the given component of \a this array.
3436  *  \param [in] compId - the index of the component of interest.
3437  *  \return double - a sum value of \a compId-th component.
3438  *  \throw If \a this is not allocated.
3439  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3440  *         not respected.
3441  */
3442 double DataArrayDouble::accumulate(int compId) const
3443 {
3444   checkAllocated();
3445   const double *ptr=getConstPointer();
3446   int nbTuple=getNumberOfTuples();
3447   int nbComps=getNumberOfComponents();
3448   if(compId<0 || compId>=nbComps)
3449     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3450   double ret=0.;
3451   for(int i=0;i<nbTuple;i++)
3452     ret+=ptr[i*nbComps+compId];
3453   return ret;
3454 }
3455
3456 /*!
3457  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3458  * The returned array will have same number of components than \a this and number of tuples equal to
3459  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3460  *
3461  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3462  * 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.
3463  *
3464  * \param [in] bgOfIndex - begin (included) of the input index array.
3465  * \param [in] endOfIndex - end (excluded) of the input index array.
3466  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3467  * 
3468  * \throw If bgOfIndex or end is NULL.
3469  * \throw If input index array is not ascendingly sorted.
3470  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3471  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3472  */
3473 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3474 {
3475   if(!bgOfIndex || !endOfIndex)
3476     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3477   checkAllocated();
3478   int nbCompo=getNumberOfComponents();
3479   int nbOfTuples=getNumberOfTuples();
3480   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3481   if(sz<1)
3482     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3483   sz--;
3484   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3485   const int *w=bgOfIndex;
3486   if(*w<0 || *w>=nbOfTuples)
3487     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3488   const double *srcPt=begin()+(*w)*nbCompo;
3489   double *tmp=ret->getPointer();
3490   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3491     {
3492       std::fill(tmp,tmp+nbCompo,0.);
3493       if(w[1]>=w[0])
3494         {
3495           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3496             {
3497               if(j>=0 && j<nbOfTuples)
3498                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3499               else
3500                 {
3501                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3502                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3503                 }
3504             }
3505         }
3506       else
3507         {
3508           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3509           throw INTERP_KERNEL::Exception(oss.str().c_str());
3510         }
3511     }
3512   ret->copyStringInfoFrom(*this);
3513   return ret.retn();
3514 }
3515
3516 /*!
3517  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3518  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3519  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3520  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3521  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3522  *          is to delete this array using decrRef() as it is no more needed. The array
3523  *          does not contain any textual info on components.
3524  *  \throw If \a this->getNumberOfComponents() != 2.
3525  */
3526 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3527 {
3528   checkAllocated();
3529   int nbOfComp=getNumberOfComponents();
3530   if(nbOfComp!=2)
3531     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3532   int nbOfTuple=getNumberOfTuples();
3533   DataArrayDouble *ret=DataArrayDouble::New();
3534   ret->alloc(nbOfTuple,2);
3535   double *w=ret->getPointer();
3536   const double *wIn=getConstPointer();
3537   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3538     {
3539       w[0]=wIn[0]*cos(wIn[1]);
3540       w[1]=wIn[0]*sin(wIn[1]);
3541     }
3542   return ret;
3543 }
3544
3545 /*!
3546  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3547  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3548  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3549  * the Cylindrical CS.
3550  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3551  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3552  *          on the third component is copied from \a this array. The caller
3553  *          is to delete this array using decrRef() as it is no more needed. 
3554  *  \throw If \a this->getNumberOfComponents() != 3.
3555  */
3556 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3557 {
3558   checkAllocated();
3559   int nbOfComp=getNumberOfComponents();
3560   if(nbOfComp!=3)
3561     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3562   int nbOfTuple=getNumberOfTuples();
3563   DataArrayDouble *ret=DataArrayDouble::New();
3564   ret->alloc(getNumberOfTuples(),3);
3565   double *w=ret->getPointer();
3566   const double *wIn=getConstPointer();
3567   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3568     {
3569       w[0]=wIn[0]*cos(wIn[1]);
3570       w[1]=wIn[0]*sin(wIn[1]);
3571       w[2]=wIn[2];
3572     }
3573   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3574   return ret;
3575 }
3576
3577 /*!
3578  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3579  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3580  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3581  * point in the Cylindrical CS.
3582  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3583  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3584  *          on the third component is copied from \a this array. The caller
3585  *          is to delete this array using decrRef() as it is no more needed.
3586  *  \throw If \a this->getNumberOfComponents() != 3.
3587  */
3588 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3589 {
3590   checkAllocated();
3591   int nbOfComp=getNumberOfComponents();
3592   if(nbOfComp!=3)
3593     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3594   int nbOfTuple=getNumberOfTuples();
3595   DataArrayDouble *ret=DataArrayDouble::New();
3596   ret->alloc(getNumberOfTuples(),3);
3597   double *w=ret->getPointer();
3598   const double *wIn=getConstPointer();
3599   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3600     {
3601       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3602       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3603       w[2]=wIn[0]*cos(wIn[1]);
3604     }
3605   return ret;
3606 }
3607
3608 /*!
3609  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3610  * array contating 6 components.
3611  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3612  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3613  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3614  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3615  *  \throw If \a this->getNumberOfComponents() != 6.
3616  */
3617 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3618 {
3619   checkAllocated();
3620   int nbOfComp=getNumberOfComponents();
3621   if(nbOfComp!=6)
3622     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3623   DataArrayDouble *ret=DataArrayDouble::New();
3624   int nbOfTuple=getNumberOfTuples();
3625   ret->alloc(nbOfTuple,1);
3626   const double *src=getConstPointer();
3627   double *dest=ret->getPointer();
3628   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3629     *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];
3630   return ret;
3631 }
3632
3633 /*!
3634  * Computes the determinant of every square matrix defined by the tuple of \a this
3635  * array, which contains either 4, 6 or 9 components. The case of 6 components
3636  * corresponds to that of the upper triangular matrix.
3637  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3638  *          is the determinant of matrix of the corresponding tuple of \a this array.
3639  *          The caller is to delete this result array using decrRef() as it is no more
3640  *          needed. 
3641  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3642  */
3643 DataArrayDouble *DataArrayDouble::determinant() const
3644 {
3645   checkAllocated();
3646   DataArrayDouble *ret=DataArrayDouble::New();
3647   int nbOfTuple=getNumberOfTuples();
3648   ret->alloc(nbOfTuple,1);
3649   const double *src=getConstPointer();
3650   double *dest=ret->getPointer();
3651   switch(getNumberOfComponents())
3652   {
3653     case 6:
3654       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3655         *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];
3656       return ret;
3657     case 4:
3658       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3659         *dest=src[0]*src[3]-src[1]*src[2];
3660       return ret;
3661     case 9:
3662       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3663         *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];
3664       return ret;
3665     default:
3666       ret->decrRef();
3667       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3668   }
3669 }
3670
3671 /*!
3672  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3673  * \a this array, which contains 6 components.
3674  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3675  *          components, whose each tuple contains the eigenvalues of the matrix of
3676  *          corresponding tuple of \a this array. 
3677  *          The caller is to delete this result array using decrRef() as it is no more
3678  *          needed. 
3679  *  \throw If \a this->getNumberOfComponents() != 6.
3680  */
3681 DataArrayDouble *DataArrayDouble::eigenValues() const
3682 {
3683   checkAllocated();
3684   int nbOfComp=getNumberOfComponents();
3685   if(nbOfComp!=6)
3686     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3687   DataArrayDouble *ret=DataArrayDouble::New();
3688   int nbOfTuple=getNumberOfTuples();
3689   ret->alloc(nbOfTuple,3);
3690   const double *src=getConstPointer();
3691   double *dest=ret->getPointer();
3692   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3693     INTERP_KERNEL::computeEigenValues6(src,dest);
3694   return ret;
3695 }
3696
3697 /*!
3698  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3699  * \a this array, which contains 6 components.
3700  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3701  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3702  *          corresponding tuple of \a this array.
3703  *          The caller is to delete this result array using decrRef() as it is no more
3704  *          needed.
3705  *  \throw If \a this->getNumberOfComponents() != 6.
3706  */
3707 DataArrayDouble *DataArrayDouble::eigenVectors() const
3708 {
3709   checkAllocated();
3710   int nbOfComp=getNumberOfComponents();
3711   if(nbOfComp!=6)
3712     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3713   DataArrayDouble *ret=DataArrayDouble::New();
3714   int nbOfTuple=getNumberOfTuples();
3715   ret->alloc(nbOfTuple,9);
3716   const double *src=getConstPointer();
3717   double *dest=ret->getPointer();
3718   for(int i=0;i<nbOfTuple;i++,src+=6)
3719     {
3720       double tmp[3];
3721       INTERP_KERNEL::computeEigenValues6(src,tmp);
3722       for(int j=0;j<3;j++,dest+=3)
3723         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3724     }
3725   return ret;
3726 }
3727
3728 /*!
3729  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3730  * array, which contains either 4, 6 or 9 components. The case of 6 components
3731  * corresponds to that of the upper triangular matrix.
3732  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3733  *          same number of components as \a this one, whose each tuple is the inverse
3734  *          matrix of the matrix of corresponding tuple of \a this array. 
3735  *          The caller is to delete this result array using decrRef() as it is no more
3736  *          needed. 
3737  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3738  */
3739 DataArrayDouble *DataArrayDouble::inverse() const
3740 {
3741   checkAllocated();
3742   int nbOfComp=getNumberOfComponents();
3743   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3744     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3745   DataArrayDouble *ret=DataArrayDouble::New();
3746   int nbOfTuple=getNumberOfTuples();
3747   ret->alloc(nbOfTuple,nbOfComp);
3748   const double *src=getConstPointer();
3749   double *dest=ret->getPointer();
3750   if(nbOfComp==6)
3751     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3752       {
3753         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];
3754         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3755         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3756         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3757         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3758         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3759         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3760       }
3761   else if(nbOfComp==4)
3762     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3763       {
3764         double det=src[0]*src[3]-src[1]*src[2];
3765         dest[0]=src[3]/det;
3766         dest[1]=-src[1]/det;
3767         dest[2]=-src[2]/det;
3768         dest[3]=src[0]/det;
3769       }
3770   else
3771     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3772       {
3773         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];
3774         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3775         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3776         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3777         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3778         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3779         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3780         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3781         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3782         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3783       }
3784   return ret;
3785 }
3786
3787 /*!
3788  * Computes the trace of every matrix defined by the tuple of \a this
3789  * array, which contains either 4, 6 or 9 components. The case of 6 components
3790  * corresponds to that of the upper triangular matrix.
3791  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3792  *          1 component, whose each tuple is the trace of
3793  *          the matrix of corresponding tuple of \a this array. 
3794  *          The caller is to delete this result array using decrRef() as it is no more
3795  *          needed. 
3796  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3797  */
3798 DataArrayDouble *DataArrayDouble::trace() const
3799 {
3800   checkAllocated();
3801   int nbOfComp=getNumberOfComponents();
3802   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3803     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3804   DataArrayDouble *ret=DataArrayDouble::New();
3805   int nbOfTuple=getNumberOfTuples();
3806   ret->alloc(nbOfTuple,1);
3807   const double *src=getConstPointer();
3808   double *dest=ret->getPointer();
3809   if(nbOfComp==6)
3810     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3811       *dest=src[0]+src[1]+src[2];
3812   else if(nbOfComp==4)
3813     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3814       *dest=src[0]+src[3];
3815   else
3816     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3817       *dest=src[0]+src[4]+src[8];
3818   return ret;
3819 }
3820
3821 /*!
3822  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3823  * \a this array, which contains 6 components.
3824  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3825  *          same number of components and tuples as \a this array.
3826  *          The caller is to delete this result array using decrRef() as it is no more
3827  *          needed.
3828  *  \throw If \a this->getNumberOfComponents() != 6.
3829  */
3830 DataArrayDouble *DataArrayDouble::deviator() const
3831 {
3832   checkAllocated();
3833   int nbOfComp=getNumberOfComponents();
3834   if(nbOfComp!=6)
3835     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3836   DataArrayDouble *ret=DataArrayDouble::New();
3837   int nbOfTuple=getNumberOfTuples();
3838   ret->alloc(nbOfTuple,6);
3839   const double *src=getConstPointer();
3840   double *dest=ret->getPointer();
3841   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3842     {
3843       double tr=(src[0]+src[1]+src[2])/3.;
3844       dest[0]=src[0]-tr;
3845       dest[1]=src[1]-tr;
3846       dest[2]=src[2]-tr;
3847       dest[3]=src[3];
3848       dest[4]=src[4];
3849       dest[5]=src[5];
3850     }
3851   return ret;
3852 }
3853
3854 /*!
3855  * Computes the magnitude of every vector defined by the tuple of
3856  * \a this array.
3857  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3858  *          same number of tuples as \a this array and one component.
3859  *          The caller is to delete this result array using decrRef() as it is no more
3860  *          needed.
3861  *  \throw If \a this is not allocated.
3862  */
3863 DataArrayDouble *DataArrayDouble::magnitude() const
3864 {
3865   checkAllocated();
3866   int nbOfComp=getNumberOfComponents();
3867   DataArrayDouble *ret=DataArrayDouble::New();
3868   int nbOfTuple=getNumberOfTuples();
3869   ret->alloc(nbOfTuple,1);
3870   const double *src=getConstPointer();
3871   double *dest=ret->getPointer();
3872   for(int i=0;i<nbOfTuple;i++,dest++)
3873     {
3874       double sum=0.;
3875       for(int j=0;j<nbOfComp;j++,src++)
3876         sum+=(*src)*(*src);
3877       *dest=sqrt(sum);
3878     }
3879   return ret;
3880 }
3881
3882 /*!
3883  * Computes for each tuple the sum of number of components values in the tuple and return it.
3884  * 
3885  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3886  *          same number of tuples as \a this array and one component.
3887  *          The caller is to delete this result array using decrRef() as it is no more
3888  *          needed.
3889  *  \throw If \a this is not allocated.
3890  */
3891 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3892 {
3893   checkAllocated();
3894   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3895   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3896   ret->alloc(nbOfTuple,1);
3897   const double *src(getConstPointer());
3898   double *dest(ret->getPointer());
3899   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3900     *dest=std::accumulate(src,src+nbOfComp,0.);
3901   return ret.retn();
3902 }
3903
3904 /*!
3905  * Computes the maximal value within every tuple of \a this array.
3906  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3907  *          same number of tuples as \a this array and one component.
3908  *          The caller is to delete this result array using decrRef() as it is no more
3909  *          needed.
3910  *  \throw If \a this is not allocated.
3911  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3912  */
3913 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3914 {
3915   checkAllocated();
3916   int nbOfComp=getNumberOfComponents();
3917   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3918   int nbOfTuple=getNumberOfTuples();
3919   ret->alloc(nbOfTuple,1);
3920   const double *src=getConstPointer();
3921   double *dest=ret->getPointer();
3922   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3923     *dest=*std::max_element(src,src+nbOfComp);
3924   return ret.retn();
3925 }
3926
3927 /*!
3928  * Computes the maximal value within every tuple of \a this array and it returns the first component
3929  * id for each tuple that corresponds to the maximal value within the tuple.
3930  * 
3931  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3932  *          same number of tuples and only one component.
3933  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3934  *          same number of tuples as \a this array and one component.
3935  *          The caller is to delete this result array using decrRef() as it is no more
3936  *          needed.
3937  *  \throw If \a this is not allocated.
3938  *  \sa DataArrayDouble::maxPerTuple
3939  */
3940 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3941 {
3942   checkAllocated();
3943   int nbOfComp=getNumberOfComponents();
3944   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3945   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3946   int nbOfTuple=getNumberOfTuples();
3947   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3948   const double *src=getConstPointer();
3949   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3950   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3951     {
3952       const double *loc=std::max_element(src,src+nbOfComp);
3953       *dest=*loc;
3954       *dest1=(int)std::distance(src,loc);
3955     }
3956   compoIdOfMaxPerTuple=ret1.retn();
3957   return ret0.retn();
3958 }
3959
3960 /*!
3961  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3962  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3963  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3964  * \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)
3965  *
3966  * \warning use this method with care because it can leads to big amount of consumed memory !
3967  * 
3968  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3969  *
3970  * \throw If \a this is not allocated.
3971  *
3972  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3973  */
3974 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3975 {
3976   checkAllocated();
3977   int nbOfComp=getNumberOfComponents();
3978   int nbOfTuples=getNumberOfTuples();
3979   const double *inData=getConstPointer();
3980   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3981   ret->alloc(nbOfTuples*nbOfTuples,1);
3982   double *outData=ret->getPointer();
3983   for(int i=0;i<nbOfTuples;i++)
3984     {
3985       outData[i*nbOfTuples+i]=0.;
3986       for(int j=i+1;j<nbOfTuples;j++)
3987         {
3988           double dist=0.;
3989           for(int k=0;k<nbOfComp;k++)
3990             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3991           dist=sqrt(dist);
3992           outData[i*nbOfTuples+j]=dist;
3993           outData[j*nbOfTuples+i]=dist;
3994         }
3995     }
3996   return ret.retn();
3997 }
3998
3999 /*!
4000  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4001  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4002  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4003  * \n Output rectangular matrix is sorted along rows.
4004  * \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)
4005  *
4006  * \warning use this method with care because it can leads to big amount of consumed memory !
4007  * 
4008  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4009  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4010  *
4011  * \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.
4012  *
4013  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4014  */
4015 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4016 {
4017   if(!other)
4018     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4019   checkAllocated();
4020   other->checkAllocated();
4021   int nbOfComp=getNumberOfComponents();
4022   int otherNbOfComp=other->getNumberOfComponents();
4023   if(nbOfComp!=otherNbOfComp)
4024     {
4025       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4026       throw INTERP_KERNEL::Exception(oss.str().c_str());
4027     }
4028   int nbOfTuples=getNumberOfTuples();
4029   int otherNbOfTuples=other->getNumberOfTuples();
4030   const double *inData=getConstPointer();
4031   const double *inDataOther=other->getConstPointer();
4032   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4033   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4034   double *outData=ret->getPointer();
4035   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4036     {
4037       for(int j=0;j<nbOfTuples;j++)
4038         {
4039           double dist=0.;
4040           for(int k=0;k<nbOfComp;k++)
4041             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4042           dist=sqrt(dist);
4043           outData[i*nbOfTuples+j]=dist;
4044         }
4045     }
4046   return ret.retn();
4047 }
4048
4049 /*!
4050  * Sorts value within every tuple of \a this array.
4051  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4052  *              in descending order.
4053  *  \throw If \a this is not allocated.
4054  */
4055 void DataArrayDouble::sortPerTuple(bool asc)
4056 {
4057   checkAllocated();
4058   double *pt=getPointer();
4059   int nbOfTuple=getNumberOfTuples();
4060   int nbOfComp=getNumberOfComponents();
4061   if(asc)
4062     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4063       std::sort(pt,pt+nbOfComp);
4064   else
4065     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4066       std::sort(pt,pt+nbOfComp,std::greater<double>());
4067   declareAsNew();
4068 }
4069
4070 /*!
4071  * Converts every value of \a this array to its absolute value.
4072  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4073  * should be called instead.
4074  *
4075  * \throw If \a this is not allocated.
4076  * \sa DataArrayDouble::computeAbs
4077  */
4078 void DataArrayDouble::abs()
4079 {
4080   checkAllocated();
4081   double *ptr(getPointer());
4082   std::size_t nbOfElems(getNbOfElems());
4083   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4084   declareAsNew();
4085 }
4086
4087 /*!
4088  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4089  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4090  *
4091  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4092  *         same number of tuples and component as \a this array.
4093  *         The caller is to delete this result array using decrRef() as it is no more
4094  *         needed.
4095  * \throw If \a this is not allocated.
4096  * \sa DataArrayDouble::abs
4097  */
4098 DataArrayDouble *DataArrayDouble::computeAbs() const
4099 {
4100   checkAllocated();
4101   DataArrayDouble *newArr(DataArrayDouble::New());
4102   int nbOfTuples(getNumberOfTuples());
4103   int nbOfComp(getNumberOfComponents());
4104   newArr->alloc(nbOfTuples,nbOfComp);
4105   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4106   newArr->copyStringInfoFrom(*this);
4107   return newArr;
4108 }
4109
4110 /*!
4111  * Apply a linear function to a given component of \a this array, so that
4112  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4113  *  \param [in] a - the first coefficient of the function.
4114  *  \param [in] b - the second coefficient of the function.
4115  *  \param [in] compoId - the index of component to modify.
4116  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4117  */
4118 void DataArrayDouble::applyLin(double a, double b, int compoId)
4119 {
4120   checkAllocated();
4121   double *ptr(getPointer()+compoId);
4122   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4123   if(compoId<0 || compoId>=nbOfComp)
4124     {
4125       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4126       throw INTERP_KERNEL::Exception(oss.str().c_str());
4127     }
4128   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4129     *ptr=a*(*ptr)+b;
4130   declareAsNew();
4131 }
4132
4133 /*!
4134  * Apply a linear function to all elements of \a this array, so that
4135  * an element _x_ becomes \f$ a * x + b \f$.
4136  *  \param [in] a - the first coefficient of the function.
4137  *  \param [in] b - the second coefficient of the function.
4138  *  \throw If \a this is not allocated.
4139  */
4140 void DataArrayDouble::applyLin(double a, double b)
4141 {
4142   checkAllocated();
4143   double *ptr=getPointer();
4144   std::size_t nbOfElems=getNbOfElems();
4145   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4146     *ptr=a*(*ptr)+b;
4147   declareAsNew();
4148 }
4149
4150 /*!
4151  * Modify all elements of \a this array, so that
4152  * an element _x_ becomes \f$ numerator / x \f$.
4153  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4154  *           array, all elements processed before detection of the zero element remain
4155  *           modified.
4156  *  \param [in] numerator - the numerator used to modify array elements.
4157  *  \throw If \a this is not allocated.
4158  *  \throw If there is an element equal to 0.0 in \a this array.
4159  */
4160 void DataArrayDouble::applyInv(double numerator)
4161 {
4162   checkAllocated();
4163   double *ptr=getPointer();
4164   std::size_t nbOfElems=getNbOfElems();
4165   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4166     {
4167       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4168         {
4169           *ptr=numerator/(*ptr);
4170         }
4171       else
4172         {
4173           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4174           oss << " !";
4175           throw INTERP_KERNEL::Exception(oss.str().c_str());
4176         }
4177     }
4178   declareAsNew();
4179 }
4180
4181 /*!
4182  * Returns a full copy of \a this array except that sign of all elements is reversed.
4183  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4184  *          same number of tuples and component as \a this array.
4185  *          The caller is to delete this result array using decrRef() as it is no more
4186  *          needed.
4187  *  \throw If \a this is not allocated.
4188  */
4189 DataArrayDouble *DataArrayDouble::negate() const
4190 {
4191   checkAllocated();
4192   DataArrayDouble *newArr=DataArrayDouble::New();
4193   int nbOfTuples=getNumberOfTuples();
4194   int nbOfComp=getNumberOfComponents();
4195   newArr->alloc(nbOfTuples,nbOfComp);
4196   const double *cptr=getConstPointer();
4197   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4198   newArr->copyStringInfoFrom(*this);
4199   return newArr;
4200 }
4201
4202 /*!
4203  * Modify all elements of \a this array, so that
4204  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4205  * all values in \a this have to be >= 0 if val is \b not integer.
4206  *  \param [in] val - the value used to apply pow on all array elements.
4207  *  \throw If \a this is not allocated.
4208  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4209  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4210  *           modified.
4211  */
4212 void DataArrayDouble::applyPow(double val)
4213 {
4214   checkAllocated();
4215   double *ptr=getPointer();
4216   std::size_t nbOfElems=getNbOfElems();
4217   int val2=(int)val;
4218   bool isInt=((double)val2)==val;
4219   if(!isInt)
4220     {
4221       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4222         {
4223           if(*ptr>=0)
4224             *ptr=pow(*ptr,val);
4225           else
4226             {
4227               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4228               throw INTERP_KERNEL::Exception(oss.str().c_str());
4229             }
4230         }
4231     }
4232   else
4233     {
4234       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4235         *ptr=pow(*ptr,val2);
4236     }
4237   declareAsNew();
4238 }
4239
4240 /*!
4241  * Modify all elements of \a this array, so that
4242  * an element _x_ becomes \f$ val ^ x \f$.
4243  *  \param [in] val - the value used to apply pow on all array elements.
4244  *  \throw If \a this is not allocated.
4245  *  \throw If \a val < 0.
4246  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4247  *           array, all elements processed before detection of the zero element remain
4248  *           modified.
4249  */
4250 void DataArrayDouble::applyRPow(double val)
4251 {
4252   checkAllocated();
4253   if(val<0.)
4254     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4255   double *ptr=getPointer();
4256   std::size_t nbOfElems=getNbOfElems();
4257   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4258     *ptr=pow(val,*ptr);
4259   declareAsNew();
4260 }
4261
4262 /*!
4263  * Returns a new DataArrayDouble created from \a this one by applying \a
4264  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4265  * For more info see \ref MEDCouplingArrayApplyFunc
4266  *  \param [in] nbOfComp - number of components in the result array.
4267  *  \param [in] func - the \a FunctionToEvaluate declared as 
4268  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4269  *              where \a pos points to the first component of a tuple of \a this array
4270  *              and \a res points to the first component of a tuple of the result array.
4271  *              Note that length (number of components) of \a pos can differ from
4272  *              that of \a res.
4273  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4274  *          same number of tuples as \a this array.
4275  *          The caller is to delete this result array using decrRef() as it is no more
4276  *          needed.
4277  *  \throw If \a this is not allocated.
4278  *  \throw If \a func returns \a false.
4279  */
4280 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4281 {
4282   checkAllocated();
4283   DataArrayDouble *newArr=DataArrayDouble::New();
4284   int nbOfTuples=getNumberOfTuples();
4285   int oldNbOfComp=getNumberOfComponents();
4286   newArr->alloc(nbOfTuples,nbOfComp);
4287   const double *ptr=getConstPointer();
4288   double *ptrToFill=newArr->getPointer();
4289   for(int i=0;i<nbOfTuples;i++)
4290     {
4291       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4292         {
4293           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4294           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4295           oss << ") : Evaluation of function failed !";
4296           newArr->decrRef();
4297           throw INTERP_KERNEL::Exception(oss.str().c_str());
4298         }
4299     }
4300   return newArr;
4301 }
4302
4303 /*!
4304  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4305  * tuple of \a this array. Textual data is not copied.
4306  * For more info see \ref MEDCouplingArrayApplyFunc1.
4307  *  \param [in] nbOfComp - number of components in the result array.
4308  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4309  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4310  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4311  *          same number of tuples as \a this array and \a nbOfComp components.
4312  *          The caller is to delete this result array using decrRef() as it is no more
4313  *          needed.
4314  *  \throw If \a this is not allocated.
4315  *  \throw If computing \a func fails.
4316  */
4317 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func) const
4318 {
4319   checkAllocated();
4320   INTERP_KERNEL::ExprParser expr(func);
4321   expr.parse();
4322   std::set<std::string> vars;
4323   expr.getTrueSetOfVars(vars);
4324   int oldNbOfComp=getNumberOfComponents();
4325   if((int)vars.size()>oldNbOfComp)
4326     {
4327       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4328       oss << vars.size() << " variables : ";
4329       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4330       throw INTERP_KERNEL::Exception(oss.str().c_str());
4331     }
4332   std::vector<std::string> varsV(vars.begin(),vars.end());
4333   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4334   //
4335   DataArrayDouble *newArr=DataArrayDouble::New();
4336   int nbOfTuples=getNumberOfTuples();
4337   newArr->alloc(nbOfTuples,nbOfComp);
4338   const double *ptr=getConstPointer();
4339   double *ptrToFill=newArr->getPointer();
4340   for(int i=0;i<nbOfTuples;i++)
4341     {
4342       try
4343       {
4344           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4345       }
4346       catch(INTERP_KERNEL::Exception& e)
4347       {
4348           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4349           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4350           oss << ") : Evaluation of function failed !" << e.what();
4351           newArr->decrRef();
4352           throw INTERP_KERNEL::Exception(oss.str().c_str());
4353       }
4354     }
4355   return newArr;
4356 }
4357
4358 /*!
4359  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4360  * tuple of \a this array. Textual data is not copied.
4361  * For more info see \ref MEDCouplingArrayApplyFunc0.
4362  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4363  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4364  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4365  *          same number of tuples and components as \a this array.
4366  *          The caller is to delete this result array using decrRef() as it is no more
4367  *          needed.
4368  *  \throw If \a this is not allocated.
4369  *  \throw If computing \a func fails.
4370  */
4371 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func) const
4372 {
4373   checkAllocated();
4374   INTERP_KERNEL::ExprParser expr(func);
4375   expr.parse();
4376   expr.prepareExprEvaluationVec();
4377   //
4378   DataArrayDouble *newArr=DataArrayDouble::New();
4379   int nbOfTuples=getNumberOfTuples();
4380   int nbOfComp=getNumberOfComponents();
4381   newArr->alloc(nbOfTuples,nbOfComp);
4382   const double *ptr=getConstPointer();
4383   double *ptrToFill=newArr->getPointer();
4384   for(int i=0;i<nbOfTuples;i++)
4385     {
4386       try
4387       {
4388           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4389       }
4390       catch(INTERP_KERNEL::Exception& e)
4391       {
4392           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4393           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4394           oss << ") : Evaluation of function failed ! " << e.what();
4395           newArr->decrRef();
4396           throw INTERP_KERNEL::Exception(oss.str().c_str());
4397       }
4398     }
4399   return newArr;
4400 }
4401
4402 /*!
4403  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4404  * tuple of \a this array. Textual data is not copied.
4405  * For more info see \ref MEDCouplingArrayApplyFunc2.
4406  *  \param [in] nbOfComp - number of components in the result array.
4407  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4408  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4409  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4410  *          same number of tuples as \a this array.
4411  *          The caller is to delete this result array using decrRef() as it is no more
4412  *          needed.
4413  *  \throw If \a this is not allocated.
4414  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4415  *  \throw If computing \a func fails.
4416  */
4417 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func) const
4418 {
4419   checkAllocated();
4420   INTERP_KERNEL::ExprParser expr(func);
4421   expr.parse();
4422   std::set<std::string> vars;
4423   expr.getTrueSetOfVars(vars);
4424   int oldNbOfComp=getNumberOfComponents();
4425   if((int)vars.size()>oldNbOfComp)
4426     {
4427       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4428       oss << vars.size() << " variables : ";
4429       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4430       throw INTERP_KERNEL::Exception(oss.str().c_str());
4431     }
4432   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4433   //
4434   DataArrayDouble *newArr=DataArrayDouble::New();
4435   int nbOfTuples=getNumberOfTuples();
4436   newArr->alloc(nbOfTuples,nbOfComp);
4437   const double *ptr=getConstPointer();
4438   double *ptrToFill=newArr->getPointer();
4439   for(int i=0;i<nbOfTuples;i++)
4440     {
4441       try
4442       {
4443           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4444       }
4445       catch(INTERP_KERNEL::Exception& e)
4446       {
4447           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4448           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4449           oss << ") : Evaluation of function failed !" << e.what();
4450           newArr->decrRef();
4451           throw INTERP_KERNEL::Exception(oss.str().c_str());
4452       }
4453     }
4454   return newArr;
4455 }
4456
4457 /*!
4458  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4459  * tuple of \a this array. Textual data is not copied.
4460  * For more info see \ref MEDCouplingArrayApplyFunc3.
4461  *  \param [in] nbOfComp - number of components in the result array.
4462  *  \param [in] varsOrder - sequence of vars defining their order.
4463  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4464  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4465  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4466  *          same number of tuples as \a this array.
4467  *          The caller is to delete this result array using decrRef() as it is no more
4468  *          needed.
4469  *  \throw If \a this is not allocated.
4470  *  \throw If \a func contains vars not in \a varsOrder.
4471  *  \throw If computing \a func fails.
4472  */
4473 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const
4474 {
4475   checkAllocated();
4476   INTERP_KERNEL::ExprParser expr(func);
4477   expr.parse();
4478   std::set<std::string> vars;
4479   expr.getTrueSetOfVars(vars);
4480   int oldNbOfComp=getNumberOfComponents();
4481   if((int)vars.size()>oldNbOfComp)
4482     {
4483       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4484       oss << vars.size() << " variables : ";
4485       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4486       throw INTERP_KERNEL::Exception(oss.str().c_str());
4487     }
4488   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4489   //
4490   DataArrayDouble *newArr=DataArrayDouble::New();
4491   int nbOfTuples=getNumberOfTuples();
4492   newArr->alloc(nbOfTuples,nbOfComp);
4493   const double *ptr=getConstPointer();
4494   double *ptrToFill=newArr->getPointer();
4495   for(int i=0;i<nbOfTuples;i++)
4496     {
4497       try
4498       {
4499           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4500       }
4501       catch(INTERP_KERNEL::Exception& e)
4502       {
4503           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4504           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4505           oss << ") : Evaluation of function failed !" << e.what();
4506           newArr->decrRef();
4507           throw INTERP_KERNEL::Exception(oss.str().c_str());
4508       }
4509     }
4510   return newArr;
4511 }
4512
4513 void DataArrayDouble::applyFuncFast32(const std::string& func)
4514 {
4515   checkAllocated();
4516   INTERP_KERNEL::ExprParser expr(func);
4517   expr.parse();
4518   char *funcStr=expr.compileX86();
4519   MYFUNCPTR funcPtr;
4520   *((void **)&funcPtr)=funcStr;//he he...
4521   //
4522   double *ptr=getPointer();
4523   int nbOfComp=getNumberOfComponents();
4524   int nbOfTuples=getNumberOfTuples();
4525   int nbOfElems=nbOfTuples*nbOfComp;
4526   for(int i=0;i<nbOfElems;i++,ptr++)
4527     *ptr=funcPtr(*ptr);
4528   declareAsNew();
4529 }
4530
4531 void DataArrayDouble::applyFuncFast64(const std::string& func)
4532 {
4533   checkAllocated();
4534   INTERP_KERNEL::ExprParser expr(func);
4535   expr.parse();
4536   char *funcStr=expr.compileX86_64();
4537   MYFUNCPTR funcPtr;
4538   *((void **)&funcPtr)=funcStr;//he he...
4539   //
4540   double *ptr=getPointer();
4541   int nbOfComp=getNumberOfComponents();
4542   int nbOfTuples=getNumberOfTuples();
4543   int nbOfElems=nbOfTuples*nbOfComp;
4544   for(int i=0;i<nbOfElems;i++,ptr++)
4545     *ptr=funcPtr(*ptr);
4546   declareAsNew();
4547 }
4548
4549 DataArrayDoubleIterator *DataArrayDouble::iterator()
4550 {
4551   return new DataArrayDoubleIterator(this);
4552 }
4553
4554 /*!
4555  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4556  * array whose values are within a given range. Textual data is not copied.
4557  *  \param [in] vmin - a lowest acceptable value (included).
4558  *  \param [in] vmax - a greatest acceptable value (included).
4559  *  \return DataArrayInt * - the new instance of DataArrayInt.
4560  *          The caller is to delete this result array using decrRef() as it is no more
4561  *          needed.
4562  *  \throw If \a this->getNumberOfComponents() != 1.
4563  *
4564  *  \sa DataArrayDouble::getIdsNotInRange
4565  *
4566  *  \if ENABLE_EXAMPLES
4567  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4568  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4569  *  \endif
4570  */
4571 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4572 {
4573   checkAllocated();
4574   if(getNumberOfComponents()!=1)
4575     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4576   const double *cptr(begin());
4577   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4578   int nbOfTuples(getNumberOfTuples());
4579   for(int i=0;i<nbOfTuples;i++,cptr++)
4580     if(*cptr>=vmin && *cptr<=vmax)
4581       ret->pushBackSilent(i);
4582   return ret.retn();
4583 }
4584
4585 /*!
4586  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4587  * array whose values are not within a given range. Textual data is not copied.
4588  *  \param [in] vmin - a lowest not acceptable value (excluded).
4589  *  \param [in] vmax - a greatest not acceptable value (excluded).
4590  *  \return DataArrayInt * - the new instance of DataArrayInt.
4591  *          The caller is to delete this result array using decrRef() as it is no more
4592  *          needed.
4593  *  \throw If \a this->getNumberOfComponents() != 1.
4594  *
4595  *  \sa DataArrayDouble::getIdsInRange
4596  */
4597 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4598 {
4599   checkAllocated();
4600   if(getNumberOfComponents()!=1)
4601     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4602   const double *cptr(begin());
4603   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4604   int nbOfTuples(getNumberOfTuples());
4605   for(int i=0;i<nbOfTuples;i++,cptr++)
4606     if(*cptr<vmin || *cptr>vmax)
4607       ret->pushBackSilent(i);
4608   return ret.retn();
4609 }
4610
4611 /*!
4612  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4613  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4614  * the number of component in the result array is same as that of each of given arrays.
4615  * Info on components is copied from the first of the given arrays. Number of components
4616  * in the given arrays must be  the same.
4617  *  \param [in] a1 - an array to include in the result array.
4618  *  \param [in] a2 - another array to include in the result array.
4619  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4620  *          The caller is to delete this result array using decrRef() as it is no more
4621  *          needed.
4622  *  \throw If both \a a1 and \a a2 are NULL.
4623  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4624  */
4625 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4626 {
4627   std::vector<const DataArrayDouble *> tmp(2);
4628   tmp[0]=a1; tmp[1]=a2;
4629   return Aggregate(tmp);
4630 }
4631
4632 /*!
4633  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4634  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4635  * the number of component in the result array is same as that of each of given arrays.
4636  * Info on components is copied from the first of the given arrays. Number of components
4637  * in the given arrays must be  the same.
4638  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4639  * not the object itself.
4640  *  \param [in] arr - a sequence of arrays to include in the result array.
4641  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4642  *          The caller is to delete this result array using decrRef() as it is no more
4643  *          needed.
4644  *  \throw If all arrays within \a arr are NULL.
4645  *  \throw If getNumberOfComponents() of arrays within \a arr.
4646  */
4647 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4648 {
4649   std::vector<const DataArrayDouble *> a;
4650   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4651     if(*it4)
4652       a.push_back(*it4);
4653   if(a.empty())
4654     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4655   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4656   int nbOfComp=(*it)->getNumberOfComponents();
4657   int nbt=(*it++)->getNumberOfTuples();
4658   for(int i=1;it!=a.end();it++,i++)
4659     {
4660       if((*it)->getNumberOfComponents()!=nbOfComp)
4661         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4662       nbt+=(*it)->getNumberOfTuples();
4663     }
4664   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4665   ret->alloc(nbt,nbOfComp);
4666   double *pt=ret->getPointer();
4667   for(it=a.begin();it!=a.end();it++)
4668     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4669   ret->copyStringInfoFrom(*(a[0]));
4670   return ret.retn();
4671 }
4672
4673 /*!
4674  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4675  * of components in the result array is a sum of the number of components of given arrays
4676  * and (2) the number of tuples in the result array is same as that of each of given
4677  * arrays. In other words the i-th tuple of result array includes all components of
4678  * i-th tuples of all given arrays.
4679  * Number of tuples in the given arrays must be  the same.
4680  *  \param [in] a1 - an array to include in the result array.
4681  *  \param [in] a2 - another array to include in the result array.
4682  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4683  *          The caller is to delete this result array using decrRef() as it is no more
4684  *          needed.
4685  *  \throw If both \a a1 and \a a2 are NULL.
4686  *  \throw If any given array is not allocated.
4687  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4688  */
4689 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4690 {
4691   std::vector<const DataArrayDouble *> arr(2);
4692   arr[0]=a1; arr[1]=a2;
4693   return Meld(arr);
4694 }
4695
4696 /*!
4697  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4698  * of components in the result array is a sum of the number of components of given arrays
4699  * and (2) the number of tuples in the result array is same as that of each of given
4700  * arrays. In other words the i-th tuple of result array includes all components of
4701  * i-th tuples of all given arrays.
4702  * Number of tuples in the given arrays must be  the same.
4703  *  \param [in] arr - a sequence of arrays to include in the result array.
4704  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4705  *          The caller is to delete this result array using decrRef() as it is no more
4706  *          needed.
4707  *  \throw If all arrays within \a arr are NULL.
4708  *  \throw If any given array is not allocated.
4709  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4710  */
4711 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4712 {
4713   std::vector<const DataArrayDouble *> a;
4714   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4715     if(*it4)
4716       a.push_back(*it4);
4717   if(a.empty())
4718     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4719   std::vector<const DataArrayDouble *>::const_iterator it;
4720   for(it=a.begin();it!=a.end();it++)
4721     (*it)->checkAllocated();
4722   it=a.begin();
4723   int nbOfTuples=(*it)->getNumberOfTuples();
4724   std::vector<int> nbc(a.size());
4725   std::vector<const double *> pts(a.size());
4726   nbc[0]=(*it)->getNumberOfComponents();
4727   pts[0]=(*it++)->getConstPointer();
4728   for(int i=1;it!=a.end();it++,i++)
4729     {
4730       if(nbOfTuples!=(*it)->getNumberOfTuples())
4731         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4732       nbc[i]=(*it)->getNumberOfComponents();
4733       pts[i]=(*it)->getConstPointer();
4734     }
4735   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4736   DataArrayDouble *ret=DataArrayDouble::New();
4737   ret->alloc(nbOfTuples,totalNbOfComp);
4738   double *retPtr=ret->getPointer();
4739   for(int i=0;i<nbOfTuples;i++)
4740     for(int j=0;j<(int)a.size();j++)
4741       {
4742         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4743         pts[j]+=nbc[j];
4744       }
4745   int k=0;
4746   for(int i=0;i<(int)a.size();i++)
4747     for(int j=0;j<nbc[i];j++,k++)
4748       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4749   return ret;
4750 }
4751
4752 /*!
4753  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4754  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4755  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4756  * Info on components and name is copied from the first of the given arrays.
4757  * Number of tuples and components in the given arrays must be the same.
4758  *  \param [in] a1 - a given array.
4759  *  \param [in] a2 - another given array.
4760  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4761  *          The caller is to delete this result array using decrRef() as it is no more
4762  *          needed.
4763  *  \throw If either \a a1 or \a a2 is NULL.
4764  *  \throw If any given array is not allocated.
4765  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4766  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4767  */
4768 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4769 {
4770   if(!a1 || !a2)
4771     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4772   a1->checkAllocated();
4773   a2->checkAllocated();
4774   int nbOfComp=a1->getNumberOfComponents();
4775   if(nbOfComp!=a2->getNumberOfComponents())
4776     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4777   int nbOfTuple=a1->getNumberOfTuples();
4778   if(nbOfTuple!=a2->getNumberOfTuples())
4779     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4780   DataArrayDouble *ret=DataArrayDouble::New();
4781   ret->alloc(nbOfTuple,1);
4782   double *retPtr=ret->getPointer();
4783   const double *a1Ptr=a1->getConstPointer();
4784   const double *a2Ptr=a2->getConstPointer();
4785   for(int i=0;i<nbOfTuple;i++)
4786     {
4787       double sum=0.;
4788       for(int j=0;j<nbOfComp;j++)
4789         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4790       retPtr[i]=sum;
4791     }
4792   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4793   ret->setName(a1->getName());
4794   return ret;
4795 }
4796
4797 /*!
4798  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4799  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4800  * product of two vectors defined by the i-th tuples of given arrays.
4801  * Info on components is copied from the first of the given arrays.
4802  * Number of tuples in the given arrays must be the same.
4803  * Number of components in the given arrays must be 3.
4804  *  \param [in] a1 - a given array.
4805  *  \param [in] a2 - another given array.
4806  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4807  *          The caller is to delete this result array using decrRef() as it is no more
4808  *          needed.
4809  *  \throw If either \a a1 or \a a2 is NULL.
4810  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4811  *  \throw If \a a1->getNumberOfComponents() != 3
4812  *  \throw If \a a2->getNumberOfComponents() != 3
4813  */
4814 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4815 {
4816   if(!a1 || !a2)
4817     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4818   int nbOfComp=a1->getNumberOfComponents();
4819   if(nbOfComp!=a2->getNumberOfComponents())
4820     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4821   if(nbOfComp!=3)
4822     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4823   int nbOfTuple=a1->getNumberOfTuples();
4824   if(nbOfTuple!=a2->getNumberOfTuples())
4825     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4826   DataArrayDouble *ret=DataArrayDouble::New();
4827   ret->alloc(nbOfTuple,3);
4828   double *retPtr=ret->getPointer();
4829   const double *a1Ptr=a1->getConstPointer();
4830   const double *a2Ptr=a2->getConstPointer();
4831   for(int i=0;i<nbOfTuple;i++)
4832     {
4833       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4834       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4835       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4836     }
4837   ret->copyStringInfoFrom(*a1);
4838   return ret;
4839 }
4840
4841 /*!
4842  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4843  * Info on components is copied from the first of the given arrays.
4844  * Number of tuples and components in the given arrays must be the same.
4845  *  \param [in] a1 - an array to compare values with another one.
4846  *  \param [in] a2 - another array to compare values with the first one.
4847  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4848  *          The caller is to delete this result array using decrRef() as it is no more
4849  *          needed.
4850  *  \throw If either \a a1 or \a a2 is NULL.
4851  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4852  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4853  */
4854 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4855 {
4856   if(!a1 || !a2)
4857     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4858   int nbOfComp=a1->getNumberOfComponents();
4859   if(nbOfComp!=a2->getNumberOfComponents())
4860     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4861   int nbOfTuple=a1->getNumberOfTuples();
4862   if(nbOfTuple!=a2->getNumberOfTuples())
4863     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4864   DataArrayDouble *ret=DataArrayDouble::New();
4865   ret->alloc(nbOfTuple,nbOfComp);
4866   double *retPtr=ret->getPointer();
4867   const double *a1Ptr=a1->getConstPointer();
4868   const double *a2Ptr=a2->getConstPointer();
4869   int nbElem=nbOfTuple*nbOfComp;
4870   for(int i=0;i<nbElem;i++)
4871     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4872   ret->copyStringInfoFrom(*a1);
4873   return ret;
4874 }
4875
4876 /*!
4877  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4878  * Info on components is copied from the first of the given arrays.
4879  * Number of tuples and components in the given arrays must be the same.
4880  *  \param [in] a1 - an array to compare values with another one.
4881  *  \param [in] a2 - another array to compare values with the first one.
4882  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4883  *          The caller is to delete this result array using decrRef() as it is no more
4884  *          needed.
4885  *  \throw If either \a a1 or \a a2 is NULL.
4886  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4887  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4888  */
4889 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4890 {
4891   if(!a1 || !a2)
4892     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4893   int nbOfComp=a1->getNumberOfComponents();
4894   if(nbOfComp!=a2->getNumberOfComponents())
4895     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4896   int nbOfTuple=a1->getNumberOfTuples();
4897   if(nbOfTuple!=a2->getNumberOfTuples())
4898     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4899   DataArrayDouble *ret=DataArrayDouble::New();
4900   ret->alloc(nbOfTuple,nbOfComp);
4901   double *retPtr=ret->getPointer();
4902   const double *a1Ptr=a1->getConstPointer();
4903   const double *a2Ptr=a2->getConstPointer();
4904   int nbElem=nbOfTuple*nbOfComp;
4905   for(int i=0;i<nbElem;i++)
4906     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4907   ret->copyStringInfoFrom(*a1);
4908   return ret;
4909 }
4910
4911 /*!
4912  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4913  * valid cases.
4914  * 1.  The arrays have same number of tuples and components. Then each value of
4915  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4916  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4917  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4918  *   component. Then
4919  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4920  * 3.  The arrays have same number of components and one array, say _a2_, has one
4921  *   tuple. Then
4922  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4923  *
4924  * Info on components is copied either from the first array (in the first case) or from
4925  * the array with maximal number of elements (getNbOfElems()).
4926  *  \param [in] a1 - an array to sum up.
4927  *  \param [in] a2 - another array to sum up.
4928  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4929  *          The caller is to delete this result array using decrRef() as it is no more
4930  *          needed.
4931  *  \throw If either \a a1 or \a a2 is NULL.
4932  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4933  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4934  *         none of them has number of tuples or components equal to 1.
4935  */
4936 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4937 {
4938   if(!a1 || !a2)
4939     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4940   int nbOfTuple=a1->getNumberOfTuples();
4941   int nbOfTuple2=a2->getNumberOfTuples();
4942   int nbOfComp=a1->getNumberOfComponents();
4943   int nbOfComp2=a2->getNumberOfComponents();
4944   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4945   if(nbOfTuple==nbOfTuple2)
4946     {
4947       if(nbOfComp==nbOfComp2)
4948         {
4949           ret=DataArrayDouble::New();
4950           ret->alloc(nbOfTuple,nbOfComp);
4951           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4952           ret->copyStringInfoFrom(*a1);
4953         }
4954       else
4955         {
4956           int nbOfCompMin,nbOfCompMax;
4957           const DataArrayDouble *aMin, *aMax;
4958           if(nbOfComp>nbOfComp2)
4959             {
4960               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4961               aMin=a2; aMax=a1;
4962             }
4963           else
4964             {
4965               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4966               aMin=a1; aMax=a2;
4967             }
4968           if(nbOfCompMin==1)
4969             {
4970               ret=DataArrayDouble::New();
4971               ret->alloc(nbOfTuple,nbOfCompMax);
4972               const double *aMinPtr=aMin->getConstPointer();
4973               const double *aMaxPtr=aMax->getConstPointer();
4974               double *res=ret->getPointer();
4975               for(int i=0;i<nbOfTuple;i++)
4976                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4977               ret->copyStringInfoFrom(*aMax);
4978             }
4979           else
4980             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4981         }
4982     }
4983   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4984     {
4985       if(nbOfComp==nbOfComp2)
4986         {
4987           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4988           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4989           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4990           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4991           ret=DataArrayDouble::New();
4992           ret->alloc(nbOfTupleMax,nbOfComp);
4993           double *res=ret->getPointer();
4994           for(int i=0;i<nbOfTupleMax;i++)
4995             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4996           ret->copyStringInfoFrom(*aMax);
4997         }
4998       else
4999         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5000     }
5001   else
5002     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5003   return ret.retn();
5004 }
5005
5006 /*!
5007  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5008  * valid cases.
5009  * 1.  The arrays have same number of tuples and components. Then each value of
5010  *   \a other array is added to the corresponding value of \a this array, i.e.:
5011  *   _a_ [ i, j ] += _other_ [ i, j ].
5012  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5013  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5014  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5015  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5016  *
5017  *  \param [in] other - an array to add to \a this one.
5018  *  \throw If \a other is NULL.
5019  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5020  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5021  *         \a other has number of both tuples and components not equal to 1.
5022  */
5023 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5024 {
5025   if(!other)
5026     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5027   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5028   checkAllocated();
5029   other->checkAllocated();
5030   int nbOfTuple=getNumberOfTuples();
5031   int nbOfTuple2=other->getNumberOfTuples();
5032   int nbOfComp=getNumberOfComponents();
5033   int nbOfComp2=other->getNumberOfComponents();
5034   if(nbOfTuple==nbOfTuple2)
5035     {
5036       if(nbOfComp==nbOfComp2)
5037         {
5038           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5039         }
5040       else if(nbOfComp2==1)
5041         {
5042           double *ptr=getPointer();
5043           const double *ptrc=other->getConstPointer();
5044           for(int i=0;i<nbOfTuple;i++)
5045             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5046         }
5047       else
5048         throw INTERP_KERNEL::Exception(msg);
5049     }
5050   else if(nbOfTuple2==1)
5051     {
5052       if(nbOfComp2==nbOfComp)
5053         {
5054           double *ptr=getPointer();
5055           const double *ptrc=other->getConstPointer();
5056           for(int i=0;i<nbOfTuple;i++)
5057             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5058         }
5059       else
5060         throw INTERP_KERNEL::Exception(msg);
5061     }
5062   else
5063     throw INTERP_KERNEL::Exception(msg);
5064   declareAsNew();
5065 }
5066
5067 /*!
5068  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5069  * valid cases.
5070  * 1.  The arrays have same number of tuples and components. Then each value of
5071  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5072  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5073  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5074  *   component. Then
5075  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5076  * 3.  The arrays have same number of components and one array, say _a2_, has one
5077  *   tuple. Then
5078  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5079  *
5080  * Info on components is copied either from the first array (in the first case) or from
5081  * the array with maximal number of elements (getNbOfElems()).
5082  *  \param [in] a1 - an array to subtract from.
5083  *  \param [in] a2 - an array to subtract.
5084  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5085  *          The caller is to delete this result array using decrRef() as it is no more
5086  *          needed.
5087  *  \throw If either \a a1 or \a a2 is NULL.
5088  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5089  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5090  *         none of them has number of tuples or components equal to 1.
5091  */
5092 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5093 {
5094   if(!a1 || !a2)
5095     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5096   int nbOfTuple1=a1->getNumberOfTuples();
5097   int nbOfTuple2=a2->getNumberOfTuples();
5098   int nbOfComp1=a1->getNumberOfComponents();
5099   int nbOfComp2=a2->getNumberOfComponents();
5100   if(nbOfTuple2==nbOfTuple1)
5101     {
5102       if(nbOfComp1==nbOfComp2)
5103         {
5104           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5105           ret->alloc(nbOfTuple2,nbOfComp1);
5106           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5107           ret->copyStringInfoFrom(*a1);
5108           return ret.retn();
5109         }
5110       else if(nbOfComp2==1)
5111         {
5112           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5113           ret->alloc(nbOfTuple1,nbOfComp1);
5114           const double *a2Ptr=a2->getConstPointer();
5115           const double *a1Ptr=a1->getConstPointer();
5116           double *res=ret->getPointer();
5117           for(int i=0;i<nbOfTuple1;i++)
5118             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5119           ret->copyStringInfoFrom(*a1);
5120           return ret.retn();
5121         }
5122       else
5123         {
5124           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5125           return 0;
5126         }
5127     }
5128   else if(nbOfTuple2==1)
5129     {
5130       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5131       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5132       ret->alloc(nbOfTuple1,nbOfComp1);
5133       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5134       double *pt=ret->getPointer();
5135       for(int i=0;i<nbOfTuple1;i++)
5136         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5137       ret->copyStringInfoFrom(*a1);
5138       return ret.retn();
5139     }
5140   else
5141     {
5142       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5143       return 0;
5144     }
5145 }
5146
5147 /*!
5148  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5149  * valid cases.
5150  * 1.  The arrays have same number of tuples and components. Then each value of
5151  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5152  *   _a_ [ i, j ] -= _other_ [ i, j ].
5153  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5154  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5155  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5156  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5157  *
5158  *  \param [in] other - an array to subtract from \a this one.
5159  *  \throw If \a other is NULL.
5160  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5161  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5162  *         \a other has number of both tuples and components not equal to 1.
5163  */
5164 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5165 {
5166   if(!other)
5167     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5168   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5169   checkAllocated();
5170   other->checkAllocated();
5171   int nbOfTuple=getNumberOfTuples();
5172   int nbOfTuple2=other->getNumberOfTuples();
5173   int nbOfComp=getNumberOfComponents();
5174   int nbOfComp2=other->getNumberOfComponents();
5175   if(nbOfTuple==nbOfTuple2)
5176     {
5177       if(nbOfComp==nbOfComp2)
5178         {
5179           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5180         }
5181       else if(nbOfComp2==1)
5182         {
5183           double *ptr=getPointer();
5184           const double *ptrc=other->getConstPointer();
5185           for(int i=0;i<nbOfTuple;i++)
5186             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5187         }
5188       else
5189         throw INTERP_KERNEL::Exception(msg);
5190     }
5191   else if(nbOfTuple2==1)
5192     {
5193       if(nbOfComp2==nbOfComp)
5194         {
5195           double *ptr=getPointer();
5196           const double *ptrc=other->getConstPointer();
5197           for(int i=0;i<nbOfTuple;i++)
5198             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5199         }
5200       else
5201         throw INTERP_KERNEL::Exception(msg);
5202     }
5203   else
5204     throw INTERP_KERNEL::Exception(msg);
5205   declareAsNew();
5206 }
5207
5208 /*!
5209  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5210  * valid cases.
5211  * 1.  The arrays have same number of tuples and components. Then each value of
5212  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5213  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5214  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5215  *   component. Then
5216  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5217  * 3.  The arrays have same number of components and one array, say _a2_, has one
5218  *   tuple. Then
5219  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5220  *
5221  * Info on components is copied either from the first array (in the first case) or from
5222  * the array with maximal number of elements (getNbOfElems()).
5223  *  \param [in] a1 - a factor array.
5224  *  \param [in] a2 - another factor array.
5225  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5226  *          The caller is to delete this result array using decrRef() as it is no more
5227  *          needed.
5228  *  \throw If either \a a1 or \a a2 is NULL.
5229  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5230  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5231  *         none of them has number of tuples or components equal to 1.
5232  */
5233 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5234 {
5235   if(!a1 || !a2)
5236     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5237   int nbOfTuple=a1->getNumberOfTuples();
5238   int nbOfTuple2=a2->getNumberOfTuples();
5239   int nbOfComp=a1->getNumberOfComponents();
5240   int nbOfComp2=a2->getNumberOfComponents();
5241   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5242   if(nbOfTuple==nbOfTuple2)
5243     {
5244       if(nbOfComp==nbOfComp2)
5245         {
5246           ret=DataArrayDouble::New();
5247           ret->alloc(nbOfTuple,nbOfComp);
5248           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5249           ret->copyStringInfoFrom(*a1);
5250         }
5251       else
5252         {
5253           int nbOfCompMin,nbOfCompMax;
5254           const DataArrayDouble *aMin, *aMax;
5255           if(nbOfComp>nbOfComp2)
5256             {
5257               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5258               aMin=a2; aMax=a1;
5259             }
5260           else
5261             {
5262               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5263               aMin=a1; aMax=a2;
5264             }
5265           if(nbOfCompMin==1)
5266             {
5267               ret=DataArrayDouble::New();
5268               ret->alloc(nbOfTuple,nbOfCompMax);
5269               const double *aMinPtr=aMin->getConstPointer();
5270               const double *aMaxPtr=aMax->getConstPointer();
5271               double *res=ret->getPointer();
5272               for(int i=0;i<nbOfTuple;i++)
5273                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5274               ret->copyStringInfoFrom(*aMax);
5275             }
5276           else
5277             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5278         }
5279     }
5280   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5281     {
5282       if(nbOfComp==nbOfComp2)
5283         {
5284           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5285           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5286           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5287           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5288           ret=DataArrayDouble::New();
5289           ret->alloc(nbOfTupleMax,nbOfComp);
5290           double *res=ret->getPointer();
5291           for(int i=0;i<nbOfTupleMax;i++)
5292             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5293           ret->copyStringInfoFrom(*aMax);
5294         }
5295       else
5296         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5297     }
5298   else
5299     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5300   return ret.retn();
5301 }
5302
5303 /*!
5304  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5305  * valid cases.
5306  * 1.  The arrays have same number of tuples and components. Then each value of
5307  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5308  *   _this_ [ i, j ] *= _other_ [ i, j ].
5309  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5310  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5311  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5312  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5313  *
5314  *  \param [in] other - an array to multiply to \a this one.
5315  *  \throw If \a other is NULL.
5316  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5317  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5318  *         \a other has number of both tuples and components not equal to 1.
5319  */
5320 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5321 {
5322   if(!other)
5323     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5324   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5325   checkAllocated();
5326   other->checkAllocated();
5327   int nbOfTuple=getNumberOfTuples();
5328   int nbOfTuple2=other->getNumberOfTuples();
5329   int nbOfComp=getNumberOfComponents();
5330   int nbOfComp2=other->getNumberOfComponents();
5331   if(nbOfTuple==nbOfTuple2)
5332     {
5333       if(nbOfComp==nbOfComp2)
5334         {
5335           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5336         }
5337       else if(nbOfComp2==1)
5338         {
5339           double *ptr=getPointer();
5340           const double *ptrc=other->getConstPointer();
5341           for(int i=0;i<nbOfTuple;i++)
5342             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5343         }
5344       else
5345         throw INTERP_KERNEL::Exception(msg);
5346     }
5347   else if(nbOfTuple2==1)
5348     {
5349       if(nbOfComp2==nbOfComp)
5350         {
5351           double *ptr=getPointer();
5352           const double *ptrc=other->getConstPointer();
5353           for(int i=0;i<nbOfTuple;i++)
5354             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5355         }
5356       else
5357         throw INTERP_KERNEL::Exception(msg);
5358     }
5359   else
5360     throw INTERP_KERNEL::Exception(msg);
5361   declareAsNew();
5362 }
5363
5364 /*!
5365  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5366  * valid cases.
5367  * 1.  The arrays have same number of tuples and components. Then each value of
5368  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5369  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5370  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5371  *   component. Then
5372  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5373  * 3.  The arrays have same number of components and one array, say _a2_, has one
5374  *   tuple. Then
5375  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5376  *
5377  * Info on components is copied either from the first array (in the first case) or from
5378  * the array with maximal number of elements (getNbOfElems()).
5379  *  \warning No check of division by zero is performed!
5380  *  \param [in] a1 - a numerator array.
5381  *  \param [in] a2 - a denominator array.
5382  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5383  *          The caller is to delete this result array using decrRef() as it is no more
5384  *          needed.
5385  *  \throw If either \a a1 or \a a2 is NULL.
5386  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5387  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5388  *         none of them has number of tuples or components equal to 1.
5389  */
5390 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5391 {
5392   if(!a1 || !a2)
5393     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5394   int nbOfTuple1=a1->getNumberOfTuples();
5395   int nbOfTuple2=a2->getNumberOfTuples();
5396   int nbOfComp1=a1->getNumberOfComponents();
5397   int nbOfComp2=a2->getNumberOfComponents();
5398   if(nbOfTuple2==nbOfTuple1)
5399     {
5400       if(nbOfComp1==nbOfComp2)
5401         {
5402           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5403           ret->alloc(nbOfTuple2,nbOfComp1);
5404           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5405           ret->copyStringInfoFrom(*a1);
5406           return ret.retn();
5407         }
5408       else if(nbOfComp2==1)
5409         {
5410           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5411           ret->alloc(nbOfTuple1,nbOfComp1);
5412           const double *a2Ptr=a2->getConstPointer();
5413           const double *a1Ptr=a1->getConstPointer();
5414           double *res=ret->getPointer();
5415           for(int i=0;i<nbOfTuple1;i++)
5416             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5417           ret->copyStringInfoFrom(*a1);
5418           return ret.retn();
5419         }
5420       else
5421         {
5422           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5423           return 0;
5424         }
5425     }
5426   else if(nbOfTuple2==1)
5427     {
5428       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5429       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5430       ret->alloc(nbOfTuple1,nbOfComp1);
5431       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5432       double *pt=ret->getPointer();
5433       for(int i=0;i<nbOfTuple1;i++)
5434         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5435       ret->copyStringInfoFrom(*a1);
5436       return ret.retn();
5437     }
5438   else
5439     {
5440       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5441       return 0;
5442     }
5443 }
5444
5445 /*!
5446  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5447  * valid cases.
5448  * 1.  The arrays have same number of tuples and components. Then each value of
5449  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5450  *   _a_ [ i, j ] /= _other_ [ i, j ].
5451  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5452  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5453  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5454  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5455  *
5456  *  \warning No check of division by zero is performed!
5457  *  \param [in] other - an array to divide \a this one by.
5458  *  \throw If \a other is NULL.
5459  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5460  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5461  *         \a other has number of both tuples and components not equal to 1.
5462  */
5463 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5464 {
5465   if(!other)
5466     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5467   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5468   checkAllocated();
5469   other->checkAllocated();
5470   int nbOfTuple=getNumberOfTuples();
5471   int nbOfTuple2=other->getNumberOfTuples();
5472   int nbOfComp=getNumberOfComponents();
5473   int nbOfComp2=other->getNumberOfComponents();
5474   if(nbOfTuple==nbOfTuple2)
5475     {
5476       if(nbOfComp==nbOfComp2)
5477         {
5478           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5479         }
5480       else if(nbOfComp2==1)
5481         {
5482           double *ptr=getPointer();
5483           const double *ptrc=other->getConstPointer();
5484           for(int i=0;i<nbOfTuple;i++)
5485             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5486         }
5487       else
5488         throw INTERP_KERNEL::Exception(msg);
5489     }
5490   else if(nbOfTuple2==1)
5491     {
5492       if(nbOfComp2==nbOfComp)
5493         {
5494           double *ptr=getPointer();
5495           const double *ptrc=other->getConstPointer();
5496           for(int i=0;i<nbOfTuple;i++)
5497             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5498         }
5499       else
5500         throw INTERP_KERNEL::Exception(msg);
5501     }
5502   else
5503     throw INTERP_KERNEL::Exception(msg);
5504   declareAsNew();
5505 }
5506
5507 /*!
5508  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5509  * valid cases.
5510  *
5511  *  \param [in] a1 - an array to pow up.
5512  *  \param [in] a2 - another array to sum up.
5513  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5514  *          The caller is to delete this result array using decrRef() as it is no more
5515  *          needed.
5516  *  \throw If either \a a1 or \a a2 is NULL.
5517  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5518  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5519  *  \throw If there is a negative value in \a a1.
5520  */
5521 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5522 {
5523   if(!a1 || !a2)
5524     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5525   int nbOfTuple=a1->getNumberOfTuples();
5526   int nbOfTuple2=a2->getNumberOfTuples();
5527   int nbOfComp=a1->getNumberOfComponents();
5528   int nbOfComp2=a2->getNumberOfComponents();
5529   if(nbOfTuple!=nbOfTuple2)
5530     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5531   if(nbOfComp!=1 || nbOfComp2!=1)
5532     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5533   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5534   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5535   double *ptr=ret->getPointer();
5536   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5537     {
5538       if(*ptr1>=0)
5539         {
5540           *ptr=pow(*ptr1,*ptr2);
5541         }
5542       else
5543         {
5544           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5545           throw INTERP_KERNEL::Exception(oss.str().c_str());
5546         }
5547     }
5548   return ret.retn();
5549 }
5550
5551 /*!
5552  * Apply pow on values of another DataArrayDouble to values of \a this one.
5553  *
5554  *  \param [in] other - an array to pow to \a this one.
5555  *  \throw If \a other is NULL.
5556  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5557  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5558  *  \throw If there is a negative value in \a this.
5559  */
5560 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5561 {
5562   if(!other)
5563     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5564   int nbOfTuple=getNumberOfTuples();
5565   int nbOfTuple2=other->getNumberOfTuples();
5566   int nbOfComp=getNumberOfComponents();
5567   int nbOfComp2=other->getNumberOfComponents();
5568   if(nbOfTuple!=nbOfTuple2)
5569     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5570   if(nbOfComp!=1 || nbOfComp2!=1)
5571     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5572   double *ptr=getPointer();
5573   const double *ptrc=other->begin();
5574   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5575     {
5576       if(*ptr>=0)
5577         *ptr=pow(*ptr,*ptrc);
5578       else
5579         {
5580           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5581           throw INTERP_KERNEL::Exception(oss.str().c_str());
5582         }
5583     }
5584   declareAsNew();
5585 }
5586
5587 /*!
5588  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5589  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5590  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5591  *
5592  * \throw if \a this is not allocated.
5593  * \throw if \a this has not exactly one component.
5594  */
5595 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5596 {
5597   checkAllocated();
5598   if(getNumberOfComponents()!=1)
5599     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5600   int nbt(getNumberOfTuples());
5601   std::vector<bool> ret(nbt);
5602   const double *pt(begin());
5603   for(int i=0;i<nbt;i++)
5604     {
5605       if(fabs(pt[i])<eps)
5606         ret[i]=false;
5607       else if(fabs(pt[i]-1.)<eps)
5608         ret[i]=true;
5609       else
5610         {
5611           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5612           throw INTERP_KERNEL::Exception(oss.str().c_str());
5613         }
5614     }
5615   return ret;
5616 }
5617
5618 /*!
5619  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5620  * Server side.
5621  */
5622 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5623 {
5624   tinyInfo.resize(2);
5625   if(isAllocated())
5626     {
5627       tinyInfo[0]=getNumberOfTuples();
5628       tinyInfo[1]=getNumberOfComponents();
5629     }
5630   else
5631     {
5632       tinyInfo[0]=-1;
5633       tinyInfo[1]=-1;
5634     }
5635 }
5636
5637 /*!
5638  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5639  * Server side.
5640  */
5641 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5642 {
5643   if(isAllocated())
5644     {
5645       int nbOfCompo=getNumberOfComponents();
5646       tinyInfo.resize(nbOfCompo+1);
5647       tinyInfo[0]=getName();
5648       for(int i=0;i<nbOfCompo;i++)
5649         tinyInfo[i+1]=getInfoOnComponent(i);
5650     }
5651   else
5652     {
5653       tinyInfo.resize(1);
5654       tinyInfo[0]=getName();
5655     }
5656 }
5657
5658 /*!
5659  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5660  * This method returns if a feeding is needed.
5661  */
5662 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5663 {
5664   int nbOfTuple=tinyInfoI[0];
5665   int nbOfComp=tinyInfoI[1];
5666   if(nbOfTuple!=-1 || nbOfComp!=-1)
5667     {
5668       alloc(nbOfTuple,nbOfComp);
5669       return true;
5670     }
5671   return false;
5672 }
5673
5674 /*!
5675  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5676  */
5677 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5678 {
5679   setName(tinyInfoS[0]);
5680   if(isAllocated())
5681     {
5682       int nbOfCompo=getNumberOfComponents();
5683       for(int i=0;i<nbOfCompo;i++)
5684         setInfoOnComponent(i,tinyInfoS[i+1]);
5685     }
5686 }
5687
5688 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5689 {
5690   if(_da)
5691     {
5692       _da->incrRef();
5693       if(_da->isAllocated())
5694         {
5695           _nb_comp=da->getNumberOfComponents();
5696           _nb_tuple=da->getNumberOfTuples();
5697           _pt=da->getPointer();
5698         }
5699     }
5700 }
5701
5702 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5703 {
5704   if(_da)
5705     _da->decrRef();
5706 }
5707
5708 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5709 {
5710   if(_tuple_id<_nb_tuple)
5711     {
5712       _tuple_id++;
5713       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5714       _pt+=_nb_comp;
5715       return ret;
5716     }
5717   else
5718     return 0;
5719 }
5720
5721 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5722 {
5723 }
5724
5725
5726 std::string DataArrayDoubleTuple::repr() const
5727 {
5728   std::ostringstream oss; oss.precision(17); oss << "(";
5729   for(int i=0;i<_nb_of_compo-1;i++)
5730     oss << _pt[i] << ", ";
5731   oss << _pt[_nb_of_compo-1] << ")";
5732   return oss.str();
5733 }
5734
5735 double DataArrayDoubleTuple::doubleValue() const
5736 {
5737   if(_nb_of_compo==1)
5738     return *_pt;
5739   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5740 }
5741
5742 /*!
5743  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5744  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5745  * 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
5746  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5747  */
5748 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5749 {
5750   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5751     {
5752       DataArrayDouble *ret=DataArrayDouble::New();
5753       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5754       return ret;
5755     }
5756   else
5757     {
5758       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5759       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5760       throw INTERP_KERNEL::Exception(oss.str().c_str());
5761     }
5762 }
5763
5764 /*!
5765  * Returns a new instance of DataArrayInt. The caller is to delete this array
5766  * using decrRef() as it is no more needed. 
5767  */
5768 DataArrayInt *DataArrayInt::New()
5769 {
5770   return new DataArrayInt;
5771 }
5772
5773 /*!
5774  * Checks if raw data is allocated. Read more on the raw data
5775  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5776  *  \return bool - \a true if the raw data is allocated, \a false else.
5777  */
5778 bool DataArrayInt::isAllocated() const
5779 {
5780   return getConstPointer()!=0;
5781 }
5782
5783 /*!
5784  * Checks if raw data is allocated and throws an exception if it is not the case.
5785  *  \throw If the raw data is not allocated.
5786  */
5787 void DataArrayInt::checkAllocated() const
5788 {
5789   if(!isAllocated())
5790     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5791 }
5792
5793 /*!
5794  * This method desallocated \a this without modification of informations relative to the components.
5795  * After call of this method, DataArrayInt::isAllocated will return false.
5796  * If \a this is already not allocated, \a this is let unchanged.
5797  */
5798 void DataArrayInt::desallocate()
5799 {
5800   _mem.destroy();
5801 }
5802
5803 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5804 {
5805   std::size_t sz(_mem.getNbOfElemAllocated());
5806   sz*=sizeof(int);
5807   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5808 }
5809
5810 /*!
5811  * Returns the only one value in \a this, if and only if number of elements
5812  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5813  *  \return double - the sole value stored in \a this array.
5814  *  \throw If at least one of conditions stated above is not fulfilled.
5815  */
5816 int DataArrayInt::intValue() const
5817 {
5818   if(isAllocated())
5819     {
5820       if(getNbOfElems()==1)
5821         {
5822           return *getConstPointer();
5823         }
5824       else
5825         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5826     }
5827   else
5828     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5829 }
5830
5831 /*!
5832  * Returns an integer value characterizing \a this array, which is useful for a quick
5833  * comparison of many instances of DataArrayInt.
5834  *  \return int - the hash value.
5835  *  \throw If \a this is not allocated.
5836  */
5837 int DataArrayInt::getHashCode() const
5838 {
5839   checkAllocated();
5840   std::size_t nbOfElems=getNbOfElems();
5841   int ret=nbOfElems*65536;
5842   int delta=3;
5843   if(nbOfElems>48)
5844     delta=nbOfElems/8;
5845   int ret0=0;
5846   const int *pt=begin();
5847   for(std::size_t i=0;i<nbOfElems;i+=delta)
5848     ret0+=pt[i] & 0x1FFF;
5849   return ret+ret0;
5850 }
5851
5852 /*!
5853  * Checks the number of tuples.
5854  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5855  *  \throw If \a this is not allocated.
5856  */
5857 bool DataArrayInt::empty() const
5858 {
5859   checkAllocated();
5860   return getNumberOfTuples()==0;
5861 }
5862
5863 /*!
5864  * Returns a full copy of \a this. For more info on copying data arrays see
5865  * \ref MEDCouplingArrayBasicsCopyDeep.
5866  *  \return DataArrayInt * - a new instance of DataArrayInt.
5867  */
5868 DataArrayInt *DataArrayInt::deepCpy() const
5869 {
5870   return new DataArrayInt(*this);
5871 }
5872
5873 /*!
5874  * Returns either a \a deep or \a shallow copy of this array. For more info see
5875  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5876  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5877  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5878  *          == \a true) or \a this instance (if \a dCpy == \a false).
5879  */
5880 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5881 {
5882   if(dCpy)
5883     return deepCpy();
5884   else
5885     {
5886       incrRef();
5887       return const_cast<DataArrayInt *>(this);
5888     }
5889 }
5890
5891 /*!
5892  * Copies all the data from another DataArrayInt. For more info see
5893  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5894  *  \param [in] other - another instance of DataArrayInt to copy data from.
5895  *  \throw If the \a other is not allocated.
5896  */
5897 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5898 {
5899   other.checkAllocated();
5900   int nbOfTuples=other.getNumberOfTuples();
5901   int nbOfComp=other.getNumberOfComponents();
5902   allocIfNecessary(nbOfTuples,nbOfComp);
5903   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5904   int *pt=getPointer();
5905   const int *ptI=other.getConstPointer();
5906   for(std::size_t i=0;i<nbOfElems;i++)
5907     pt[i]=ptI[i];
5908   copyStringInfoFrom(other);
5909 }
5910
5911 /*!
5912  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5913  * 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.
5914  * If \a this has not already been allocated, number of components is set to one.
5915  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5916  * 
5917  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5918  */
5919 void DataArrayInt::reserve(std::size_t nbOfElems)
5920 {
5921   int nbCompo=getNumberOfComponents();
5922   if(nbCompo==1)
5923     {
5924       _mem.reserve(nbOfElems);
5925     }
5926   else if(nbCompo==0)
5927     {
5928       _mem.reserve(nbOfElems);
5929       _info_on_compo.resize(1);
5930     }
5931   else
5932     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5933 }
5934
5935 /*!
5936  * 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
5937  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5938  *
5939  * \param [in] val the value to be added in \a this
5940  * \throw If \a this has already been allocated with number of components different from one.
5941  * \sa DataArrayInt::pushBackValsSilent
5942  */
5943 void DataArrayInt::pushBackSilent(int val)
5944 {
5945   int nbCompo=getNumberOfComponents();
5946   if(nbCompo==1)
5947     _mem.pushBack(val);
5948   else if(nbCompo==0)
5949     {
5950       _info_on_compo.resize(1);
5951       _mem.pushBack(val);
5952     }
5953   else
5954     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5955 }
5956
5957 /*!
5958  * 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
5959  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5960  *
5961  *  \param [in] valsBg - an array of values to push at the end of \this.
5962  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5963  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5964  * \throw If \a this has already been allocated with number of components different from one.
5965  * \sa DataArrayInt::pushBackSilent
5966  */
5967 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5968 {
5969   int nbCompo=getNumberOfComponents();
5970   if(nbCompo==1)
5971     _mem.insertAtTheEnd(valsBg,valsEnd);
5972   else if(nbCompo==0)
5973     {
5974       _info_on_compo.resize(1);
5975       _mem.insertAtTheEnd(valsBg,valsEnd);
5976     }
5977   else
5978     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5979 }
5980
5981 /*!
5982  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5983  * \throw If \a this is already empty.
5984  * \throw If \a this has number of components different from one.
5985  */
5986 int DataArrayInt::popBackSilent()
5987 {
5988   if(getNumberOfComponents()==1)
5989     return _mem.popBack();
5990   else
5991     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5992 }
5993
5994 /*!
5995  * 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.
5996  *
5997  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5998  */
5999 void DataArrayInt::pack() const
6000 {
6001   _mem.pack();
6002 }
6003
6004 /*!
6005  * Allocates the raw data in memory. If exactly as same memory as needed already
6006  * allocated, it is not re-allocated.
6007  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6008  *  \param [in] nbOfCompo - number of components of data to allocate.
6009  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6010  */
6011 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6012 {
6013   if(isAllocated())
6014     {
6015       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6016         alloc(nbOfTuple,nbOfCompo);
6017     }
6018   else
6019     alloc(nbOfTuple,nbOfCompo);
6020 }
6021
6022 /*!
6023  * Allocates the raw data in memory. If the memory was already allocated, then it is
6024  * freed and re-allocated. See an example of this method use
6025  * \ref MEDCouplingArraySteps1WC "here".
6026  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6027  *  \param [in] nbOfCompo - number of components of data to allocate.
6028  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6029  */
6030 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6031 {
6032   if(nbOfTuple<0 || nbOfCompo<0)
6033     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6034   _info_on_compo.resize(nbOfCompo);
6035   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6036   declareAsNew();
6037 }
6038
6039 /*!
6040  * Assign zero to all values in \a this array. To know more on filling arrays see
6041  * \ref MEDCouplingArrayFill.
6042  * \throw If \a this is not allocated.
6043  */
6044 void DataArrayInt::fillWithZero()
6045 {
6046   checkAllocated();
6047   _mem.fillWithValue(0);
6048   declareAsNew();
6049 }
6050
6051 /*!
6052  * Assign \a val to all values in \a this array. To know more on filling arrays see
6053  * \ref MEDCouplingArrayFill.
6054  *  \param [in] val - the value to fill with.
6055  *  \throw If \a this is not allocated.
6056  */
6057 void DataArrayInt::fillWithValue(int val)
6058 {
6059   checkAllocated();
6060   _mem.fillWithValue(val);
6061   declareAsNew();
6062 }
6063
6064 /*!
6065  * Set all values in \a this array so that the i-th element equals to \a init + i
6066  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6067  *  \param [in] init - value to assign to the first element of array.
6068  *  \throw If \a this->getNumberOfComponents() != 1
6069  *  \throw If \a this is not allocated.
6070  */
6071 void DataArrayInt::iota(int init)
6072 {
6073   checkAllocated();
6074   if(getNumberOfComponents()!=1)
6075     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6076   int *ptr=getPointer();
6077   int ntuples=getNumberOfTuples();
6078   for(int i=0;i<ntuples;i++)
6079     ptr[i]=init+i;
6080   declareAsNew();
6081 }
6082
6083 /*!
6084  * Returns a textual and human readable representation of \a this instance of
6085  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6086  *  \return std::string - text describing \a this DataArrayInt.
6087  */
6088 std::string DataArrayInt::repr() const
6089 {
6090   std::ostringstream ret;
6091   reprStream(ret);
6092   return ret.str();
6093 }
6094
6095 std::string DataArrayInt::reprZip() const
6096 {
6097   std::ostringstream ret;
6098   reprZipStream(ret);
6099   return ret.str();
6100 }
6101
6102 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6103 {
6104   static const char SPACE[4]={' ',' ',' ',' '};
6105   checkAllocated();
6106   std::string idt(indent,' ');
6107   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6108   if(byteArr)
6109     {
6110       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6111       if(std::string(type)=="Int32")
6112         {
6113           const char *data(reinterpret_cast<const char *>(begin()));
6114           std::size_t sz(getNbOfElems()*sizeof(int));
6115           byteArr->insertAtTheEnd(data,data+sz);
6116           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6117         }
6118       else if(std::string(type)=="Int8")
6119         {
6120           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6121           std::copy(begin(),end(),(char *)tmp);
6122           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6123           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6124         }
6125       else if(std::string(type)=="UInt8")
6126         {
6127           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6128           std::copy(begin(),end(),(unsigned char *)tmp);
6129           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6130           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6131         }
6132       else
6133         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6134     }
6135   else
6136     {
6137       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6138       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6139     }
6140   ofs << std::endl << idt << "</DataArray>\n";
6141 }
6142
6143 void DataArrayInt::reprStream(std::ostream& stream) const
6144 {
6145   stream << "Name of int array : \"" << _name << "\"\n";
6146   reprWithoutNameStream(stream);
6147 }
6148
6149 void DataArrayInt::reprZipStream(std::ostream& stream) const
6150 {
6151   stream << "Name of int array : \"" << _name << "\"\n";
6152   reprZipWithoutNameStream(stream);
6153 }
6154
6155 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6156 {
6157   DataArray::reprWithoutNameStream(stream);
6158   _mem.repr(getNumberOfComponents(),stream);
6159 }
6160
6161 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6162 {
6163   DataArray::reprWithoutNameStream(stream);
6164   _mem.reprZip(getNumberOfComponents(),stream);
6165 }
6166
6167 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6168 {
6169   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6170   const int *data=getConstPointer();
6171   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6172   if(nbTuples*nbComp>=1)
6173     {
6174       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6175       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6176       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6177       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6178     }
6179   else
6180     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6181   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6182 }
6183
6184 /*!
6185  * Method that gives a quick overvien of \a this for python.
6186  */
6187 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6188 {
6189   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6190   stream << "DataArrayInt C++ instance at " << this << ". ";
6191   if(isAllocated())
6192     {
6193       int nbOfCompo=(int)_info_on_compo.size();
6194       if(nbOfCompo>=1)
6195         {
6196           int nbOfTuples=getNumberOfTuples();
6197           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6198           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6199         }
6200       else
6201         stream << "Number of components : 0.";
6202     }
6203   else
6204     stream << "*** No data allocated ****";
6205 }
6206
6207 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6208 {
6209   const int *data=begin();
6210   int nbOfTuples=getNumberOfTuples();
6211   int nbOfCompo=(int)_info_on_compo.size();
6212   std::ostringstream oss2; oss2 << "[";
6213   std::string oss2Str(oss2.str());
6214   bool isFinished=true;
6215   for(int i=0;i<nbOfTuples && isFinished;i++)
6216     {
6217       if(nbOfCompo>1)
6218         {
6219           oss2 << "(";
6220           for(int j=0;j<nbOfCompo;j++,data++)
6221             {
6222               oss2 << *data;
6223               if(j!=nbOfCompo-1) oss2 << ", ";
6224             }
6225           oss2 << ")";
6226         }
6227       else
6228         oss2 << *data++;
6229       if(i!=nbOfTuples-1) oss2 << ", ";
6230       std::string oss3Str(oss2.str());
6231       if(oss3Str.length()<maxNbOfByteInRepr)
6232         oss2Str=oss3Str;
6233       else
6234         isFinished=false;
6235     }
6236   stream << oss2Str;
6237   if(!isFinished)
6238     stream << "... ";
6239   stream << "]";
6240 }
6241
6242 /*!
6243  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6244  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6245  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6246  *         to \a this array.
6247  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6248  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6249  *  \throw If \a this->getNumberOfComponents() != 1
6250  *  \throw If any value of \a this can't be used as a valid index for 
6251  *         [\a indArrBg, \a indArrEnd).
6252  */
6253 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6254 {
6255   checkAllocated();
6256   if(getNumberOfComponents()!=1)
6257     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6258   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6259   int nbOfTuples=getNumberOfTuples();
6260   int *pt=getPointer();
6261   for(int i=0;i<nbOfTuples;i++,pt++)
6262     {
6263       if(*pt>=0 && *pt<nbElemsIn)
6264         *pt=indArrBg[*pt];
6265       else
6266         {
6267           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6268           throw INTERP_KERNEL::Exception(oss.str().c_str());
6269         }
6270     }
6271   declareAsNew();
6272 }
6273
6274 /*!
6275  * Computes distribution of values of \a this one-dimensional array between given value
6276  * ranges (casts). This method is typically useful for entity number spliting by types,
6277  * for example. 
6278  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6279  *           check of this is be done. If not, the result is not warranted. 
6280  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6281  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6282  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6283  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6284  *         should be more than every value in \a this array.
6285  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6286  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6287  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6288  *         (same number of tuples and components), the caller is to delete 
6289  *         using decrRef() as it is no more needed.
6290  *         This array contains indices of ranges for every value of \a this array. I.e.
6291  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6292  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6293  *         this in which cast it holds.
6294  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6295  *         array, the caller is to delete using decrRef() as it is no more needed.
6296  *         This array contains ranks of values of \a this array within ranges
6297  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6298  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6299  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6300  *         for each tuple its rank inside its cast. The rank is computed as difference
6301  *         between the value and the lowest value of range.
6302  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6303  *         ranges (casts) to which at least one value of \a this array belongs.
6304  *         Or, in other words, this param contains the casts that \a this contains.
6305  *         The caller is to delete this array using decrRef() as it is no more needed.
6306  *
6307  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6308  *            the output of this method will be : 
6309  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6310  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6311  * - \a castsPresent  : [0,1]
6312  *
6313  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6314  * range #1 and its rank within this range is 2; etc.
6315  *
6316  *  \throw If \a this->getNumberOfComponents() != 1.
6317  *  \throw If \a arrEnd - arrBg < 2.
6318  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6319  */
6320 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6321                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6322     {
6323   checkAllocated();
6324   if(getNumberOfComponents()!=1)
6325     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6326   int nbOfTuples=getNumberOfTuples();
6327   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6328   if(nbOfCast<2)
6329     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6330   nbOfCast--;
6331   const int *work=getConstPointer();
6332   typedef std::reverse_iterator<const int *> rintstart;
6333   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6334   rintstart end2(arrBg);
6335   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6336   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6337   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6338   ret1->alloc(nbOfTuples,1);
6339   ret2->alloc(nbOfTuples,1);
6340   int *ret1Ptr=ret1->getPointer();
6341   int *ret2Ptr=ret2->getPointer();
6342   std::set<std::size_t> castsDetected;
6343   for(int i=0;i<nbOfTuples;i++)
6344     {
6345       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6346       std::size_t pos=std::distance(bg,res);
6347       std::size_t pos2=nbOfCast-pos;
6348       if(pos2<nbOfCast)
6349         {
6350           ret1Ptr[i]=(int)pos2;
6351           ret2Ptr[i]=work[i]-arrBg[pos2];
6352           castsDetected.insert(pos2);
6353         }
6354       else
6355         {
6356           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6357           throw INTERP_KERNEL::Exception(oss.str().c_str());
6358         }
6359     }
6360   ret3->alloc((int)castsDetected.size(),1);
6361   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6362   castArr=ret1.retn();
6363   rankInsideCast=ret2.retn();
6364   castsPresent=ret3.retn();
6365     }
6366
6367 /*!
6368  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6369  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6370  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6371  * new value in place \a indArr[ \a v ] is i.
6372  *  \param [in] indArrBg - the array holding indices within the result array to assign
6373  *         indices of values of \a this array pointing to values of \a indArrBg.
6374  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6375  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6376  *  \return DataArrayInt * - the new instance of DataArrayInt.
6377  *          The caller is to delete this result array using decrRef() as it is no more
6378  *          needed.
6379  *  \throw If \a this->getNumberOfComponents() != 1.
6380  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6381  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6382  */
6383 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6384 {
6385   checkAllocated();
6386   if(getNumberOfComponents()!=1)
6387     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6388   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6389   int nbOfTuples=getNumberOfTuples();
6390   const int *pt=getConstPointer();
6391   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6392   ret->alloc(nbOfTuples,1);
6393   ret->fillWithValue(-1);
6394   int *tmp=ret->getPointer();
6395   for(int i=0;i<nbOfTuples;i++,pt++)
6396     {
6397       if(*pt>=0 && *pt<nbElemsIn)
6398         {
6399           int pos=indArrBg[*pt];
6400           if(pos>=0 && pos<nbOfTuples)
6401             tmp[pos]=i;
6402           else
6403             {
6404               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6405               throw INTERP_KERNEL::Exception(oss.str().c_str());
6406             }
6407         }
6408       else
6409         {
6410           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6411           throw INTERP_KERNEL::Exception(oss.str().c_str());
6412         }
6413     }
6414   return ret.retn();
6415 }
6416
6417 /*!
6418  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6419  * from values of \a this array, which is supposed to contain a renumbering map in 
6420  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6421  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6422  *  \param [in] newNbOfElem - the number of tuples in the result array.
6423  *  \return DataArrayInt * - the new instance of DataArrayInt.
6424  *          The caller is to delete this result array using decrRef() as it is no more
6425  *          needed.
6426  * 
6427  *  \if ENABLE_EXAMPLES
6428  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6429  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6430  *  \endif
6431  */
6432 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6433 {
6434   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6435   ret->alloc(newNbOfElem,1);
6436   int nbOfOldNodes=getNumberOfTuples();
6437   const int *old2New=getConstPointer();
6438   int *pt=ret->getPointer();
6439   for(int i=0;i!=nbOfOldNodes;i++)
6440     {
6441       int newp(old2New[i]);
6442       if(newp!=-1)
6443         {
6444           if(newp>=0 && newp<newNbOfElem)
6445             pt[newp]=i;
6446           else
6447             {
6448               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6449               throw INTERP_KERNEL::Exception(oss.str().c_str());
6450             }
6451         }
6452     }
6453   return ret.retn();
6454 }
6455
6456 /*!
6457  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6458  * 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]
6459  */
6460 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6461 {
6462   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6463   ret->alloc(newNbOfElem,1);
6464   int nbOfOldNodes=getNumberOfTuples();
6465   const int *old2New=getConstPointer();
6466   int *pt=ret->getPointer();
6467   for(int i=nbOfOldNodes-1;i>=0;i--)
6468     {
6469       int newp(old2New[i]);
6470       if(newp!=-1)
6471         {
6472           if(newp>=0 && newp<newNbOfElem)
6473             pt[newp]=i;
6474           else
6475             {
6476               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6477               throw INTERP_KERNEL::Exception(oss.str().c_str());
6478             }
6479         }
6480     }
6481   return ret.retn();
6482 }
6483
6484 /*!
6485  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6486  * from values of \a this array, which is supposed to contain a renumbering map in 
6487  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6488  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6489  *  \param [in] newNbOfElem - the number of tuples in the result array.
6490  *  \return DataArrayInt * - the new instance of DataArrayInt.
6491  *          The caller is to delete this result array using decrRef() as it is no more
6492  *          needed.
6493  * 
6494  *  \if ENABLE_EXAMPLES
6495  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6496  *
6497  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6498  *  \endif
6499  */
6500 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6501 {
6502   checkAllocated();
6503   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6504   ret->alloc(oldNbOfElem,1);
6505   const int *new2Old=getConstPointer();
6506   int *pt=ret->getPointer();
6507   std::fill(pt,pt+oldNbOfElem,-1);
6508   int nbOfNewElems=getNumberOfTuples();
6509   for(int i=0;i<nbOfNewElems;i++)
6510     {
6511       int v(new2Old[i]);
6512       if(v>=0 && v<oldNbOfElem)
6513         pt[v]=i;
6514       else
6515         {
6516           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6517           throw INTERP_KERNEL::Exception(oss.str().c_str());
6518         }
6519     }
6520   return ret.retn();
6521 }
6522
6523 /*!
6524  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6525  * mismatch is given.
6526  * 
6527  * \param [in] other the instance to be compared with \a this
6528  * \param [out] reason In case of inequality returns the reason.
6529  * \sa DataArrayInt::isEqual
6530  */
6531 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6532 {
6533   if(!areInfoEqualsIfNotWhy(other,reason))
6534     return false;
6535   return _mem.isEqual(other._mem,0,reason);
6536 }
6537
6538 /*!
6539  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6540  * \ref MEDCouplingArrayBasicsCompare.
6541  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6542  *  \return bool - \a true if the two arrays are equal, \a false else.
6543  */
6544 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6545 {
6546   std::string tmp;
6547   return isEqualIfNotWhy(other,tmp);
6548 }
6549
6550 /*!
6551  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6552  * \ref MEDCouplingArrayBasicsCompare.
6553  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6554  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6555  */
6556 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6557 {
6558   std::string tmp;
6559   return _mem.isEqual(other._mem,0,tmp);
6560 }
6561
6562 /*!
6563  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6564  * performed on sorted value sequences.
6565  * For more info see\ref MEDCouplingArrayBasicsCompare.
6566  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6567  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6568  */
6569 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6570 {
6571   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6572   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6573   a->sort();
6574   b->sort();
6575   return a->isEqualWithoutConsideringStr(*b);
6576 }
6577
6578 /*!
6579  * This method compares content of input vector \a v and \a this.
6580  * 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.
6581  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6582  *
6583  * \param [in] v - the vector of 'flags' to be compared with \a this.
6584  *
6585  * \throw If \a this is not sorted ascendingly.
6586  * \throw If \a this has not exactly one component.
6587  * \throw If \a this is not allocated.
6588  */
6589 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6590 {
6591   checkAllocated();
6592   if(getNumberOfComponents()!=1)
6593     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6594   const int *w(begin()),*end2(end());
6595   int refVal=-std::numeric_limits<int>::max();
6596   int i=0;
6597   std::vector<bool>::const_iterator it(v.begin());
6598   for(;it!=v.end();it++,i++)
6599     {
6600       if(*it)
6601         {
6602           if(w!=end2)
6603             {
6604               if(*w++==i)
6605                 {
6606                   if(i>refVal)
6607                     refVal=i;
6608                   else
6609                     {
6610                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6611                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6612                     }
6613                 }
6614               else
6615                 return false;
6616             }
6617           else
6618             return false;
6619         }
6620     }
6621   return w==end2;
6622 }
6623
6624 /*!
6625  * Sorts values of the array.
6626  *  \param [in] asc - \a true means ascending order, \a false, descending.
6627  *  \throw If \a this is not allocated.
6628  *  \throw If \a this->getNumberOfComponents() != 1.
6629  */
6630 void DataArrayInt::sort(bool asc)
6631 {
6632   checkAllocated();
6633   if(getNumberOfComponents()!=1)
6634     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6635   _mem.sort(asc);
6636   declareAsNew();
6637 }
6638
6639 /*!
6640  * Computes for each tuple the sum of number of components values in the tuple and return it.
6641  * 
6642  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6643  *          same number of tuples as \a this array and one component.
6644  *          The caller is to delete this result array using decrRef() as it is no more
6645  *          needed.
6646  *  \throw If \a this is not allocated.
6647  */
6648 DataArrayInt *DataArrayInt::sumPerTuple() const
6649 {
6650   checkAllocated();
6651   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6652   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6653   ret->alloc(nbOfTuple,1);
6654   const int *src(getConstPointer());
6655   int *dest(ret->getPointer());
6656   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6657     *dest=std::accumulate(src,src+nbOfComp,0);
6658   return ret.retn();
6659 }
6660
6661 /*!
6662  * Reverse the array values.
6663  *  \throw If \a this->getNumberOfComponents() < 1.
6664  *  \throw If \a this is not allocated.
6665  */
6666 void DataArrayInt::reverse()
6667 {
6668   checkAllocated();
6669   _mem.reverse(getNumberOfComponents());
6670   declareAsNew();
6671 }
6672
6673 /*!
6674  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6675  * If not an exception is thrown.
6676  *  \param [in] increasing - if \a true, the array values should be increasing.
6677  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6678  *         increasing arg.
6679  *  \throw If \a this->getNumberOfComponents() != 1.
6680  *  \throw If \a this is not allocated.
6681  */
6682 void DataArrayInt::checkMonotonic(bool increasing) const
6683 {
6684   if(!isMonotonic(increasing))
6685     {
6686       if (increasing)
6687         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6688       else
6689         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6690     }
6691 }
6692
6693 /*!
6694  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6695  *  \param [in] increasing - if \a true, array values should be increasing.
6696  *  \return bool - \a true if values change in accordance with \a increasing arg.
6697  *  \throw If \a this->getNumberOfComponents() != 1.
6698  *  \throw If \a this is not allocated.
6699  */
6700 bool DataArrayInt::isMonotonic(bool increasing) const
6701 {
6702   checkAllocated();
6703   if(getNumberOfComponents()!=1)
6704     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6705   int nbOfElements=getNumberOfTuples();
6706   const int *ptr=getConstPointer();
6707   if(nbOfElements==0)
6708     return true;
6709   int ref=ptr[0];
6710   if(increasing)
6711     {
6712       for(int i=1;i<nbOfElements;i++)
6713         {
6714           if(ptr[i]>=ref)
6715             ref=ptr[i];
6716           else
6717             return false;
6718         }
6719     }
6720   else
6721     {
6722       for(int i=1;i<nbOfElements;i++)
6723         {
6724           if(ptr[i]<=ref)
6725             ref=ptr[i];
6726           else
6727             return false;
6728         }
6729     }
6730   return true;
6731 }
6732
6733 /*!
6734  * This method check that array consistently INCREASING or DECREASING in value.
6735  */
6736 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6737 {
6738   checkAllocated();
6739   if(getNumberOfComponents()!=1)
6740     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6741   int nbOfElements=getNumberOfTuples();
6742   const int *ptr=getConstPointer();
6743   if(nbOfElements==0)
6744     return true;
6745   int ref=ptr[0];
6746   if(increasing)
6747     {
6748       for(int i=1;i<nbOfElements;i++)
6749         {
6750           if(ptr[i]>ref)
6751             ref=ptr[i];
6752           else
6753             return false;
6754         }
6755     }
6756   else
6757     {
6758       for(int i=1;i<nbOfElements;i++)
6759         {
6760           if(ptr[i]<ref)
6761             ref=ptr[i];
6762           else
6763             return false;
6764         }
6765     }
6766   return true;
6767 }
6768
6769 /*!
6770  * This method check that array consistently INCREASING or DECREASING in value.
6771  */
6772 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6773 {
6774   if(!isStrictlyMonotonic(increasing))
6775     {
6776       if (increasing)
6777         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6778       else
6779         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6780     }
6781 }
6782
6783 /*!
6784  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6785  * one-dimensional arrays that must be of the same length. The result array describes
6786  * correspondence between \a this and \a other arrays, so that 
6787  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6788  * not possible because some element in \a other is not in \a this, an exception is thrown.
6789  *  \param [in] other - an array to compute permutation to.
6790  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6791  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6792  * no more needed.
6793  *  \throw If \a this->getNumberOfComponents() != 1.
6794  *  \throw If \a other->getNumberOfComponents() != 1.
6795  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6796  *  \throw If \a other includes a value which is not in \a this array.
6797  * 
6798  *  \if ENABLE_EXAMPLES
6799  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6800  *
6801  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6802  *  \endif
6803  */
6804 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6805 {
6806   checkAllocated();
6807   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6808     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6809   int nbTuple=getNumberOfTuples();
6810   other.checkAllocated();
6811   if(nbTuple!=other.getNumberOfTuples())
6812     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6813   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6814   ret->alloc(nbTuple,1);
6815   ret->fillWithValue(-1);
6816   const int *pt=getConstPointer();
6817   std::map<int,int> mm;
6818   for(int i=0;i<nbTuple;i++)
6819     mm[pt[i]]=i;
6820   pt=other.getConstPointer();
6821   int *retToFill=ret->getPointer();
6822   for(int i=0;i<nbTuple;i++)
6823     {
6824       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6825       if(it==mm.end())
6826         {
6827           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6828           throw INTERP_KERNEL::Exception(oss.str().c_str());
6829         }
6830       retToFill[i]=(*it).second;
6831     }
6832   return ret.retn();
6833 }
6834
6835 /*!
6836  * Sets a C array to be used as raw data of \a this. The previously set info
6837  *  of components is retained and re-sized. 
6838  * For more info see \ref MEDCouplingArraySteps1.
6839  *  \param [in] array - the C array to be used as raw data of \a this.
6840  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6841  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6842  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6843  *                     \c free(\c array ) will be called.
6844  *  \param [in] nbOfTuple - new number of tuples in \a this.
6845  *  \param [in] nbOfCompo - new number of components in \a this.
6846  */
6847 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6848 {
6849   _info_on_compo.resize(nbOfCompo);
6850   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6851   declareAsNew();
6852 }
6853
6854 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6855 {
6856   _info_on_compo.resize(nbOfCompo);
6857   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6858   declareAsNew();
6859 }
6860
6861 /*!
6862  * Returns a new DataArrayInt holding the same values as \a this array but differently
6863  * arranged in memory. If \a this array holds 2 components of 3 values:
6864  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6865  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6866  *  \warning Do not confuse this method with transpose()!
6867  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6868  *          is to delete using decrRef() as it is no more needed.
6869  *  \throw If \a this is not allocated.
6870  */
6871 DataArrayInt *DataArrayInt::fromNoInterlace() const
6872 {
6873   checkAllocated();
6874   if(_mem.isNull())
6875     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6876   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6877   DataArrayInt *ret=DataArrayInt::New();
6878   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6879   return ret;
6880 }
6881
6882 /*!
6883  * Returns a new DataArrayInt holding the same values as \a this array but differently
6884  * arranged in memory. If \a this array holds 2 components of 3 values:
6885  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6886  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6887  *  \warning Do not confuse this method with transpose()!
6888  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6889  *          is to delete using decrRef() as it is no more needed.
6890  *  \throw If \a this is not allocated.
6891  */
6892 DataArrayInt *DataArrayInt::toNoInterlace() const
6893 {
6894   checkAllocated();
6895   if(_mem.isNull())
6896     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6897   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6898   DataArrayInt *ret=DataArrayInt::New();
6899   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6900   return ret;
6901 }
6902
6903 /*!
6904  * Permutes values of \a this array as required by \a old2New array. The values are
6905  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6906  * the same as in \this one.
6907  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6908  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6909  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6910  *     giving a new position for i-th old value.
6911  */
6912 void DataArrayInt::renumberInPlace(const int *old2New)
6913 {
6914   checkAllocated();
6915   int nbTuples=getNumberOfTuples();
6916   int nbOfCompo=getNumberOfComponents();
6917   int *tmp=new int[nbTuples*nbOfCompo];
6918   const int *iptr=getConstPointer();
6919   for(int i=0;i<nbTuples;i++)
6920     {
6921       int v=old2New[i];
6922       if(v>=0 && v<nbTuples)
6923         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6924       else
6925         {
6926           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6927           throw INTERP_KERNEL::Exception(oss.str().c_str());
6928         }
6929     }
6930   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6931   delete [] tmp;
6932   declareAsNew();
6933 }
6934
6935 /*!
6936  * Permutes values of \a this array as required by \a new2Old array. The values are
6937  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6938  * the same as in \this one.
6939  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6940  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6941  *     giving a previous position of i-th new value.
6942  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6943  *          is to delete using decrRef() as it is no more needed.
6944  */
6945 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6946 {
6947   checkAllocated();
6948   int nbTuples=getNumberOfTuples();
6949   int nbOfCompo=getNumberOfComponents();
6950   int *tmp=new int[nbTuples*nbOfCompo];
6951   const int *iptr=getConstPointer();
6952   for(int i=0;i<nbTuples;i++)
6953     {
6954       int v=new2Old[i];
6955       if(v>=0 && v<nbTuples)
6956         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6957       else
6958         {
6959           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6960           throw INTERP_KERNEL::Exception(oss.str().c_str());
6961         }
6962     }
6963   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6964   delete [] tmp;
6965   declareAsNew();
6966 }
6967
6968 /*!
6969  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6970  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6971  * Number of tuples in the result array remains the same as in \this one.
6972  * If a permutation reduction is needed, renumberAndReduce() should be used.
6973  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6974  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6975  *          giving a new position for i-th old value.
6976  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6977  *          is to delete using decrRef() as it is no more needed.
6978  *  \throw If \a this is not allocated.
6979  */
6980 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6981 {
6982   checkAllocated();
6983   int nbTuples=getNumberOfTuples();
6984   int nbOfCompo=getNumberOfComponents();
6985   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6986   ret->alloc(nbTuples,nbOfCompo);
6987   ret->copyStringInfoFrom(*this);
6988   const int *iptr=getConstPointer();
6989   int *optr=ret->getPointer();
6990   for(int i=0;i<nbTuples;i++)
6991     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6992   ret->copyStringInfoFrom(*this);
6993   return ret.retn();
6994 }
6995
6996 /*!
6997  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6998  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6999  * tuples in the result array remains the same as in \this one.
7000  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7001  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7002  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7003  *     giving a previous position of i-th new value.
7004  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7005  *          is to delete using decrRef() as it is no more needed.
7006  */
7007 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7008 {
7009   checkAllocated();
7010   int nbTuples=getNumberOfTuples();
7011   int nbOfCompo=getNumberOfComponents();
7012   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7013   ret->alloc(nbTuples,nbOfCompo);
7014   ret->copyStringInfoFrom(*this);
7015   const int *iptr=getConstPointer();
7016   int *optr=ret->getPointer();
7017   for(int i=0;i<nbTuples;i++)
7018     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7019   ret->copyStringInfoFrom(*this);
7020   return ret.retn();
7021 }
7022
7023 /*!
7024  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7025  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7026  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7027  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7028  * \a old2New[ i ] is negative, is missing from the result array.
7029  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7030  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7031  *     giving a new position for i-th old tuple and giving negative position for
7032  *     for i-th old tuple that should be omitted.
7033  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7034  *          is to delete using decrRef() as it is no more needed.
7035  */
7036 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7037 {
7038   checkAllocated();
7039   int nbTuples=getNumberOfTuples();
7040   int nbOfCompo=getNumberOfComponents();
7041   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7042   ret->alloc(newNbOfTuple,nbOfCompo);
7043   const int *iptr=getConstPointer();
7044   int *optr=ret->getPointer();
7045   for(int i=0;i<nbTuples;i++)
7046     {
7047       int w=old2New[i];
7048       if(w>=0)
7049         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7050     }
7051   ret->copyStringInfoFrom(*this);
7052   return ret.retn();
7053 }
7054
7055 /*!
7056  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7057  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7058  * \a new2OldBg array.
7059  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7060  * This method is equivalent to renumberAndReduce() except that convention in input is
7061  * \c new2old and \b not \c old2new.
7062  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7063  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7064  *              tuple index in \a this array to fill the i-th tuple in the new array.
7065  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7066  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7067  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7068  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7069  *          is to delete using decrRef() as it is no more needed.
7070  */
7071 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7072 {
7073   checkAllocated();
7074   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7075   int nbComp=getNumberOfComponents();
7076   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7077   ret->copyStringInfoFrom(*this);
7078   int *pt=ret->getPointer();
7079   const int *srcPt=getConstPointer();
7080   int i=0;
7081   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7082     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7083   ret->copyStringInfoFrom(*this);
7084   return ret.retn();
7085 }
7086
7087 /*!
7088  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7089  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7090  * \a new2OldBg array.
7091  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7092  * This method is equivalent to renumberAndReduce() except that convention in input is
7093  * \c new2old and \b not \c old2new.
7094  * This method is equivalent to selectByTupleId() except that it prevents coping data
7095  * from behind the end of \a this array.
7096  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7097  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7098  *              tuple index in \a this array to fill the i-th tuple in the new array.
7099  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7100  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7101  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7102  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7103  *          is to delete using decrRef() as it is no more needed.
7104  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7105  */
7106 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7107 {
7108   checkAllocated();
7109   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7110   int nbComp=getNumberOfComponents();
7111   int oldNbOfTuples=getNumberOfTuples();
7112   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7113   ret->copyStringInfoFrom(*this);
7114   int *pt=ret->getPointer();
7115   const int *srcPt=getConstPointer();
7116   int i=0;
7117   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7118     if(*w>=0 && *w<oldNbOfTuples)
7119       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7120     else
7121       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7122   ret->copyStringInfoFrom(*this);
7123   return ret.retn();
7124 }
7125
7126 /*!
7127  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7128  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7129  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7130  * command \c range( \a bg, \a end2, \a step ).
7131  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7132  * not constructed explicitly.
7133  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7134  *  \param [in] bg - index of the first tuple to copy from \a this array.
7135  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7136  *  \param [in] step - index increment to get index of the next tuple to copy.
7137  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7138  *          is to delete using decrRef() as it is no more needed.
7139  *  \sa DataArrayInt::substr.
7140  */
7141 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7142 {
7143   checkAllocated();
7144   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7145   int nbComp=getNumberOfComponents();
7146   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7147   ret->alloc(newNbOfTuples,nbComp);
7148   int *pt=ret->getPointer();
7149   const int *srcPt=getConstPointer()+bg*nbComp;
7150   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7151     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7152   ret->copyStringInfoFrom(*this);
7153   return ret.retn();
7154 }
7155
7156 /*!
7157  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7158  * of tuples specified by \a ranges parameter.
7159  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7160  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7161  *              of tuples in [\c begin,\c end) format.
7162  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7163  *          is to delete using decrRef() as it is no more needed.
7164  *  \throw If \a end < \a begin.
7165  *  \throw If \a end > \a this->getNumberOfTuples().
7166  *  \throw If \a this is not allocated.
7167  */
7168 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7169 {
7170   checkAllocated();
7171   int nbOfComp=getNumberOfComponents();
7172   int nbOfTuplesThis=getNumberOfTuples();
7173   if(ranges.empty())
7174     {
7175       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7176       ret->alloc(0,nbOfComp);
7177       ret->copyStringInfoFrom(*this);
7178       return ret.retn();
7179     }
7180   int ref=ranges.front().first;
7181   int nbOfTuples=0;
7182   bool isIncreasing=true;
7183   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7184     {
7185       if((*it).first<=(*it).second)
7186         {
7187           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7188             {
7189               nbOfTuples+=(*it).second-(*it).first;
7190               if(isIncreasing)
7191                 isIncreasing=ref<=(*it).first;
7192               ref=(*it).second;
7193             }
7194           else
7195             {
7196               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7197               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7198               throw INTERP_KERNEL::Exception(oss.str().c_str());
7199             }
7200         }
7201       else
7202         {
7203           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7204           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7205           throw INTERP_KERNEL::Exception(oss.str().c_str());
7206         }
7207     }
7208   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7209     return deepCpy();
7210   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7211   ret->alloc(nbOfTuples,nbOfComp);
7212   ret->copyStringInfoFrom(*this);
7213   const int *src=getConstPointer();
7214   int *work=ret->getPointer();
7215   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7216     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7217   return ret.retn();
7218 }
7219
7220 /*!
7221  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7222  * This map, if applied to \a this array, would make it sorted. For example, if
7223  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7224  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7225  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7226  * This method is useful for renumbering (in MED file for example). For more info
7227  * on renumbering see \ref MEDCouplingArrayRenumbering.
7228  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7229  *          array using decrRef() as it is no more needed.
7230  *  \throw If \a this is not allocated.
7231  *  \throw If \a this->getNumberOfComponents() != 1.
7232  *  \throw If there are equal values in \a this array.
7233  */
7234 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7235 {
7236   checkAllocated();
7237   if(getNumberOfComponents()!=1)
7238     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7239   int nbTuples=getNumberOfTuples();
7240   const int *pt=getConstPointer();
7241   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7242   DataArrayInt *ret=DataArrayInt::New();
7243   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7244   return ret;
7245 }
7246
7247 /*!
7248  * 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
7249  * input array \a ids2.
7250  * \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.
7251  * 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
7252  * inversely.
7253  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7254  *
7255  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7256  *          array using decrRef() as it is no more needed.
7257  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7258  * 
7259  */
7260 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7261 {
7262   if(!ids1 || !ids2)
7263     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7264   if(!ids1->isAllocated() || !ids2->isAllocated())
7265     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7266   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7267     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7268   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7269     {
7270       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 !";
7271       throw INTERP_KERNEL::Exception(oss.str().c_str());
7272     }
7273   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7274   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7275   p1->sort(true); p2->sort(true);
7276   if(!p1->isEqualWithoutConsideringStr(*p2))
7277     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7278   p1=ids1->checkAndPreparePermutation();
7279   p2=ids2->checkAndPreparePermutation();
7280   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7281   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7282   return p2.retn();
7283 }
7284
7285 /*!
7286  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7287  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7288  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7289  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7290  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7291  * The first of out arrays returns indices of elements of \a this array, grouped by their
7292  * place in the set \a B. The second out array is the index of the first one; it shows how
7293  * many elements of \a A are mapped into each element of \a B. <br>
7294  * For more info on
7295  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7296  * \b Example:
7297  * - \a this: [0,3,2,3,2,2,1,2]
7298  * - \a targetNb: 4
7299  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7300  * - \a arrI: [0,1,2,6,8]
7301  *
7302  * This result means: <br>
7303  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7304  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7305  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7306  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7307  * \a arrI[ 2+1 ]]); <br> etc.
7308  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7309  *         than the maximal value of \a A.
7310  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7311  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7312  *         this array using decrRef() as it is no more needed.
7313  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7314  *         elements of \a this. The caller is to delete this array using decrRef() as it
7315  *         is no more needed.
7316  *  \throw If \a this is not allocated.
7317  *  \throw If \a this->getNumberOfComponents() != 1.
7318  *  \throw If any value in \a this is more or equal to \a targetNb.
7319  */
7320 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7321 {
7322   checkAllocated();
7323   if(getNumberOfComponents()!=1)
7324     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7325   int nbOfTuples=getNumberOfTuples();
7326   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7327   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7328   retI->alloc(targetNb+1,1);
7329   const int *input=getConstPointer();
7330   std::vector< std::vector<int> > tmp(targetNb);
7331   for(int i=0;i<nbOfTuples;i++)
7332     {
7333       int tmp2=input[i];
7334       if(tmp2>=0 && tmp2<targetNb)
7335         tmp[tmp2].push_back(i);
7336       else
7337         {
7338           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7339           throw INTERP_KERNEL::Exception(oss.str().c_str());
7340         }
7341     }
7342   int *retIPtr=retI->getPointer();
7343   *retIPtr=0;
7344   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7345     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7346   if(nbOfTuples!=retI->getIJ(targetNb,0))
7347     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7348   ret->alloc(nbOfTuples,1);
7349   int *retPtr=ret->getPointer();
7350   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7351     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7352   arr=ret.retn();
7353   arrI=retI.retn();
7354 }
7355
7356
7357 /*!
7358  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7359  * from a zip representation of a surjective format (returned e.g. by
7360  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7361  * for example). The result array minimizes the permutation. <br>
7362  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7363  * \b Example: <br>
7364  * - \a nbOfOldTuples: 10 
7365  * - \a arr          : [0,3, 5,7,9]
7366  * - \a arrIBg       : [0,2,5]
7367  * - \a newNbOfTuples: 7
7368  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7369  *
7370  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7371  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7372  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7373  *         (indices of) equal values. Its every element (except the last one) points to
7374  *         the first element of a group of equal values.
7375  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7376  *          arrIBg is \a arrIEnd[ -1 ].
7377  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7378  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7379  *          array using decrRef() as it is no more needed.
7380  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7381  */
7382 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7383 {
7384   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7385   ret->alloc(nbOfOldTuples,1);
7386   int *pt=ret->getPointer();
7387   std::fill(pt,pt+nbOfOldTuples,-1);
7388   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7389   const int *cIPtr=arrIBg;
7390   for(int i=0;i<nbOfGrps;i++)
7391     pt[arr[cIPtr[i]]]=-(i+2);
7392   int newNb=0;
7393   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7394     {
7395       if(pt[iNode]<0)
7396         {
7397           if(pt[iNode]==-1)
7398             pt[iNode]=newNb++;
7399           else
7400             {
7401               int grpId=-(pt[iNode]+2);
7402               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7403                 {
7404                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7405                     pt[arr[j]]=newNb;
7406                   else
7407                     {
7408                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7409                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7410                     }
7411                 }
7412               newNb++;
7413             }
7414         }
7415     }
7416   newNbOfTuples=newNb;
7417   return ret.retn();
7418 }
7419
7420 /*!
7421  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7422  * which if applied to \a this array would make it sorted ascendingly.
7423  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7424  * \b Example: <br>
7425  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7426  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7427  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7428  *
7429  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7430  *          array using decrRef() as it is no more needed.
7431  *  \throw If \a this is not allocated.
7432  *  \throw If \a this->getNumberOfComponents() != 1.
7433  */
7434 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7435 {
7436   checkAllocated();
7437   if(getNumberOfComponents()!=1)
7438     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7439   int nbOfTuples=getNumberOfTuples();
7440   const int *pt=getConstPointer();
7441   std::map<int,int> m;
7442   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7443   ret->alloc(nbOfTuples,1);
7444   int *opt=ret->getPointer();
7445   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7446     {
7447       int val=*pt;
7448       std::map<int,int>::iterator it=m.find(val);
7449       if(it!=m.end())
7450         {
7451           *opt=(*it).second;
7452           (*it).second++;
7453         }
7454       else
7455         {
7456           *opt=0;
7457           m.insert(std::pair<int,int>(val,1));
7458         }
7459     }
7460   int sum=0;
7461   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7462     {
7463       int vt=(*it).second;
7464       (*it).second=sum;
7465       sum+=vt;
7466     }
7467   pt=getConstPointer();
7468   opt=ret->getPointer();
7469   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7470     *opt+=m[*pt];
7471   //
7472   return ret.retn();
7473 }
7474
7475 /*!
7476  * Checks if contents of \a this array are equal to that of an array filled with
7477  * iota(). This method is particularly useful for DataArrayInt instances that represent
7478  * a renumbering array to check the real need in renumbering. 
7479  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7480  *  \throw If \a this is not allocated.
7481  *  \throw If \a this->getNumberOfComponents() != 1.
7482  */
7483 bool DataArrayInt::isIdentity() const
7484 {
7485   checkAllocated();
7486   if(getNumberOfComponents()!=1)
7487     return false;
7488   int nbOfTuples=getNumberOfTuples();
7489   const int *pt=getConstPointer();
7490   for(int i=0;i<nbOfTuples;i++,pt++)
7491     if(*pt!=i)
7492       return false;
7493   return true;
7494 }
7495
7496 /*!
7497  * Checks if all values in \a this array are equal to \a val.
7498  *  \param [in] val - value to check equality of array values to.
7499  *  \return bool - \a true if all values are \a val.
7500  *  \throw If \a this is not allocated.
7501  *  \throw If \a this->getNumberOfComponents() != 1
7502  */
7503 bool DataArrayInt::isUniform(int val) const
7504 {
7505   checkAllocated();
7506   if(getNumberOfComponents()!=1)
7507     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7508   int nbOfTuples=getNumberOfTuples();
7509   const int *w=getConstPointer();
7510   const int *end2=w+nbOfTuples;
7511   for(;w!=end2;w++)
7512     if(*w!=val)
7513       return false;
7514   return true;
7515 }
7516
7517 /*!
7518  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7519  * array to the new one.
7520  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7521  */
7522 DataArrayDouble *DataArrayInt::convertToDblArr() const
7523 {
7524   checkAllocated();
7525   DataArrayDouble *ret=DataArrayDouble::New();
7526   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7527   std::size_t nbOfVals=getNbOfElems();
7528   const int *src=getConstPointer();
7529   double *dest=ret->getPointer();
7530   std::copy(src,src+nbOfVals,dest);
7531   ret->copyStringInfoFrom(*this);
7532   return ret;
7533 }
7534
7535 /*!
7536  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7537  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7538  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7539  * This method is a specialization of selectByTupleId2().
7540  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7541  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7542  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7543  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7544  *          is to delete using decrRef() as it is no more needed.
7545  *  \throw If \a tupleIdBg < 0.
7546  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7547     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7548  *  \sa DataArrayInt::selectByTupleId2
7549  */
7550 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7551 {
7552   checkAllocated();
7553   int nbt=getNumberOfTuples();
7554   if(tupleIdBg<0)
7555     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7556   if(tupleIdBg>nbt)
7557     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7558   int trueEnd=tupleIdEnd;
7559   if(tupleIdEnd!=-1)
7560     {
7561       if(tupleIdEnd>nbt)
7562         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7563     }
7564   else
7565     trueEnd=nbt;
7566   int nbComp=getNumberOfComponents();
7567   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7568   ret->alloc(trueEnd-tupleIdBg,nbComp);
7569   ret->copyStringInfoFrom(*this);
7570   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7571   return ret.retn();
7572 }
7573
7574 /*!
7575  * Changes the number of components within \a this array so that its raw data **does
7576  * not** change, instead splitting this data into tuples changes.
7577  *  \warning This method erases all (name and unit) component info set before!
7578  *  \param [in] newNbOfComp - number of components for \a this array to have.
7579  *  \throw If \a this is not allocated
7580  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7581  *  \throw If \a newNbOfCompo is lower than 1.
7582  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7583  *  \warning This method erases all (name and unit) component info set before!
7584  */
7585 void DataArrayInt::rearrange(int newNbOfCompo)
7586 {
7587   checkAllocated();
7588   if(newNbOfCompo<1)
7589     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7590   std::size_t nbOfElems=getNbOfElems();
7591   if(nbOfElems%newNbOfCompo!=0)
7592     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7593   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7594     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7595   _info_on_compo.clear();
7596   _info_on_compo.resize(newNbOfCompo);
7597   declareAsNew();
7598 }
7599
7600 /*!
7601  * Changes the number of components within \a this array to be equal to its number
7602  * of tuples, and inversely its number of tuples to become equal to its number of 
7603  * components. So that its raw data **does not** change, instead splitting this
7604  * data into tuples changes.
7605  *  \warning This method erases all (name and unit) component info set before!
7606  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7607  *  \throw If \a this is not allocated.
7608  *  \sa rearrange()
7609  */
7610 void DataArrayInt::transpose()
7611 {
7612   checkAllocated();
7613   int nbOfTuples=getNumberOfTuples();
7614   rearrange(nbOfTuples);
7615 }
7616
7617 /*!
7618  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7619  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7620  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7621  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7622  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7623  * components.  
7624  *  \param [in] newNbOfComp - number of components for the new array to have.
7625  *  \param [in] dftValue - value assigned to new values added to the new array.
7626  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7627  *          is to delete using decrRef() as it is no more needed.
7628  *  \throw If \a this is not allocated.
7629  */
7630 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7631 {
7632   checkAllocated();
7633   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7634   ret->alloc(getNumberOfTuples(),newNbOfComp);
7635   const int *oldc=getConstPointer();
7636   int *nc=ret->getPointer();
7637   int nbOfTuples=getNumberOfTuples();
7638   int oldNbOfComp=getNumberOfComponents();
7639   int dim=std::min(oldNbOfComp,newNbOfComp);
7640   for(int i=0;i<nbOfTuples;i++)
7641     {
7642       int j=0;
7643       for(;j<dim;j++)
7644         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7645       for(;j<newNbOfComp;j++)
7646         nc[newNbOfComp*i+j]=dftValue;
7647     }
7648   ret->setName(getName());
7649   for(int i=0;i<dim;i++)
7650     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7651   ret->setName(getName());
7652   return ret.retn();
7653 }
7654
7655 /*!
7656  * Changes number of tuples in the array. If the new number of tuples is smaller
7657  * than the current number the array is truncated, otherwise the array is extended.
7658  *  \param [in] nbOfTuples - new number of tuples. 
7659  *  \throw If \a this is not allocated.
7660  *  \throw If \a nbOfTuples is negative.
7661  */
7662 void DataArrayInt::reAlloc(int nbOfTuples)
7663 {
7664   if(nbOfTuples<0)
7665     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7666   checkAllocated();
7667   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7668   declareAsNew();
7669 }
7670
7671
7672 /*!
7673  * Returns a copy of \a this array composed of selected components.
7674  * The new DataArrayInt has the same number of tuples but includes components
7675  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7676  * can be either less, same or more than \a this->getNbOfElems().
7677  *  \param [in] compoIds - sequence of zero based indices of components to include
7678  *              into the new array.
7679  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7680  *          is to delete using decrRef() as it is no more needed.
7681  *  \throw If \a this is not allocated.
7682  *  \throw If a component index (\a i) is not valid: 
7683  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7684  *
7685  *  \if ENABLE_EXAMPLES
7686  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7687  *  \endif
7688  */
7689 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7690 {
7691   checkAllocated();
7692   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7693   int newNbOfCompo=(int)compoIds.size();
7694   int oldNbOfCompo=getNumberOfComponents();
7695   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7696     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7697   int nbOfTuples=getNumberOfTuples();
7698   ret->alloc(nbOfTuples,newNbOfCompo);
7699   ret->copyPartOfStringInfoFrom(*this,compoIds);
7700   const int *oldc=getConstPointer();
7701   int *nc=ret->getPointer();
7702   for(int i=0;i<nbOfTuples;i++)
7703     for(int j=0;j<newNbOfCompo;j++,nc++)
7704       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7705   return ret.retn();
7706 }
7707
7708 /*!
7709  * Appends components of another array to components of \a this one, tuple by tuple.
7710  * So that the number of tuples of \a this array remains the same and the number of 
7711  * components increases.
7712  *  \param [in] other - the DataArrayInt to append to \a this one.
7713  *  \throw If \a this is not allocated.
7714  *  \throw If \a this and \a other arrays have different number of tuples.
7715  *
7716  *  \if ENABLE_EXAMPLES
7717  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7718  *
7719  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7720  *  \endif
7721  */
7722 void DataArrayInt::meldWith(const DataArrayInt *other)
7723 {
7724   if(!other)
7725     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7726   checkAllocated();
7727   other->checkAllocated();
7728   int nbOfTuples=getNumberOfTuples();
7729   if(nbOfTuples!=other->getNumberOfTuples())
7730     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7731   int nbOfComp1=getNumberOfComponents();
7732   int nbOfComp2=other->getNumberOfComponents();
7733   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7734   int *w=newArr;
7735   const int *inp1=getConstPointer();
7736   const int *inp2=other->getConstPointer();
7737   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7738     {
7739       w=std::copy(inp1,inp1+nbOfComp1,w);
7740       w=std::copy(inp2,inp2+nbOfComp2,w);
7741     }
7742   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7743   std::vector<int> compIds(nbOfComp2);
7744   for(int i=0;i<nbOfComp2;i++)
7745     compIds[i]=nbOfComp1+i;
7746   copyPartOfStringInfoFrom2(compIds,*other);
7747 }
7748
7749 /*!
7750  * Copy all components in a specified order from another DataArrayInt.
7751  * The specified components become the first ones in \a this array.
7752  * Both numerical and textual data is copied. The number of tuples in \a this and
7753  * the other array can be different.
7754  *  \param [in] a - the array to copy data from.
7755  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7756  *              to be copied.
7757  *  \throw If \a a is NULL.
7758  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7759  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7760  *
7761  *  \if ENABLE_EXAMPLES
7762  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7763  *  \endif
7764  */
7765 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7766 {
7767   if(!a)
7768     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7769   checkAllocated();
7770   a->checkAllocated();
7771   copyPartOfStringInfoFrom2(compoIds,*a);
7772   std::size_t partOfCompoSz=compoIds.size();
7773   int nbOfCompo=getNumberOfComponents();
7774   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7775   const int *ac=a->getConstPointer();
7776   int *nc=getPointer();
7777   for(int i=0;i<nbOfTuples;i++)
7778     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7779       nc[nbOfCompo*i+compoIds[j]]=*ac;
7780 }
7781
7782 /*!
7783  * Copy all values from another DataArrayInt into specified tuples and components
7784  * of \a this array. Textual data is not copied.
7785  * The tree parameters defining set of indices of tuples and components are similar to
7786  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7787  *  \param [in] a - the array to copy values from.
7788  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7789  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7790  *              are located.
7791  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7792  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7793  *  \param [in] endComp - index of the component before which the components to assign
7794  *              to are located.
7795  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7796  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7797  *              must be equal to the number of columns to assign to, else an
7798  *              exception is thrown; if \a false, then it is only required that \a
7799  *              a->getNbOfElems() equals to number of values to assign to (this condition
7800  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7801  *              values to assign to is given by following Python expression:
7802  *              \a nbTargetValues = 
7803  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7804  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7805  *  \throw If \a a is NULL.
7806  *  \throw If \a a is not allocated.
7807  *  \throw If \a this is not allocated.
7808  *  \throw If parameters specifying tuples and components to assign to do not give a
7809  *            non-empty range of increasing indices.
7810  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7811  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7812  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7813  *
7814  *  \if ENABLE_EXAMPLES
7815  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7816  *  \endif
7817  */
7818 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7819 {
7820   if(!a)
7821     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7822   const char msg[]="DataArrayInt::setPartOfValues1";
7823   checkAllocated();
7824   a->checkAllocated();
7825   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7826   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7827   int nbComp=getNumberOfComponents();
7828   int nbOfTuples=getNumberOfTuples();
7829   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7830   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7831   bool assignTech=true;
7832   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7833     {
7834       if(strictCompoCompare)
7835         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7836     }
7837   else
7838     {
7839       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7840       assignTech=false;
7841     }
7842   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7843   const int *srcPt=a->getConstPointer();
7844   if(assignTech)
7845     {
7846       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7847         for(int j=0;j<newNbOfComp;j++,srcPt++)
7848           pt[j*stepComp]=*srcPt;
7849     }
7850   else
7851     {
7852       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7853         {
7854           const int *srcPt2=srcPt;
7855           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7856             pt[j*stepComp]=*srcPt2;
7857         }
7858     }
7859 }
7860
7861 /*!
7862  * Assign a given value to values at specified tuples and components of \a this array.
7863  * The tree parameters defining set of indices of tuples and components are similar to
7864  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7865  *  \param [in] a - the value to assign.
7866  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7867  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7868  *              are located.
7869  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7870  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7871  *  \param [in] endComp - index of the component before which the components to assign
7872  *              to are located.
7873  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7874  *  \throw If \a this is not allocated.
7875  *  \throw If parameters specifying tuples and components to assign to, do not give a
7876  *            non-empty range of increasing indices or indices are out of a valid range
7877  *            for \this array.
7878  *
7879  *  \if ENABLE_EXAMPLES
7880  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7881  *  \endif
7882  */
7883 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7884 {
7885   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7886   checkAllocated();
7887   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7888   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7889   int nbComp=getNumberOfComponents();
7890   int nbOfTuples=getNumberOfTuples();
7891   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7892   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7893   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7894   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7895     for(int j=0;j<newNbOfComp;j++)
7896       pt[j*stepComp]=a;
7897 }
7898
7899
7900 /*!
7901  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7902  * components of \a this array. Textual data is not copied.
7903  * The tuples and components to assign to are defined by C arrays of indices.
7904  * There are two *modes of usage*:
7905  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7906  *   of \a a is assigned to its own location within \a this array. 
7907  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7908  *   components of every specified tuple of \a this array. In this mode it is required
7909  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7910  * 
7911  *  \param [in] a - the array to copy values from.
7912  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7913  *              assign values of \a a to.
7914  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7915  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7916  *              \a bgTuples <= \a pi < \a endTuples.
7917  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7918  *              assign values of \a a to.
7919  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7920  *              pointer to a component index <em>(pi)</em> varies as this: 
7921  *              \a bgComp <= \a pi < \a endComp.
7922  *  \param [in] strictCompoCompare - this parameter is checked only if the
7923  *               *mode of usage* is the first; if it is \a true (default), 
7924  *               then \a a->getNumberOfComponents() must be equal 
7925  *               to the number of specified columns, else this is not required.
7926  *  \throw If \a a is NULL.
7927  *  \throw If \a a is not allocated.
7928  *  \throw If \a this is not allocated.
7929  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7930  *         out of a valid range for \a this array.
7931  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7932  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7933  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7934  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7935  *
7936  *  \if ENABLE_EXAMPLES
7937  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7938  *  \endif
7939  */
7940 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7941 {
7942   if(!a)
7943     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7944   const char msg[]="DataArrayInt::setPartOfValues2";
7945   checkAllocated();
7946   a->checkAllocated();
7947   int nbComp=getNumberOfComponents();
7948   int nbOfTuples=getNumberOfTuples();
7949   for(const int *z=bgComp;z!=endComp;z++)
7950     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7951   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7952   int newNbOfComp=(int)std::distance(bgComp,endComp);
7953   bool assignTech=true;
7954   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7955     {
7956       if(strictCompoCompare)
7957         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7958     }
7959   else
7960     {
7961       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7962       assignTech=false;
7963     }
7964   int *pt=getPointer();
7965   const int *srcPt=a->getConstPointer();
7966   if(assignTech)
7967     {    
7968       for(const int *w=bgTuples;w!=endTuples;w++)
7969         {
7970           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7971           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7972             {    
7973               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7974             }
7975         }
7976     }
7977   else
7978     {
7979       for(const int *w=bgTuples;w!=endTuples;w++)
7980         {
7981           const int *srcPt2=srcPt;
7982           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7983           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7984             {    
7985               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7986             }
7987         }
7988     }
7989 }
7990
7991 /*!
7992  * Assign a given value to values at specified tuples and components of \a this array.
7993  * The tuples and components to assign to are defined by C arrays of indices.
7994  *  \param [in] a - the value to assign.
7995  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7996  *              assign \a a to.
7997  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7998  *              pointer to a tuple index (\a pi) varies as this: 
7999  *              \a bgTuples <= \a pi < \a endTuples.
8000  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8001  *              assign \a a to.
8002  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8003  *              pointer to a component index (\a pi) varies as this: 
8004  *              \a bgComp <= \a pi < \a endComp.
8005  *  \throw If \a this is not allocated.
8006  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8007  *         out of a valid range for \a this array.
8008  *
8009  *  \if ENABLE_EXAMPLES
8010  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8011  *  \endif
8012  */
8013 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8014 {
8015   checkAllocated();
8016   int nbComp=getNumberOfComponents();
8017   int nbOfTuples=getNumberOfTuples();
8018   for(const int *z=bgComp;z!=endComp;z++)
8019     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8020   int *pt=getPointer();
8021   for(const int *w=bgTuples;w!=endTuples;w++)
8022     for(const int *z=bgComp;z!=endComp;z++)
8023       {
8024         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8025         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8026       }
8027 }
8028
8029 /*!
8030  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8031  * components of \a this array. Textual data is not copied.
8032  * The tuples to assign to are defined by a C array of indices.
8033  * The components to assign to are defined by three values similar to parameters of
8034  * the Python function \c range(\c start,\c stop,\c step).
8035  * There are two *modes of usage*:
8036  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8037  *   of \a a is assigned to its own location within \a this array. 
8038  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8039  *   components of every specified tuple of \a this array. In this mode it is required
8040  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8041  *
8042  *  \param [in] a - the array to copy values from.
8043  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8044  *              assign values of \a a to.
8045  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8046  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8047  *              \a bgTuples <= \a pi < \a endTuples.
8048  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8049  *  \param [in] endComp - index of the component before which the components to assign
8050  *              to are located.
8051  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8052  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8053  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8054  *               then \a a->getNumberOfComponents() must be equal 
8055  *               to the number of specified columns, else this is not required.
8056  *  \throw If \a a is NULL.
8057  *  \throw If \a a is not allocated.
8058  *  \throw If \a this is not allocated.
8059  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8060  *         \a this array.
8061  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8062  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8063  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8064  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8065  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8066  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8067  *  \throw If parameters specifying components to assign to, do not give a
8068  *            non-empty range of increasing indices or indices are out of a valid range
8069  *            for \this array.
8070  *
8071  *  \if ENABLE_EXAMPLES
8072  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8073  *  \endif
8074  */
8075 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8076 {
8077   if(!a)
8078     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8079   const char msg[]="DataArrayInt::setPartOfValues3";
8080   checkAllocated();
8081   a->checkAllocated();
8082   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8083   int nbComp=getNumberOfComponents();
8084   int nbOfTuples=getNumberOfTuples();
8085   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8086   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8087   bool assignTech=true;
8088   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8089     {
8090       if(strictCompoCompare)
8091         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8092     }
8093   else
8094     {
8095       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8096       assignTech=false;
8097     }
8098   int *pt=getPointer()+bgComp;
8099   const int *srcPt=a->getConstPointer();
8100   if(assignTech)
8101     {
8102       for(const int *w=bgTuples;w!=endTuples;w++)
8103         for(int j=0;j<newNbOfComp;j++,srcPt++)
8104           {
8105             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8106             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8107           }
8108     }
8109   else
8110     {
8111       for(const int *w=bgTuples;w!=endTuples;w++)
8112         {
8113           const int *srcPt2=srcPt;
8114           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8115             {
8116               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8117               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8118             }
8119         }
8120     }
8121 }
8122
8123 /*!
8124  * Assign a given value to values at specified tuples and components of \a this array.
8125  * The tuples to assign to are defined by a C array of indices.
8126  * The components to assign to are defined by three values similar to parameters of
8127  * the Python function \c range(\c start,\c stop,\c step).
8128  *  \param [in] a - the value to assign.
8129  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8130  *              assign \a a to.
8131  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8132  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8133  *              \a bgTuples <= \a pi < \a endTuples.
8134  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8135  *  \param [in] endComp - index of the component before which the components to assign
8136  *              to are located.
8137  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8138  *  \throw If \a this is not allocated.
8139  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8140  *         \a this array.
8141  *  \throw If parameters specifying components to assign to, do not give a
8142  *            non-empty range of increasing indices or indices are out of a valid range
8143  *            for \this array.
8144  *
8145  *  \if ENABLE_EXAMPLES
8146  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8147  *  \endif
8148  */
8149 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8150 {
8151   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8152   checkAllocated();
8153   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8154   int nbComp=getNumberOfComponents();
8155   int nbOfTuples=getNumberOfTuples();
8156   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8157   int *pt=getPointer()+bgComp;
8158   for(const int *w=bgTuples;w!=endTuples;w++)
8159     for(int j=0;j<newNbOfComp;j++)
8160       {
8161         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8162         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8163       }
8164 }
8165
8166 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8167 {
8168   if(!a)
8169     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8170   const char msg[]="DataArrayInt::setPartOfValues4";
8171   checkAllocated();
8172   a->checkAllocated();
8173   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8174   int newNbOfComp=(int)std::distance(bgComp,endComp);
8175   int nbComp=getNumberOfComponents();
8176   for(const int *z=bgComp;z!=endComp;z++)
8177     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8178   int nbOfTuples=getNumberOfTuples();
8179   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8180   bool assignTech=true;
8181   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8182     {
8183       if(strictCompoCompare)
8184         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8185     }
8186   else
8187     {
8188       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8189       assignTech=false;
8190     }
8191   const int *srcPt=a->getConstPointer();
8192   int *pt=getPointer()+bgTuples*nbComp;
8193   if(assignTech)
8194     {
8195       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8196         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8197           pt[*z]=*srcPt;
8198     }
8199   else
8200     {
8201       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8202         {
8203           const int *srcPt2=srcPt;
8204           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8205             pt[*z]=*srcPt2;
8206         }
8207     }
8208 }
8209
8210 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8211 {
8212   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8213   checkAllocated();
8214   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8215   int nbComp=getNumberOfComponents();
8216   for(const int *z=bgComp;z!=endComp;z++)
8217     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8218   int nbOfTuples=getNumberOfTuples();
8219   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8220   int *pt=getPointer()+bgTuples*nbComp;
8221   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8222     for(const int *z=bgComp;z!=endComp;z++)
8223       pt[*z]=a;
8224 }
8225
8226 /*!
8227  * Copy some tuples from another DataArrayInt into specified tuples
8228  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8229  * components.
8230  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8231  * All components of selected tuples are copied.
8232  *  \param [in] a - the array to copy values from.
8233  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8234  *              target tuples of \a this. \a tuplesSelec has two components, and the
8235  *              first component specifies index of the source tuple and the second
8236  *              one specifies index of the target tuple.
8237  *  \throw If \a this is not allocated.
8238  *  \throw If \a a is NULL.
8239  *  \throw If \a a is not allocated.
8240  *  \throw If \a tuplesSelec is NULL.
8241  *  \throw If \a tuplesSelec is not allocated.
8242  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8243  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8244  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8245  *         the corresponding (\a this or \a a) array.
8246  */
8247 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8248 {
8249   if(!a || !tuplesSelec)
8250     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8251   checkAllocated();
8252   a->checkAllocated();
8253   tuplesSelec->checkAllocated();
8254   int nbOfComp=getNumberOfComponents();
8255   if(nbOfComp!=a->getNumberOfComponents())
8256     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8257   if(tuplesSelec->getNumberOfComponents()!=2)
8258     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8259   int thisNt=getNumberOfTuples();
8260   int aNt=a->getNumberOfTuples();
8261   int *valsToSet=getPointer();
8262   const int *valsSrc=a->getConstPointer();
8263   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8264     {
8265       if(tuple[1]>=0 && tuple[1]<aNt)
8266         {
8267           if(tuple[0]>=0 && tuple[0]<thisNt)
8268             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8269           else
8270             {
8271               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8272               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8273               throw INTERP_KERNEL::Exception(oss.str().c_str());
8274             }
8275         }
8276       else
8277         {
8278           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8279           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8280           throw INTERP_KERNEL::Exception(oss.str().c_str());
8281         }
8282     }
8283 }
8284
8285 /*!
8286  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8287  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8288  * components.
8289  * The tuples to assign to are defined by index of the first tuple, and
8290  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8291  * The tuples to copy are defined by values of a DataArrayInt.
8292  * All components of selected tuples are copied.
8293  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8294  *              values to.
8295  *  \param [in] aBase - the array to copy values from.
8296  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8297  *  \throw If \a this is not allocated.
8298  *  \throw If \a aBase is NULL.
8299  *  \throw If \a aBase is not allocated.
8300  *  \throw If \a tuplesSelec is NULL.
8301  *  \throw If \a tuplesSelec is not allocated.
8302  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8303  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8304  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8305  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8306  *         \a aBase array.
8307  */
8308 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8309 {
8310   if(!aBase || !tuplesSelec)
8311     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8312   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8313   if(!a)
8314     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8315   checkAllocated();
8316   a->checkAllocated();
8317   tuplesSelec->checkAllocated();
8318   int nbOfComp=getNumberOfComponents();
8319   if(nbOfComp!=a->getNumberOfComponents())
8320     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8321   if(tuplesSelec->getNumberOfComponents()!=1)
8322     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8323   int thisNt=getNumberOfTuples();
8324   int aNt=a->getNumberOfTuples();
8325   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8326   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8327   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8328     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8329   const int *valsSrc=a->getConstPointer();
8330   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8331     {
8332       if(*tuple>=0 && *tuple<aNt)
8333         {
8334           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8335         }
8336       else
8337         {
8338           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8339           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8340           throw INTERP_KERNEL::Exception(oss.str().c_str());
8341         }
8342     }
8343 }
8344
8345 /*!
8346  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8347  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8348  * components.
8349  * The tuples to copy are defined by three values similar to parameters of
8350  * the Python function \c range(\c start,\c stop,\c step).
8351  * The tuples to assign to are defined by index of the first tuple, and
8352  * their number is defined by number of tuples to copy.
8353  * All components of selected tuples are copied.
8354  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8355  *              values to.
8356  *  \param [in] aBase - the array to copy values from.
8357  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8358  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8359  *              are located.
8360  *  \param [in] step - index increment to get index of the next tuple to copy.
8361  *  \throw If \a this is not allocated.
8362  *  \throw If \a aBase is NULL.
8363  *  \throw If \a aBase is not allocated.
8364  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8365  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8366  *  \throw If parameters specifying tuples to copy, do not give a
8367  *            non-empty range of increasing indices or indices are out of a valid range
8368  *            for the array \a aBase.
8369  */
8370 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8371 {
8372   if(!aBase)
8373     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8374   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8375   if(!a)
8376     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8377   checkAllocated();
8378   a->checkAllocated();
8379   int nbOfComp=getNumberOfComponents();
8380   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8381   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8382   if(nbOfComp!=a->getNumberOfComponents())
8383     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8384   int thisNt=getNumberOfTuples();
8385   int aNt=a->getNumberOfTuples();
8386   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8387   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8388     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8389   if(end2>aNt)
8390     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8391   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8392   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8393     {
8394       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8395     }
8396 }
8397
8398 /*!
8399  * Returns a value located at specified tuple and component.
8400  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8401  * parameters is checked. So this method is safe but expensive if used to go through
8402  * all values of \a this.
8403  *  \param [in] tupleId - index of tuple of interest.
8404  *  \param [in] compoId - index of component of interest.
8405  *  \return double - value located by \a tupleId and \a compoId.
8406  *  \throw If \a this is not allocated.
8407  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8408  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8409  */
8410 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8411 {
8412   checkAllocated();
8413   if(tupleId<0 || tupleId>=getNumberOfTuples())
8414     {
8415       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8416       throw INTERP_KERNEL::Exception(oss.str().c_str());
8417     }
8418   if(compoId<0 || compoId>=getNumberOfComponents())
8419     {
8420       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8421       throw INTERP_KERNEL::Exception(oss.str().c_str());
8422     }
8423   return _mem[tupleId*_info_on_compo.size()+compoId];
8424 }
8425
8426 /*!
8427  * Returns the first value of \a this. 
8428  *  \return int - the last value of \a this array.
8429  *  \throw If \a this is not allocated.
8430  *  \throw If \a this->getNumberOfComponents() != 1.
8431  *  \throw If \a this->getNumberOfTuples() < 1.
8432  */
8433 int DataArrayInt::front() const
8434 {
8435   checkAllocated();
8436   if(getNumberOfComponents()!=1)
8437     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8438   int nbOfTuples=getNumberOfTuples();
8439   if(nbOfTuples<1)
8440     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8441   return *(getConstPointer());
8442 }
8443
8444 /*!
8445  * Returns the last value of \a this. 
8446  *  \return int - the last value of \a this array.
8447  *  \throw If \a this is not allocated.
8448  *  \throw If \a this->getNumberOfComponents() != 1.
8449  *  \throw If \a this->getNumberOfTuples() < 1.
8450  */
8451 int DataArrayInt::back() const
8452 {
8453   checkAllocated();
8454   if(getNumberOfComponents()!=1)
8455     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8456   int nbOfTuples=getNumberOfTuples();
8457   if(nbOfTuples<1)
8458     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8459   return *(getConstPointer()+nbOfTuples-1);
8460 }
8461
8462 /*!
8463  * Assign pointer to one array to a pointer to another appay. Reference counter of
8464  * \a arrayToSet is incremented / decremented.
8465  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8466  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8467  */
8468 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8469 {
8470   if(newArray!=arrayToSet)
8471     {
8472       if(arrayToSet)
8473         arrayToSet->decrRef();
8474       arrayToSet=newArray;
8475       if(arrayToSet)
8476         arrayToSet->incrRef();
8477     }
8478 }
8479
8480 DataArrayIntIterator *DataArrayInt::iterator()
8481 {
8482   return new DataArrayIntIterator(this);
8483 }
8484
8485 /*!
8486  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8487  * given one.
8488  *  \param [in] val - the value to find within \a this.
8489  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8490  *          array using decrRef() as it is no more needed.
8491  *  \throw If \a this is not allocated.
8492  *  \throw If \a this->getNumberOfComponents() != 1.
8493  *  \sa DataArrayInt::getIdsEqualTuple
8494  */
8495 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8496 {
8497   checkAllocated();
8498   if(getNumberOfComponents()!=1)
8499     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8500   const int *cptr(getConstPointer());
8501   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8502   int nbOfTuples=getNumberOfTuples();
8503   for(int i=0;i<nbOfTuples;i++,cptr++)
8504     if(*cptr==val)
8505       ret->pushBackSilent(i);
8506   return ret.retn();
8507 }
8508
8509 /*!
8510  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8511  * equal to a given one. 
8512  *  \param [in] val - the value to ignore within \a this.
8513  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8514  *          array using decrRef() as it is no more needed.
8515  *  \throw If \a this is not allocated.
8516  *  \throw If \a this->getNumberOfComponents() != 1.
8517  */
8518 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8519 {
8520   checkAllocated();
8521   if(getNumberOfComponents()!=1)
8522     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8523   const int *cptr(getConstPointer());
8524   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8525   int nbOfTuples=getNumberOfTuples();
8526   for(int i=0;i<nbOfTuples;i++,cptr++)
8527     if(*cptr!=val)
8528       ret->pushBackSilent(i);
8529   return ret.retn();
8530 }
8531
8532 /*!
8533  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8534  * This method is an extension of  DataArrayInt::getIdsEqual method.
8535  *
8536  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8537  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8538  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8539  *          array using decrRef() as it is no more needed.
8540  *  \throw If \a this is not allocated.
8541  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8542  * \throw If \a this->getNumberOfComponents() is equal to 0.
8543  * \sa DataArrayInt::getIdsEqual
8544  */
8545 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8546 {
8547   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8548   checkAllocated();
8549   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8550     {
8551       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8552       throw INTERP_KERNEL::Exception(oss.str().c_str());
8553     }
8554   if(nbOfCompoExp==0)
8555     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8556   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8557   const int *bg(begin()),*end2(end()),*work(begin());
8558   while(work!=end2)
8559     {
8560       work=std::search(work,end2,tupleBg,tupleEnd);
8561       if(work!=end2)
8562         {
8563           std::size_t pos(std::distance(bg,work));
8564           if(pos%nbOfCompoExp==0)
8565             ret->pushBackSilent(pos/nbOfCompoExp);
8566           work++;
8567         }
8568     }
8569   return ret.retn();
8570 }
8571
8572 /*!
8573  * Assigns \a newValue to all elements holding \a oldValue within \a this
8574  * one-dimensional array.
8575  *  \param [in] oldValue - the value to replace.
8576  *  \param [in] newValue - the value to assign.
8577  *  \return int - number of replacements performed.
8578  *  \throw If \a this is not allocated.
8579  *  \throw If \a this->getNumberOfComponents() != 1.
8580  */
8581 int DataArrayInt::changeValue(int oldValue, int newValue)
8582 {
8583   checkAllocated();
8584   if(getNumberOfComponents()!=1)
8585     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8586   int *start=getPointer();
8587   int *end2=start+getNbOfElems();
8588   int ret=0;
8589   for(int *val=start;val!=end2;val++)
8590     {
8591       if(*val==oldValue)
8592         {
8593           *val=newValue;
8594           ret++;
8595         }
8596     }
8597   return ret;
8598 }
8599
8600 /*!
8601  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8602  * one of given values.
8603  *  \param [in] valsBg - an array of values to find within \a this array.
8604  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8605  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8606  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8607  *          array using decrRef() as it is no more needed.
8608  *  \throw If \a this->getNumberOfComponents() != 1.
8609  */
8610 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8611 {
8612   if(getNumberOfComponents()!=1)
8613     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8614   std::set<int> vals2(valsBg,valsEnd);
8615   const int *cptr=getConstPointer();
8616   std::vector<int> res;
8617   int nbOfTuples=getNumberOfTuples();
8618   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8619   for(int i=0;i<nbOfTuples;i++,cptr++)
8620     if(vals2.find(*cptr)!=vals2.end())
8621       ret->pushBackSilent(i);
8622   return ret.retn();
8623 }
8624
8625 /*!
8626  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8627  * equal to any of given values.
8628  *  \param [in] valsBg - an array of values to ignore within \a this array.
8629  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8630  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8631  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8632  *          array using decrRef() as it is no more needed.
8633  *  \throw If \a this->getNumberOfComponents() != 1.
8634  */
8635 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8636 {
8637   if(getNumberOfComponents()!=1)
8638     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8639   std::set<int> vals2(valsBg,valsEnd);
8640   const int *cptr=getConstPointer();
8641   std::vector<int> res;
8642   int nbOfTuples=getNumberOfTuples();
8643   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8644   for(int i=0;i<nbOfTuples;i++,cptr++)
8645     if(vals2.find(*cptr)==vals2.end())
8646       ret->pushBackSilent(i);
8647   return ret.retn();
8648 }
8649
8650 /*!
8651  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8652  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8653  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8654  * If any the tuple id is returned. If not -1 is returned.
8655  * 
8656  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8657  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8658  *
8659  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8660  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8661  */
8662 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8663 {
8664   checkAllocated();
8665   int nbOfCompo=getNumberOfComponents();
8666   if(nbOfCompo==0)
8667     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8668   if(nbOfCompo!=(int)tupl.size())
8669     {
8670       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8671       throw INTERP_KERNEL::Exception(oss.str().c_str());
8672     }
8673   const int *cptr=getConstPointer();
8674   std::size_t nbOfVals=getNbOfElems();
8675   for(const int *work=cptr;work!=cptr+nbOfVals;)
8676     {
8677       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8678       if(work!=cptr+nbOfVals)
8679         {
8680           if(std::distance(cptr,work)%nbOfCompo!=0)
8681             work++;
8682           else
8683             return std::distance(cptr,work)/nbOfCompo;
8684         }
8685     }
8686   return -1;
8687 }
8688
8689 /*!
8690  * This method searches the sequence specified in input parameter \b vals in \b this.
8691  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8692  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8693  * \sa DataArrayInt::locateTuple
8694  */
8695 int DataArrayInt::search(const std::vector<int>& vals) const
8696 {
8697   checkAllocated();
8698   int nbOfCompo=getNumberOfComponents();
8699   if(nbOfCompo!=1)
8700     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8701   const int *cptr=getConstPointer();
8702   std::size_t nbOfVals=getNbOfElems();
8703   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8704   if(loc!=cptr+nbOfVals)
8705     return std::distance(cptr,loc);
8706   return -1;
8707 }
8708
8709 /*!
8710  * This method expects to be called when number of components of this is equal to one.
8711  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8712  * If not any tuple contains \b value -1 is returned.
8713  * \sa DataArrayInt::presenceOfValue
8714  */
8715 int DataArrayInt::locateValue(int value) const
8716 {
8717   checkAllocated();
8718   if(getNumberOfComponents()!=1)
8719     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8720   const int *cptr=getConstPointer();
8721   int nbOfTuples=getNumberOfTuples();
8722   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8723   if(ret!=cptr+nbOfTuples)
8724     return std::distance(cptr,ret);
8725   return -1;
8726 }
8727
8728 /*!
8729  * This method expects to be called when number of components of this is equal to one.
8730  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8731  * If not any tuple contains one of the values contained in 'vals' false is returned.
8732  * \sa DataArrayInt::presenceOfValue
8733  */
8734 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8735 {
8736   checkAllocated();
8737   if(getNumberOfComponents()!=1)
8738     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8739   std::set<int> vals2(vals.begin(),vals.end());
8740   const int *cptr=getConstPointer();
8741   int nbOfTuples=getNumberOfTuples();
8742   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8743     if(vals2.find(*w)!=vals2.end())
8744       return std::distance(cptr,w);
8745   return -1;
8746 }
8747
8748 /*!
8749  * This method returns the number of values in \a this that are equals to input parameter \a value.
8750  * This method only works for single component array.
8751  *
8752  * \return a value in [ 0, \c this->getNumberOfTuples() )
8753  *
8754  * \throw If \a this is not allocated
8755  *
8756  */
8757 int DataArrayInt::count(int value) const
8758 {
8759   int ret=0;
8760   checkAllocated();
8761   if(getNumberOfComponents()!=1)
8762     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8763   const int *vals=begin();
8764   int nbOfTuples=getNumberOfTuples();
8765   for(int i=0;i<nbOfTuples;i++,vals++)
8766     if(*vals==value)
8767       ret++;
8768   return ret;
8769 }
8770
8771 /*!
8772  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8773  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8774  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8775  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8776  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8777  * \sa DataArrayInt::locateTuple
8778  */
8779 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8780 {
8781   return locateTuple(tupl)!=-1;
8782 }
8783
8784
8785 /*!
8786  * Returns \a true if a given value is present within \a this one-dimensional array.
8787  *  \param [in] value - the value to find within \a this array.
8788  *  \return bool - \a true in case if \a value is present within \a this array.
8789  *  \throw If \a this is not allocated.
8790  *  \throw If \a this->getNumberOfComponents() != 1.
8791  *  \sa locateValue()
8792  */
8793 bool DataArrayInt::presenceOfValue(int value) const
8794 {
8795   return locateValue(value)!=-1;
8796 }
8797
8798 /*!
8799  * This method expects to be called when number of components of this is equal to one.
8800  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8801  * If not any tuple contains one of the values contained in 'vals' false is returned.
8802  * \sa DataArrayInt::locateValue
8803  */
8804 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8805 {
8806   return locateValue(vals)!=-1;
8807 }
8808
8809 /*!
8810  * Accumulates values of each component of \a this array.
8811  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8812  *         by the caller, that is filled by this method with sum value for each
8813  *         component.
8814  *  \throw If \a this is not allocated.
8815  */
8816 void DataArrayInt::accumulate(int *res) const
8817 {
8818   checkAllocated();
8819   const int *ptr=getConstPointer();
8820   int nbTuple=getNumberOfTuples();
8821   int nbComps=getNumberOfComponents();
8822   std::fill(res,res+nbComps,0);
8823   for(int i=0;i<nbTuple;i++)
8824     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8825 }
8826
8827 int DataArrayInt::accumulate(int compId) const
8828 {
8829   checkAllocated();
8830   const int *ptr=getConstPointer();
8831   int nbTuple=getNumberOfTuples();
8832   int nbComps=getNumberOfComponents();
8833   if(compId<0 || compId>=nbComps)
8834     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8835   int ret=0;
8836   for(int i=0;i<nbTuple;i++)
8837     ret+=ptr[i*nbComps+compId];
8838   return ret;
8839 }
8840
8841 /*!
8842  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8843  * The returned array will have same number of components than \a this and number of tuples equal to
8844  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8845  *
8846  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8847  *
8848  * \param [in] bgOfIndex - begin (included) of the input index array.
8849  * \param [in] endOfIndex - end (excluded) of the input index array.
8850  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8851  * 
8852  * \throw If bgOfIndex or end is NULL.
8853  * \throw If input index array is not ascendingly sorted.
8854  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8855  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8856  */
8857 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8858 {
8859   if(!bgOfIndex || !endOfIndex)
8860     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8861   checkAllocated();
8862   int nbCompo=getNumberOfComponents();
8863   int nbOfTuples=getNumberOfTuples();
8864   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8865   if(sz<1)
8866     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8867   sz--;
8868   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8869   const int *w=bgOfIndex;
8870   if(*w<0 || *w>=nbOfTuples)
8871     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8872   const int *srcPt=begin()+(*w)*nbCompo;
8873   int *tmp=ret->getPointer();
8874   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8875     {
8876       std::fill(tmp,tmp+nbCompo,0);
8877       if(w[1]>=w[0])
8878         {
8879           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8880             {
8881               if(j>=0 && j<nbOfTuples)
8882                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8883               else
8884                 {
8885                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8886                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8887                 }
8888             }
8889         }
8890       else
8891         {
8892           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8893           throw INTERP_KERNEL::Exception(oss.str().c_str());
8894         }
8895     }
8896   ret->copyStringInfoFrom(*this);
8897   return ret.retn();
8898 }
8899
8900 /*!
8901  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8902  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8903  * offsetA2</em> and (2)
8904  * the number of component in the result array is same as that of each of given arrays.
8905  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8906  * Info on components is copied from the first of the given arrays. Number of components
8907  * in the given arrays must be the same.
8908  *  \param [in] a1 - an array to include in the result array.
8909  *  \param [in] a2 - another array to include in the result array.
8910  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8911  *  \return DataArrayInt * - the new instance of DataArrayInt.
8912  *          The caller is to delete this result array using decrRef() as it is no more
8913  *          needed.
8914  *  \throw If either \a a1 or \a a2 is NULL.
8915  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8916  */
8917 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8918 {
8919   if(!a1 || !a2)
8920     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8921   int nbOfComp=a1->getNumberOfComponents();
8922   if(nbOfComp!=a2->getNumberOfComponents())
8923     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8924   int nbOfTuple1=a1->getNumberOfTuples();
8925   int nbOfTuple2=a2->getNumberOfTuples();
8926   DataArrayInt *ret=DataArrayInt::New();
8927   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8928   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8929   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8930   ret->copyStringInfoFrom(*a1);
8931   return ret;
8932 }
8933
8934 /*!
8935  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8936  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8937  * the number of component in the result array is same as that of each of given arrays.
8938  * Info on components is copied from the first of the given arrays. Number of components
8939  * in the given arrays must be  the same.
8940  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
8941  * not the object itself.
8942  *  \param [in] arr - a sequence of arrays to include in the result array.
8943  *  \return DataArrayInt * - the new instance of DataArrayInt.
8944  *          The caller is to delete this result array using decrRef() as it is no more
8945  *          needed.
8946  *  \throw If all arrays within \a arr are NULL.
8947  *  \throw If getNumberOfComponents() of arrays within \a arr.
8948  */
8949 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8950 {
8951   std::vector<const DataArrayInt *> a;
8952   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8953     if(*it4)
8954       a.push_back(*it4);
8955   if(a.empty())
8956     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8957   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8958   int nbOfComp=(*it)->getNumberOfComponents();
8959   int nbt=(*it++)->getNumberOfTuples();
8960   for(int i=1;it!=a.end();it++,i++)
8961     {
8962       if((*it)->getNumberOfComponents()!=nbOfComp)
8963         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8964       nbt+=(*it)->getNumberOfTuples();
8965     }
8966   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8967   ret->alloc(nbt,nbOfComp);
8968   int *pt=ret->getPointer();
8969   for(it=a.begin();it!=a.end();it++)
8970     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8971   ret->copyStringInfoFrom(*(a[0]));
8972   return ret.retn();
8973 }
8974
8975 /*!
8976  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8977  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8978  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8979  * 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.
8980  * 
8981  * \return DataArrayInt * - a new object to be managed by the caller.
8982  */
8983 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8984 {
8985   int retSz=1;
8986   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8987     {
8988       if(*it4)
8989         {
8990           (*it4)->checkAllocated();
8991           if((*it4)->getNumberOfComponents()!=1)
8992             {
8993               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8994               throw INTERP_KERNEL::Exception(oss.str().c_str());
8995             }
8996           int nbTupl=(*it4)->getNumberOfTuples();
8997           if(nbTupl<1)
8998             {
8999               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9000               throw INTERP_KERNEL::Exception(oss.str().c_str());
9001             }
9002           if((*it4)->front()!=0)
9003             {
9004               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9005               throw INTERP_KERNEL::Exception(oss.str().c_str());
9006             }
9007           retSz+=nbTupl-1;
9008         }
9009       else
9010         {
9011           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9012           throw INTERP_KERNEL::Exception(oss.str().c_str());
9013         }
9014     }
9015   if(arrs.empty())
9016     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9017   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9018   ret->alloc(retSz,1);
9019   int *pt=ret->getPointer(); *pt++=0;
9020   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9021     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9022   ret->copyStringInfoFrom(*(arrs[0]));
9023   return ret.retn();
9024 }
9025
9026 /*!
9027  * Returns the maximal value and its location within \a this one-dimensional array.
9028  *  \param [out] tupleId - index of the tuple holding the maximal value.
9029  *  \return int - the maximal value among all values of \a this array.
9030  *  \throw If \a this->getNumberOfComponents() != 1
9031  *  \throw If \a this->getNumberOfTuples() < 1
9032  */
9033 int DataArrayInt::getMaxValue(int& tupleId) const
9034 {
9035   checkAllocated();
9036   if(getNumberOfComponents()!=1)
9037     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9038   int nbOfTuples=getNumberOfTuples();
9039   if(nbOfTuples<=0)
9040     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9041   const int *vals=getConstPointer();
9042   const int *loc=std::max_element(vals,vals+nbOfTuples);
9043   tupleId=(int)std::distance(vals,loc);
9044   return *loc;
9045 }
9046
9047 /*!
9048  * Returns the maximal value within \a this array that is allowed to have more than
9049  *  one component.
9050  *  \return int - the maximal value among all values of \a this array.
9051  *  \throw If \a this is not allocated.
9052  */
9053 int DataArrayInt::getMaxValueInArray() const
9054 {
9055   checkAllocated();
9056   const int *loc=std::max_element(begin(),end());
9057   return *loc;
9058 }
9059
9060 /*!
9061  * Returns the minimal value and its location within \a this one-dimensional array.
9062  *  \param [out] tupleId - index of the tuple holding the minimal value.
9063  *  \return int - the minimal value among all values of \a this array.
9064  *  \throw If \a this->getNumberOfComponents() != 1
9065  *  \throw If \a this->getNumberOfTuples() < 1
9066  */
9067 int DataArrayInt::getMinValue(int& tupleId) const
9068 {
9069   checkAllocated();
9070   if(getNumberOfComponents()!=1)
9071     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9072   int nbOfTuples=getNumberOfTuples();
9073   if(nbOfTuples<=0)
9074     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9075   const int *vals=getConstPointer();
9076   const int *loc=std::min_element(vals,vals+nbOfTuples);
9077   tupleId=(int)std::distance(vals,loc);
9078   return *loc;
9079 }
9080
9081 /*!
9082  * Returns the minimal value within \a this array that is allowed to have more than
9083  *  one component.
9084  *  \return int - the minimal value among all values of \a this array.
9085  *  \throw If \a this is not allocated.
9086  */
9087 int DataArrayInt::getMinValueInArray() const
9088 {
9089   checkAllocated();
9090   const int *loc=std::min_element(begin(),end());
9091   return *loc;
9092 }
9093
9094 /*!
9095  * Converts every value of \a this array to its absolute value.
9096  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9097  * should be called instead.
9098  *
9099  * \throw If \a this is not allocated.
9100  * \sa DataArrayInt::computeAbs
9101  */
9102 void DataArrayInt::abs()
9103 {
9104   checkAllocated();
9105   int *ptr(getPointer());
9106   std::size_t nbOfElems(getNbOfElems());
9107   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9108   declareAsNew();
9109 }
9110
9111 /*!
9112  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9113  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9114  *
9115  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9116  *         same number of tuples and component as \a this array.
9117  *         The caller is to delete this result array using decrRef() as it is no more
9118  *         needed.
9119  * \throw If \a this is not allocated.
9120  * \sa DataArrayInt::abs
9121  */
9122 DataArrayInt *DataArrayInt::computeAbs() const
9123 {
9124   checkAllocated();
9125   DataArrayInt *newArr(DataArrayInt::New());
9126   int nbOfTuples(getNumberOfTuples());
9127   int nbOfComp(getNumberOfComponents());
9128   newArr->alloc(nbOfTuples,nbOfComp);
9129   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9130   newArr->copyStringInfoFrom(*this);
9131   return newArr;
9132 }
9133
9134 /*!
9135  * Apply a liner function to a given component of \a this array, so that
9136  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9137  *  \param [in] a - the first coefficient of the function.
9138  *  \param [in] b - the second coefficient of the function.
9139  *  \param [in] compoId - the index of component to modify.
9140  *  \throw If \a this is not allocated.
9141  */
9142 void DataArrayInt::applyLin(int a, int b, int compoId)
9143 {
9144   checkAllocated();
9145   int *ptr=getPointer()+compoId;
9146   int nbOfComp=getNumberOfComponents();
9147   int nbOfTuple=getNumberOfTuples();
9148   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9149     *ptr=a*(*ptr)+b;
9150   declareAsNew();
9151 }
9152
9153 /*!
9154  * Apply a liner function to all elements of \a this array, so that
9155  * an element _x_ becomes \f$ a * x + b \f$.
9156  *  \param [in] a - the first coefficient of the function.
9157  *  \param [in] b - the second coefficient of the function.
9158  *  \throw If \a this is not allocated.
9159  */
9160 void DataArrayInt::applyLin(int a, int b)
9161 {
9162   checkAllocated();
9163   int *ptr=getPointer();
9164   std::size_t nbOfElems=getNbOfElems();
9165   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9166     *ptr=a*(*ptr)+b;
9167   declareAsNew();
9168 }
9169
9170 /*!
9171  * Returns a full copy of \a this array except that sign of all elements is reversed.
9172  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9173  *          same number of tuples and component as \a this array.
9174  *          The caller is to delete this result array using decrRef() as it is no more
9175  *          needed.
9176  *  \throw If \a this is not allocated.
9177  */
9178 DataArrayInt *DataArrayInt::negate() const
9179 {
9180   checkAllocated();
9181   DataArrayInt *newArr=DataArrayInt::New();
9182   int nbOfTuples=getNumberOfTuples();
9183   int nbOfComp=getNumberOfComponents();
9184   newArr->alloc(nbOfTuples,nbOfComp);
9185   const int *cptr=getConstPointer();
9186   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9187   newArr->copyStringInfoFrom(*this);
9188   return newArr;
9189 }
9190
9191 /*!
9192  * Modify all elements of \a this array, so that
9193  * an element _x_ becomes \f$ numerator / x \f$.
9194  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9195  *           array, all elements processed before detection of the zero element remain
9196  *           modified.
9197  *  \param [in] numerator - the numerator used to modify array elements.
9198  *  \throw If \a this is not allocated.
9199  *  \throw If there is an element equal to 0 in \a this array.
9200  */
9201 void DataArrayInt::applyInv(int numerator)
9202 {
9203   checkAllocated();
9204   int *ptr=getPointer();
9205   std::size_t nbOfElems=getNbOfElems();
9206   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9207     {
9208       if(*ptr!=0)
9209         {
9210           *ptr=numerator/(*ptr);
9211         }
9212       else
9213         {
9214           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9215           oss << " !";
9216           throw INTERP_KERNEL::Exception(oss.str().c_str());
9217         }
9218     }
9219   declareAsNew();
9220 }
9221
9222 /*!
9223  * Modify all elements of \a this array, so that
9224  * an element _x_ becomes \f$ x / val \f$.
9225  *  \param [in] val - the denominator used to modify array elements.
9226  *  \throw If \a this is not allocated.
9227  *  \throw If \a val == 0.
9228  */
9229 void DataArrayInt::applyDivideBy(int val)
9230 {
9231   if(val==0)
9232     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9233   checkAllocated();
9234   int *ptr=getPointer();
9235   std::size_t nbOfElems=getNbOfElems();
9236   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9237   declareAsNew();
9238 }
9239
9240 /*!
9241  * Modify all elements of \a this array, so that
9242  * an element _x_ becomes  <em> x % val </em>.
9243  *  \param [in] val - the divisor used to modify array elements.
9244  *  \throw If \a this is not allocated.
9245  *  \throw If \a val <= 0.
9246  */
9247 void DataArrayInt::applyModulus(int val)
9248 {
9249   if(val<=0)
9250     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9251   checkAllocated();
9252   int *ptr=getPointer();
9253   std::size_t nbOfElems=getNbOfElems();
9254   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9255   declareAsNew();
9256 }
9257
9258 /*!
9259  * This method works only on data array with one component.
9260  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9261  * this[*id] in [\b vmin,\b vmax)
9262  * 
9263  * \param [in] vmin begin of range. This value is included in range (included).
9264  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9265  * \return a newly allocated data array that the caller should deal with.
9266  *
9267  * \sa DataArrayInt::getIdsNotInRange
9268  */
9269 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9270 {
9271   checkAllocated();
9272   if(getNumberOfComponents()!=1)
9273     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9274   const int *cptr(begin());
9275   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9276   int nbOfTuples(getNumberOfTuples());
9277   for(int i=0;i<nbOfTuples;i++,cptr++)
9278     if(*cptr>=vmin && *cptr<vmax)
9279       ret->pushBackSilent(i);
9280   return ret.retn();
9281 }
9282
9283 /*!
9284  * This method works only on data array with one component.
9285  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9286  * this[*id] \b not in [\b vmin,\b vmax)
9287  * 
9288  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9289  * \param [in] vmax end of range. This value is included in range (included).
9290  * \return a newly allocated data array that the caller should deal with.
9291  * 
9292  * \sa DataArrayInt::getIdsInRange
9293  */
9294 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9295 {
9296   checkAllocated();
9297   if(getNumberOfComponents()!=1)
9298     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9299   const int *cptr(getConstPointer());
9300   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9301   int nbOfTuples(getNumberOfTuples());
9302   for(int i=0;i<nbOfTuples;i++,cptr++)
9303     if(*cptr<vmin || *cptr>=vmax)
9304       ret->pushBackSilent(i);
9305   return ret.retn();
9306 }
9307
9308 /*!
9309  * This method works only on data array with one component.
9310  * 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.
9311  * 
9312  * \param [in] vmin begin of range. This value is included in range (included).
9313  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9314  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9315 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9316 {
9317   checkAllocated();
9318   if(getNumberOfComponents()!=1)
9319     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9320   int nbOfTuples=getNumberOfTuples();
9321   bool ret=true;
9322   const int *cptr=getConstPointer();
9323   for(int i=0;i<nbOfTuples;i++,cptr++)
9324     {
9325       if(*cptr>=vmin && *cptr<vmax)
9326         { ret=ret && *cptr==i; }
9327       else
9328         {
9329           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9330           throw INTERP_KERNEL::Exception(oss.str().c_str());
9331         }
9332     }
9333   return ret;
9334 }
9335
9336 /*!
9337  * Modify all elements of \a this array, so that
9338  * an element _x_ becomes <em> val % x </em>.
9339  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9340  *           array, all elements processed before detection of the zero element remain
9341  *           modified.
9342  *  \param [in] val - the divident used to modify array elements.
9343  *  \throw If \a this is not allocated.
9344  *  \throw If there is an element equal to or less than 0 in \a this array.
9345  */
9346 void DataArrayInt::applyRModulus(int val)
9347 {
9348   checkAllocated();
9349   int *ptr=getPointer();
9350   std::size_t nbOfElems=getNbOfElems();
9351   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9352     {
9353       if(*ptr>0)
9354         {
9355           *ptr=val%(*ptr);
9356         }
9357       else
9358         {
9359           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9360           oss << " !";
9361           throw INTERP_KERNEL::Exception(oss.str().c_str());
9362         }
9363     }
9364   declareAsNew();
9365 }
9366
9367 /*!
9368  * Modify all elements of \a this array, so that
9369  * an element _x_ becomes <em> val ^ x </em>.
9370  *  \param [in] val - the value used to apply pow on all array elements.
9371  *  \throw If \a this is not allocated.
9372  *  \throw If \a val < 0.
9373  */
9374 void DataArrayInt::applyPow(int val)
9375 {
9376   checkAllocated();
9377   if(val<0)
9378     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9379   int *ptr=getPointer();
9380   std::size_t nbOfElems=getNbOfElems();
9381   if(val==0)
9382     {
9383       std::fill(ptr,ptr+nbOfElems,1);
9384       return ;
9385     }
9386   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9387     {
9388       int tmp=1;
9389       for(int j=0;j<val;j++)
9390         tmp*=*ptr;
9391       *ptr=tmp;
9392     }
9393   declareAsNew();
9394 }
9395
9396 /*!
9397  * Modify all elements of \a this array, so that
9398  * an element _x_ becomes \f$ val ^ x \f$.
9399  *  \param [in] val - the value used to apply pow on all array elements.
9400  *  \throw If \a this is not allocated.
9401  *  \throw If there is an element < 0 in \a this array.
9402  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9403  *           array, all elements processed before detection of the zero element remain
9404  *           modified.
9405  */
9406 void DataArrayInt::applyRPow(int val)
9407 {
9408   checkAllocated();
9409   int *ptr=getPointer();
9410   std::size_t nbOfElems=getNbOfElems();
9411   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9412     {
9413       if(*ptr>=0)
9414         {
9415           int tmp=1;
9416           for(int j=0;j<*ptr;j++)
9417             tmp*=val;
9418           *ptr=tmp;
9419         }
9420       else
9421         {
9422           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9423           oss << " !";
9424           throw INTERP_KERNEL::Exception(oss.str().c_str());
9425         }
9426     }
9427   declareAsNew();
9428 }
9429
9430 /*!
9431  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9432  * of components in the result array is a sum of the number of components of given arrays
9433  * and (2) the number of tuples in the result array is same as that of each of given
9434  * arrays. In other words the i-th tuple of result array includes all components of
9435  * i-th tuples of all given arrays.
9436  * Number of tuples in the given arrays must be the same.
9437  *  \param [in] a1 - an array to include in the result array.
9438  *  \param [in] a2 - another array to include in the result array.
9439  *  \return DataArrayInt * - the new instance of DataArrayInt.
9440  *          The caller is to delete this result array using decrRef() as it is no more
9441  *          needed.
9442  *  \throw If both \a a1 and \a a2 are NULL.
9443  *  \throw If any given array is not allocated.
9444  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9445  */
9446 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9447 {
9448   std::vector<const DataArrayInt *> arr(2);
9449   arr[0]=a1; arr[1]=a2;
9450   return Meld(arr);
9451 }
9452
9453 /*!
9454  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9455  * of components in the result array is a sum of the number of components of given arrays
9456  * and (2) the number of tuples in the result array is same as that of each of given
9457  * arrays. In other words the i-th tuple of result array includes all components of
9458  * i-th tuples of all given arrays.
9459  * Number of tuples in the given arrays must be  the same.
9460  *  \param [in] arr - a sequence of arrays to include in the result array.
9461  *  \return DataArrayInt * - the new instance of DataArrayInt.
9462  *          The caller is to delete this result array using decrRef() as it is no more
9463  *          needed.
9464  *  \throw If all arrays within \a arr are NULL.
9465  *  \throw If any given array is not allocated.
9466  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9467  */
9468 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9469 {
9470   std::vector<const DataArrayInt *> a;
9471   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9472     if(*it4)
9473       a.push_back(*it4);
9474   if(a.empty())
9475     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9476   std::vector<const DataArrayInt *>::const_iterator it;
9477   for(it=a.begin();it!=a.end();it++)
9478     (*it)->checkAllocated();
9479   it=a.begin();
9480   int nbOfTuples=(*it)->getNumberOfTuples();
9481   std::vector<int> nbc(a.size());
9482   std::vector<const int *> pts(a.size());
9483   nbc[0]=(*it)->getNumberOfComponents();
9484   pts[0]=(*it++)->getConstPointer();
9485   for(int i=1;it!=a.end();it++,i++)
9486     {
9487       if(nbOfTuples!=(*it)->getNumberOfTuples())
9488         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9489       nbc[i]=(*it)->getNumberOfComponents();
9490       pts[i]=(*it)->getConstPointer();
9491     }
9492   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9493   DataArrayInt *ret=DataArrayInt::New();
9494   ret->alloc(nbOfTuples,totalNbOfComp);
9495   int *retPtr=ret->getPointer();
9496   for(int i=0;i<nbOfTuples;i++)
9497     for(int j=0;j<(int)a.size();j++)
9498       {
9499         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9500         pts[j]+=nbc[j];
9501       }
9502   int k=0;
9503   for(int i=0;i<(int)a.size();i++)
9504     for(int j=0;j<nbc[i];j++,k++)
9505       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9506   return ret;
9507 }
9508
9509 /*!
9510  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9511  * The i-th item of the result array is an ID of a set of elements belonging to a
9512  * unique set of groups, which the i-th element is a part of. This set of elements
9513  * belonging to a unique set of groups is called \a family, so the result array contains
9514  * IDs of families each element belongs to.
9515  *
9516  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9517  * then there are 3 families:
9518  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9519  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9520  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9521  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9522  * stands for the element #3 which is in none of groups.
9523  *
9524  *  \param [in] groups - sequence of groups of element IDs.
9525  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9526  *         in \a groups.
9527  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9528  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9529  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9530  *         delete this array using decrRef() as it is no more needed.
9531  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9532  */
9533 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9534 {
9535   std::vector<const DataArrayInt *> groups2;
9536   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9537     if(*it4)
9538       groups2.push_back(*it4);
9539   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9540   ret->alloc(newNb,1);
9541   int *retPtr=ret->getPointer();
9542   std::fill(retPtr,retPtr+newNb,0);
9543   int fid=1;
9544   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9545     {
9546       const int *ptr=(*iter)->getConstPointer();
9547       std::size_t nbOfElem=(*iter)->getNbOfElems();
9548       int sfid=fid;
9549       for(int j=0;j<sfid;j++)
9550         {
9551           bool found=false;
9552           for(std::size_t i=0;i<nbOfElem;i++)
9553             {
9554               if(ptr[i]>=0 && ptr[i]<newNb)
9555                 {
9556                   if(retPtr[ptr[i]]==j)
9557                     {
9558                       retPtr[ptr[i]]=fid;
9559                       found=true;
9560                     }
9561                 }
9562               else
9563                 {
9564                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9565                   oss << ") !";
9566                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9567                 }
9568             }
9569           if(found)
9570             fid++;
9571         }
9572     }
9573   fidsOfGroups.clear();
9574   fidsOfGroups.resize(groups2.size());
9575   int grId=0;
9576   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9577     {
9578       std::set<int> tmp;
9579       const int *ptr=(*iter)->getConstPointer();
9580       std::size_t nbOfElem=(*iter)->getNbOfElems();
9581       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9582         tmp.insert(retPtr[*p]);
9583       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9584     }
9585   return ret.retn();
9586 }
9587
9588 /*!
9589  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9590  * arrays. The result array does not contain any duplicates and its values
9591  * are sorted in ascending order.
9592  *  \param [in] arr - sequence of DataArrayInt's to unite.
9593  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9594  *         array using decrRef() as it is no more needed.
9595  *  \throw If any \a arr[i] is not allocated.
9596  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9597  */
9598 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9599 {
9600   std::vector<const DataArrayInt *> a;
9601   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9602     if(*it4)
9603       a.push_back(*it4);
9604   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9605     {
9606       (*it)->checkAllocated();
9607       if((*it)->getNumberOfComponents()!=1)
9608         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9609     }
9610   //
9611   std::set<int> r;
9612   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9613     {
9614       const int *pt=(*it)->getConstPointer();
9615       int nbOfTuples=(*it)->getNumberOfTuples();
9616       r.insert(pt,pt+nbOfTuples);
9617     }
9618   DataArrayInt *ret=DataArrayInt::New();
9619   ret->alloc((int)r.size(),1);
9620   std::copy(r.begin(),r.end(),ret->getPointer());
9621   return ret;
9622 }
9623
9624 /*!
9625  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9626  * arrays. The result array does not contain any duplicates and its values
9627  * are sorted in ascending order.
9628  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9629  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9630  *         array using decrRef() as it is no more needed.
9631  *  \throw If any \a arr[i] is not allocated.
9632  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9633  */
9634 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9635 {
9636   std::vector<const DataArrayInt *> a;
9637   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9638     if(*it4)
9639       a.push_back(*it4);
9640   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9641     {
9642       (*it)->checkAllocated();
9643       if((*it)->getNumberOfComponents()!=1)
9644         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9645     }
9646   //
9647   std::set<int> r;
9648   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9649     {
9650       const int *pt=(*it)->getConstPointer();
9651       int nbOfTuples=(*it)->getNumberOfTuples();
9652       std::set<int> s1(pt,pt+nbOfTuples);
9653       if(it!=a.begin())
9654         {
9655           std::set<int> r2;
9656           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9657           r=r2;
9658         }
9659       else
9660         r=s1;
9661     }
9662   DataArrayInt *ret(DataArrayInt::New());
9663   ret->alloc((int)r.size(),1);
9664   std::copy(r.begin(),r.end(),ret->getPointer());
9665   return ret;
9666 }
9667
9668 /// @cond INTERNAL
9669 namespace ParaMEDMEMImpl
9670 {
9671   class OpSwitchedOn
9672   {
9673   public:
9674     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9675     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9676   private:
9677     int *_pt;
9678     int _cnt;
9679   };
9680
9681   class OpSwitchedOff
9682   {
9683   public:
9684     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9685     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9686   private:
9687     int *_pt;
9688     int _cnt;
9689   };
9690 }
9691 /// @endcond
9692
9693 /*!
9694  * This method returns the list of ids in ascending mode so that v[id]==true.
9695  */
9696 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9697 {
9698   int sz((int)std::count(v.begin(),v.end(),true));
9699   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9700   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
9701   return ret.retn();
9702 }
9703
9704 /*!
9705  * This method returns the list of ids in ascending mode so that v[id]==false.
9706  */
9707 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9708 {
9709   int sz((int)std::count(v.begin(),v.end(),false));
9710   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9711   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
9712   return ret.retn();
9713 }
9714
9715 /*!
9716  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9717  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9718  *
9719  * \param [in] v the input data structure to be translate into skyline format.
9720  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9721  * \param [out] dataIndex the second element of the skyline format.
9722  */
9723 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9724 {
9725   int sz((int)v.size());
9726   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9727   ret1->alloc(sz+1,1);
9728   int *pt(ret1->getPointer()); *pt=0;
9729   for(int i=0;i<sz;i++,pt++)
9730     pt[1]=pt[0]+(int)v[i].size();
9731   ret0->alloc(ret1->back(),1);
9732   pt=ret0->getPointer();
9733   for(int i=0;i<sz;i++)
9734     pt=std::copy(v[i].begin(),v[i].end(),pt);
9735   data=ret0.retn(); dataIndex=ret1.retn();
9736 }
9737
9738 /*!
9739  * Returns a new DataArrayInt which contains a complement of elements of \a this
9740  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9741  * \a nbOfElement) not present in \a this array.
9742  *  \param [in] nbOfElement - maximal size of the result array.
9743  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9744  *         array using decrRef() as it is no more needed.
9745  *  \throw If \a this is not allocated.
9746  *  \throw If \a this->getNumberOfComponents() != 1.
9747  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9748  *         nbOfElement ).
9749  */
9750 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9751 {
9752   checkAllocated();
9753   if(getNumberOfComponents()!=1)
9754     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9755   std::vector<bool> tmp(nbOfElement);
9756   const int *pt=getConstPointer();
9757   int nbOfTuples=getNumberOfTuples();
9758   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9759     if(*w>=0 && *w<nbOfElement)
9760       tmp[*w]=true;
9761     else
9762       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9763   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9764   DataArrayInt *ret=DataArrayInt::New();
9765   ret->alloc(nbOfRetVal,1);
9766   int j=0;
9767   int *retPtr=ret->getPointer();
9768   for(int i=0;i<nbOfElement;i++)
9769     if(!tmp[i])
9770       retPtr[j++]=i;
9771   return ret;
9772 }
9773
9774 /*!
9775  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9776  * from an \a other one-dimensional array.
9777  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9778  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9779  *         caller is to delete this array using decrRef() as it is no more needed.
9780  *  \throw If \a other is NULL.
9781  *  \throw If \a other is not allocated.
9782  *  \throw If \a other->getNumberOfComponents() != 1.
9783  *  \throw If \a this is not allocated.
9784  *  \throw If \a this->getNumberOfComponents() != 1.
9785  *  \sa DataArrayInt::buildSubstractionOptimized()
9786  */
9787 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9788 {
9789   if(!other)
9790     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9791   checkAllocated();
9792   other->checkAllocated();
9793   if(getNumberOfComponents()!=1)
9794     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9795   if(other->getNumberOfComponents()!=1)
9796     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9797   const int *pt=getConstPointer();
9798   int nbOfTuples=getNumberOfTuples();
9799   std::set<int> s1(pt,pt+nbOfTuples);
9800   pt=other->getConstPointer();
9801   nbOfTuples=other->getNumberOfTuples();
9802   std::set<int> s2(pt,pt+nbOfTuples);
9803   std::vector<int> r;
9804   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9805   DataArrayInt *ret=DataArrayInt::New();
9806   ret->alloc((int)r.size(),1);
9807   std::copy(r.begin(),r.end(),ret->getPointer());
9808   return ret;
9809 }
9810
9811 /*!
9812  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9813  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9814  * 
9815  * \param [in] other an array with one component and expected to be sorted ascendingly.
9816  * \ret list of ids in \a this but not in \a other.
9817  * \sa DataArrayInt::buildSubstraction
9818  */
9819 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9820 {
9821   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9822   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9823   checkAllocated(); other->checkAllocated();
9824   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9825   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9826   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9827   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9828   for(;work1!=pt1End;work1++)
9829     {
9830       if(work2!=pt2End && *work1==*work2)
9831         work2++;
9832       else
9833         ret->pushBackSilent(*work1);
9834     }
9835   return ret.retn();
9836 }
9837
9838
9839 /*!
9840  * Returns a new DataArrayInt which contains all elements of \a this and a given
9841  * one-dimensional arrays. The result array does not contain any duplicates
9842  * and its values are sorted in ascending order.
9843  *  \param [in] other - an array to unite with \a this one.
9844  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9845  *         array using decrRef() as it is no more needed.
9846  *  \throw If \a this or \a other is not allocated.
9847  *  \throw If \a this->getNumberOfComponents() != 1.
9848  *  \throw If \a other->getNumberOfComponents() != 1.
9849  */
9850 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9851 {
9852   std::vector<const DataArrayInt *>arrs(2);
9853   arrs[0]=this; arrs[1]=other;
9854   return BuildUnion(arrs);
9855 }
9856
9857
9858 /*!
9859  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9860  * one-dimensional arrays. The result array does not contain any duplicates
9861  * and its values are sorted in ascending order.
9862  *  \param [in] other - an array to intersect with \a this one.
9863  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9864  *         array using decrRef() as it is no more needed.
9865  *  \throw If \a this or \a other is not allocated.
9866  *  \throw If \a this->getNumberOfComponents() != 1.
9867  *  \throw If \a other->getNumberOfComponents() != 1.
9868  */
9869 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9870 {
9871   std::vector<const DataArrayInt *>arrs(2);
9872   arrs[0]=this; arrs[1]=other;
9873   return BuildIntersection(arrs);
9874 }
9875
9876 /*!
9877  * This method can be applied on allocated with one component DataArrayInt instance.
9878  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9879  * 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]
9880  * 
9881  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9882  * \throw if \a this is not allocated or if \a this has not exactly one component.
9883  */
9884 DataArrayInt *DataArrayInt::buildUnique() const
9885 {
9886   checkAllocated();
9887   if(getNumberOfComponents()!=1)
9888     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9889   int nbOfTuples=getNumberOfTuples();
9890   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9891   int *data=tmp->getPointer();
9892   int *last=std::unique(data,data+nbOfTuples);
9893   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9894   ret->alloc(std::distance(data,last),1);
9895   std::copy(data,last,ret->getPointer());
9896   return ret.retn();
9897 }
9898
9899 /*!
9900  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9901  * "index" array. Such "index" array is returned for example by 
9902  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9903  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9904  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9905  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9906  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9907  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9908  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9909  *          The caller is to delete this array using decrRef() as it is no more needed. 
9910  *  \throw If \a this is not allocated.
9911  *  \throw If \a this->getNumberOfComponents() != 1.
9912  *  \throw If \a this->getNumberOfTuples() < 2.
9913  *
9914  *  \b Example: <br> 
9915  *         - this contains [1,3,6,7,7,9,15]
9916  *         - result array contains [2,3,1,0,2,6],
9917  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9918  *
9919  * \sa DataArrayInt::computeOffsets2
9920  */
9921 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9922 {
9923   checkAllocated();
9924   if(getNumberOfComponents()!=1)
9925     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9926   int nbOfTuples=getNumberOfTuples();
9927   if(nbOfTuples<2)
9928     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9929   const int *ptr=getConstPointer();
9930   DataArrayInt *ret=DataArrayInt::New();
9931   ret->alloc(nbOfTuples-1,1);
9932   int *out=ret->getPointer();
9933   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9934   return ret;
9935 }
9936
9937 /*!
9938  * Modifies \a this one-dimensional array so that value of each element \a x
9939  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9940  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9941  * and components remains the same.<br>
9942  * This method is useful for allToAllV in MPI with contiguous policy. This method
9943  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9944  * this one.
9945  *  \throw If \a this is not allocated.
9946  *  \throw If \a this->getNumberOfComponents() != 1.
9947  *
9948  *  \b Example: <br>
9949  *          - Before \a this contains [3,5,1,2,0,8]
9950  *          - After \a this contains  [0,3,8,9,11,11]<br>
9951  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9952  *          array is retained and thus there is no space to store the last element.
9953  */
9954 void DataArrayInt::computeOffsets()
9955 {
9956   checkAllocated();
9957   if(getNumberOfComponents()!=1)
9958     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9959   int nbOfTuples=getNumberOfTuples();
9960   if(nbOfTuples==0)
9961     return ;
9962   int *work=getPointer();
9963   int tmp=work[0];
9964   work[0]=0;
9965   for(int i=1;i<nbOfTuples;i++)
9966     {
9967       int tmp2=work[i];
9968       work[i]=work[i-1]+tmp;
9969       tmp=tmp2;
9970     }
9971   declareAsNew();
9972 }
9973
9974
9975 /*!
9976  * Modifies \a this one-dimensional array so that value of each element \a x
9977  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9978  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9979  * components remains the same and number of tuples is inceamented by one.<br>
9980  * This method is useful for allToAllV in MPI with contiguous policy. This method
9981  * differs from computeOffsets() in that the number of tuples is changed by this one.
9982  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9983  *  \throw If \a this is not allocated.
9984  *  \throw If \a this->getNumberOfComponents() != 1.
9985  *
9986  *  \b Example: <br>
9987  *          - Before \a this contains [3,5,1,2,0,8]
9988  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9989  * \sa DataArrayInt::deltaShiftIndex
9990  */
9991 void DataArrayInt::computeOffsets2()
9992 {
9993   checkAllocated();
9994   if(getNumberOfComponents()!=1)
9995     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9996   int nbOfTuples=getNumberOfTuples();
9997   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9998   if(nbOfTuples==0)
9999     return ;
10000   const int *work=getConstPointer();
10001   ret[0]=0;
10002   for(int i=0;i<nbOfTuples;i++)
10003     ret[i+1]=work[i]+ret[i];
10004   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10005   declareAsNew();
10006 }
10007
10008 /*!
10009  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10010  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10011  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10012  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10013  * filling completely one of the ranges in \a this.
10014  *
10015  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10016  * \param [out] rangeIdsFetched the range ids fetched
10017  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10018  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10019  *
10020  * \sa DataArrayInt::computeOffsets2
10021  *
10022  *  \b Example: <br>
10023  *          - \a this : [0,3,7,9,15,18]
10024  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10025  *          - \a rangeIdsFetched result array: [0,2,4]
10026  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10027  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10028  * <br>
10029  */
10030 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10031 {
10032   if(!listOfIds)
10033     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10034   listOfIds->checkAllocated(); checkAllocated();
10035   if(listOfIds->getNumberOfComponents()!=1)
10036     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10037   if(getNumberOfComponents()!=1)
10038     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10039   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10040   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10041   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10042   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10043   while(tupPtr!=tupEnd && offPtr!=offEnd)
10044     {
10045       if(*tupPtr==*offPtr)
10046         {
10047           int i=offPtr[0];
10048           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10049           if(i==offPtr[1])
10050             {
10051               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10052               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10053               offPtr++;
10054             }
10055         }
10056       else
10057         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10058     }
10059   rangeIdsFetched=ret0.retn();
10060   idsInInputListThatFetch=ret1.retn();
10061 }
10062
10063 /*!
10064  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10065  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10066  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10067  * beginning within the "iota" array. And \a this is a one-dimensional array
10068  * considered as a selector of groups described by \a offsets to include into the result array.
10069  *  \throw If \a offsets is NULL.
10070  *  \throw If \a offsets is not allocated.
10071  *  \throw If \a offsets->getNumberOfComponents() != 1.
10072  *  \throw If \a offsets is not monotonically increasing.
10073  *  \throw If \a this is not allocated.
10074  *  \throw If \a this->getNumberOfComponents() != 1.
10075  *  \throw If any element of \a this is not a valid index for \a offsets array.
10076  *
10077  *  \b Example: <br>
10078  *          - \a this: [0,2,3]
10079  *          - \a offsets: [0,3,6,10,14,20]
10080  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10081  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10082  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10083  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10084  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10085  */
10086 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10087 {
10088   if(!offsets)
10089     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10090   checkAllocated();
10091   if(getNumberOfComponents()!=1)
10092     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10093   offsets->checkAllocated();
10094   if(offsets->getNumberOfComponents()!=1)
10095     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10096   int othNbTuples=offsets->getNumberOfTuples()-1;
10097   int nbOfTuples=getNumberOfTuples();
10098   int retNbOftuples=0;
10099   const int *work=getConstPointer();
10100   const int *offPtr=offsets->getConstPointer();
10101   for(int i=0;i<nbOfTuples;i++)
10102     {
10103       int val=work[i];
10104       if(val>=0 && val<othNbTuples)
10105         {
10106           int delta=offPtr[val+1]-offPtr[val];
10107           if(delta>=0)
10108             retNbOftuples+=delta;
10109           else
10110             {
10111               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10112               throw INTERP_KERNEL::Exception(oss.str().c_str());
10113             }
10114         }
10115       else
10116         {
10117           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10118           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10119           throw INTERP_KERNEL::Exception(oss.str().c_str());
10120         }
10121     }
10122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10123   ret->alloc(retNbOftuples,1);
10124   int *retPtr=ret->getPointer();
10125   for(int i=0;i<nbOfTuples;i++)
10126     {
10127       int val=work[i];
10128       int start=offPtr[val];
10129       int off=offPtr[val+1]-start;
10130       for(int j=0;j<off;j++,retPtr++)
10131         *retPtr=start+j;
10132     }
10133   return ret.retn();
10134 }
10135
10136 /*!
10137  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10138  * scaled array (monotonically increasing).
10139 from that of \a this and \a
10140  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10141  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10142  * beginning within the "iota" array. And \a this is a one-dimensional array
10143  * considered as a selector of groups described by \a offsets to include into the result array.
10144  *  \throw If \a  is NULL.
10145  *  \throw If \a this is not allocated.
10146  *  \throw If \a this->getNumberOfComponents() != 1.
10147  *  \throw If \a this->getNumberOfTuples() == 0.
10148  *  \throw If \a this is not monotonically increasing.
10149  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10150  *
10151  *  \b Example: <br>
10152  *          - \a bg , \a stop and \a step : (0,5,2)
10153  *          - \a this: [0,3,6,10,14,20]
10154  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10155  */
10156 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10157 {
10158   if(!isAllocated())
10159     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10160   if(getNumberOfComponents()!=1)
10161     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10162   int nbOfTuples(getNumberOfTuples());
10163   if(nbOfTuples==0)
10164     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10165   const int *ids(begin());
10166   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10167   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10168     {
10169       if(pos>=0 && pos<nbOfTuples-1)
10170         {
10171           int delta(ids[pos+1]-ids[pos]);
10172           sz+=delta;
10173           if(delta<0)
10174             {
10175               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10176               throw INTERP_KERNEL::Exception(oss.str().c_str());
10177             }          
10178         }
10179       else
10180         {
10181           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10182           throw INTERP_KERNEL::Exception(oss.str().c_str());
10183         }
10184     }
10185   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10186   int *retPtr(ret->getPointer());
10187   pos=bg;
10188   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10189     {
10190       int delta(ids[pos+1]-ids[pos]);
10191       for(int j=0;j<delta;j++,retPtr++)
10192         *retPtr=pos;
10193     }
10194   return ret.retn();
10195 }
10196
10197 /*!
10198  * 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.
10199  * 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
10200  * in tuple **i** of returned DataArrayInt.
10201  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10202  *
10203  * 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)]
10204  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10205  * 
10206  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10207  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10208  * \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
10209  *        is thrown if no ranges in \a ranges contains value in \a this.
10210  * 
10211  * \sa DataArrayInt::findIdInRangeForEachTuple
10212  */
10213 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10214 {
10215   if(!ranges)
10216     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10217   if(ranges->getNumberOfComponents()!=2)
10218     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10219   checkAllocated();
10220   if(getNumberOfComponents()!=1)
10221     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10222   int nbTuples=getNumberOfTuples();
10223   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10224   int nbOfRanges=ranges->getNumberOfTuples();
10225   const int *rangesPtr=ranges->getConstPointer();
10226   int *retPtr=ret->getPointer();
10227   const int *inPtr=getConstPointer();
10228   for(int i=0;i<nbTuples;i++,retPtr++)
10229     {
10230       int val=inPtr[i];
10231       bool found=false;
10232       for(int j=0;j<nbOfRanges && !found;j++)
10233         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10234           { *retPtr=j; found=true; }
10235       if(found)
10236         continue;
10237       else
10238         {
10239           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10240           throw INTERP_KERNEL::Exception(oss.str().c_str());
10241         }
10242     }
10243   return ret.retn();
10244 }
10245
10246 /*!
10247  * 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.
10248  * 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
10249  * in tuple **i** of returned DataArrayInt.
10250  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10251  *
10252  * 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)]
10253  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10254  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10255  * 
10256  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10257  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10258  * \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
10259  *        is thrown if no ranges in \a ranges contains value in \a this.
10260  * \sa DataArrayInt::findRangeIdForEachTuple
10261  */
10262 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10263 {
10264   if(!ranges)
10265     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10266   if(ranges->getNumberOfComponents()!=2)
10267     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10268   checkAllocated();
10269   if(getNumberOfComponents()!=1)
10270     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10271   int nbTuples=getNumberOfTuples();
10272   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10273   int nbOfRanges=ranges->getNumberOfTuples();
10274   const int *rangesPtr=ranges->getConstPointer();
10275   int *retPtr=ret->getPointer();
10276   const int *inPtr=getConstPointer();
10277   for(int i=0;i<nbTuples;i++,retPtr++)
10278     {
10279       int val=inPtr[i];
10280       bool found=false;
10281       for(int j=0;j<nbOfRanges && !found;j++)
10282         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10283           { *retPtr=val-rangesPtr[2*j]; found=true; }
10284       if(found)
10285         continue;
10286       else
10287         {
10288           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10289           throw INTERP_KERNEL::Exception(oss.str().c_str());
10290         }
10291     }
10292   return ret.retn();
10293 }
10294
10295 /*!
10296  * 
10297  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10298  *             \a nbTimes  should be at least equal to 1.
10299  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10300  * \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.
10301  */
10302 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10303 {
10304   checkAllocated();
10305   if(getNumberOfComponents()!=1)
10306     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10307   if(nbTimes<1)
10308     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10309   int nbTuples=getNumberOfTuples();
10310   const int *inPtr=getConstPointer();
10311   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10312   int *retPtr=ret->getPointer();
10313   for(int i=0;i<nbTuples;i++,inPtr++)
10314     {
10315       int val=*inPtr;
10316       for(int j=0;j<nbTimes;j++,retPtr++)
10317         *retPtr=val;
10318     }
10319   ret->copyStringInfoFrom(*this);
10320   return ret.retn();
10321 }
10322
10323 /*!
10324  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10325  * But the number of components can be different from one.
10326  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10327  */
10328 DataArrayInt *DataArrayInt::getDifferentValues() const
10329 {
10330   checkAllocated();
10331   std::set<int> ret;
10332   ret.insert(begin(),end());
10333   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10334   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10335   return ret2.retn();
10336 }
10337
10338 /*!
10339  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10340  * them it tells which tuple id have this id.
10341  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10342  * This method returns two arrays having same size.
10343  * 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.
10344  * 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]]
10345  */
10346 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10347 {
10348   checkAllocated();
10349   if(getNumberOfComponents()!=1)
10350     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10351   int id=0;
10352   std::map<int,int> m,m2,m3;
10353   for(const int *w=begin();w!=end();w++)
10354     m[*w]++;
10355   differentIds.resize(m.size());
10356   std::vector<DataArrayInt *> ret(m.size());
10357   std::vector<int *> retPtr(m.size());
10358   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10359     {
10360       m2[(*it).first]=id;
10361       ret[id]=DataArrayInt::New();
10362       ret[id]->alloc((*it).second,1);
10363       retPtr[id]=ret[id]->getPointer();
10364       differentIds[id]=(*it).first;
10365     }
10366   id=0;
10367   for(const int *w=begin();w!=end();w++,id++)
10368     {
10369       retPtr[m2[*w]][m3[*w]++]=id;
10370     }
10371   return ret;
10372 }
10373
10374 /*!
10375  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10376  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10377  *
10378  * \param [in] nbOfSlices - number of slices expected.
10379  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10380  * 
10381  * \sa DataArray::GetSlice
10382  * \throw If \a this is not allocated or not with exactly one component.
10383  * \throw If an element in \a this if < 0.
10384  */
10385 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10386 {
10387   if(!isAllocated() || getNumberOfComponents()!=1)
10388     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10389   if(nbOfSlices<=0)
10390     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10391   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10392   int sumPerSlc(sum/nbOfSlices),pos(0);
10393   const int *w(begin());
10394   std::vector< std::pair<int,int> > ret(nbOfSlices);
10395   for(int i=0;i<nbOfSlices;i++)
10396     {
10397       std::pair<int,int> p(pos,-1);
10398       int locSum(0);
10399       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10400       if(i!=nbOfSlices-1)
10401         p.second=pos;
10402       else
10403         p.second=nbOfTuples;
10404       ret[i]=p;
10405     }
10406   return ret;
10407 }
10408
10409 /*!
10410  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10411  * valid cases.
10412  * 1.  The arrays have same number of tuples and components. Then each value of
10413  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10414  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10415  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10416  *   component. Then
10417  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10418  * 3.  The arrays have same number of components and one array, say _a2_, has one
10419  *   tuple. Then
10420  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10421  *
10422  * Info on components is copied either from the first array (in the first case) or from
10423  * the array with maximal number of elements (getNbOfElems()).
10424  *  \param [in] a1 - an array to sum up.
10425  *  \param [in] a2 - another array to sum up.
10426  *  \return DataArrayInt * - the new instance of DataArrayInt.
10427  *          The caller is to delete this result array using decrRef() as it is no more
10428  *          needed.
10429  *  \throw If either \a a1 or \a a2 is NULL.
10430  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10431  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10432  *         none of them has number of tuples or components equal to 1.
10433  */
10434 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10435 {
10436   if(!a1 || !a2)
10437     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10438   int nbOfTuple=a1->getNumberOfTuples();
10439   int nbOfTuple2=a2->getNumberOfTuples();
10440   int nbOfComp=a1->getNumberOfComponents();
10441   int nbOfComp2=a2->getNumberOfComponents();
10442   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10443   if(nbOfTuple==nbOfTuple2)
10444     {
10445       if(nbOfComp==nbOfComp2)
10446         {
10447           ret=DataArrayInt::New();
10448           ret->alloc(nbOfTuple,nbOfComp);
10449           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10450           ret->copyStringInfoFrom(*a1);
10451         }
10452       else
10453         {
10454           int nbOfCompMin,nbOfCompMax;
10455           const DataArrayInt *aMin, *aMax;
10456           if(nbOfComp>nbOfComp2)
10457             {
10458               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10459               aMin=a2; aMax=a1;
10460             }
10461           else
10462             {
10463               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10464               aMin=a1; aMax=a2;
10465             }
10466           if(nbOfCompMin==1)
10467             {
10468               ret=DataArrayInt::New();
10469               ret->alloc(nbOfTuple,nbOfCompMax);
10470               const int *aMinPtr=aMin->getConstPointer();
10471               const int *aMaxPtr=aMax->getConstPointer();
10472               int *res=ret->getPointer();
10473               for(int i=0;i<nbOfTuple;i++)
10474                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10475               ret->copyStringInfoFrom(*aMax);
10476             }
10477           else
10478             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10479         }
10480     }
10481   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10482     {
10483       if(nbOfComp==nbOfComp2)
10484         {
10485           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10486           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10487           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10488           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10489           ret=DataArrayInt::New();
10490           ret->alloc(nbOfTupleMax,nbOfComp);
10491           int *res=ret->getPointer();
10492           for(int i=0;i<nbOfTupleMax;i++)
10493             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10494           ret->copyStringInfoFrom(*aMax);
10495         }
10496       else
10497         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10498     }
10499   else
10500     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10501   return ret.retn();
10502 }
10503
10504 /*!
10505  * Adds values of another DataArrayInt to values of \a this one. There are 3
10506  * valid cases.
10507  * 1.  The arrays have same number of tuples and components. Then each value of
10508  *   \a other array is added to the corresponding value of \a this array, i.e.:
10509  *   _a_ [ i, j ] += _other_ [ i, j ].
10510  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10511  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10512  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10513  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10514  *
10515  *  \param [in] other - an array to add to \a this one.
10516  *  \throw If \a other is NULL.
10517  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10518  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10519  *         \a other has number of both tuples and components not equal to 1.
10520  */
10521 void DataArrayInt::addEqual(const DataArrayInt *other)
10522 {
10523   if(!other)
10524     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10525   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10526   checkAllocated(); other->checkAllocated();
10527   int nbOfTuple=getNumberOfTuples();
10528   int nbOfTuple2=other->getNumberOfTuples();
10529   int nbOfComp=getNumberOfComponents();
10530   int nbOfComp2=other->getNumberOfComponents();
10531   if(nbOfTuple==nbOfTuple2)
10532     {
10533       if(nbOfComp==nbOfComp2)
10534         {
10535           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10536         }
10537       else if(nbOfComp2==1)
10538         {
10539           int *ptr=getPointer();
10540           const int *ptrc=other->getConstPointer();
10541           for(int i=0;i<nbOfTuple;i++)
10542             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10543         }
10544       else
10545         throw INTERP_KERNEL::Exception(msg);
10546     }
10547   else if(nbOfTuple2==1)
10548     {
10549       if(nbOfComp2==nbOfComp)
10550         {
10551           int *ptr=getPointer();
10552           const int *ptrc=other->getConstPointer();
10553           for(int i=0;i<nbOfTuple;i++)
10554             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10555         }
10556       else
10557         throw INTERP_KERNEL::Exception(msg);
10558     }
10559   else
10560     throw INTERP_KERNEL::Exception(msg);
10561   declareAsNew();
10562 }
10563
10564 /*!
10565  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10566  * valid cases.
10567  * 1.  The arrays have same number of tuples and components. Then each value of
10568  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10569  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10570  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10571  *   component. Then
10572  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10573  * 3.  The arrays have same number of components and one array, say _a2_, has one
10574  *   tuple. Then
10575  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10576  *
10577  * Info on components is copied either from the first array (in the first case) or from
10578  * the array with maximal number of elements (getNbOfElems()).
10579  *  \param [in] a1 - an array to subtract from.
10580  *  \param [in] a2 - an array to subtract.
10581  *  \return DataArrayInt * - the new instance of DataArrayInt.
10582  *          The caller is to delete this result array using decrRef() as it is no more
10583  *          needed.
10584  *  \throw If either \a a1 or \a a2 is NULL.
10585  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10586  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10587  *         none of them has number of tuples or components equal to 1.
10588  */
10589 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10590 {
10591   if(!a1 || !a2)
10592     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10593   int nbOfTuple1=a1->getNumberOfTuples();
10594   int nbOfTuple2=a2->getNumberOfTuples();
10595   int nbOfComp1=a1->getNumberOfComponents();
10596   int nbOfComp2=a2->getNumberOfComponents();
10597   if(nbOfTuple2==nbOfTuple1)
10598     {
10599       if(nbOfComp1==nbOfComp2)
10600         {
10601           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10602           ret->alloc(nbOfTuple2,nbOfComp1);
10603           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10604           ret->copyStringInfoFrom(*a1);
10605           return ret.retn();
10606         }
10607       else if(nbOfComp2==1)
10608         {
10609           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10610           ret->alloc(nbOfTuple1,nbOfComp1);
10611           const int *a2Ptr=a2->getConstPointer();
10612           const int *a1Ptr=a1->getConstPointer();
10613           int *res=ret->getPointer();
10614           for(int i=0;i<nbOfTuple1;i++)
10615             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10616           ret->copyStringInfoFrom(*a1);
10617           return ret.retn();
10618         }
10619       else
10620         {
10621           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10622           return 0;
10623         }
10624     }
10625   else if(nbOfTuple2==1)
10626     {
10627       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10628       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10629       ret->alloc(nbOfTuple1,nbOfComp1);
10630       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10631       int *pt=ret->getPointer();
10632       for(int i=0;i<nbOfTuple1;i++)
10633         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10634       ret->copyStringInfoFrom(*a1);
10635       return ret.retn();
10636     }
10637   else
10638     {
10639       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10640       return 0;
10641     }
10642 }
10643
10644 /*!
10645  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10646  * valid cases.
10647  * 1.  The arrays have same number of tuples and components. Then each value of
10648  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10649  *   _a_ [ i, j ] -= _other_ [ i, j ].
10650  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10651  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10652  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10653  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10654  *
10655  *  \param [in] other - an array to subtract from \a this one.
10656  *  \throw If \a other is NULL.
10657  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10658  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10659  *         \a other has number of both tuples and components not equal to 1.
10660  */
10661 void DataArrayInt::substractEqual(const DataArrayInt *other)
10662 {
10663   if(!other)
10664     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10665   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10666   checkAllocated(); other->checkAllocated();
10667   int nbOfTuple=getNumberOfTuples();
10668   int nbOfTuple2=other->getNumberOfTuples();
10669   int nbOfComp=getNumberOfComponents();
10670   int nbOfComp2=other->getNumberOfComponents();
10671   if(nbOfTuple==nbOfTuple2)
10672     {
10673       if(nbOfComp==nbOfComp2)
10674         {
10675           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10676         }
10677       else if(nbOfComp2==1)
10678         {
10679           int *ptr=getPointer();
10680           const int *ptrc=other->getConstPointer();
10681           for(int i=0;i<nbOfTuple;i++)
10682             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10683         }
10684       else
10685         throw INTERP_KERNEL::Exception(msg);
10686     }
10687   else if(nbOfTuple2==1)
10688     {
10689       int *ptr=getPointer();
10690       const int *ptrc=other->getConstPointer();
10691       for(int i=0;i<nbOfTuple;i++)
10692         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10693     }
10694   else
10695     throw INTERP_KERNEL::Exception(msg);
10696   declareAsNew();
10697 }
10698
10699 /*!
10700  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10701  * valid cases.
10702  * 1.  The arrays have same number of tuples and components. Then each value of
10703  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10704  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10705  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10706  *   component. Then
10707  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10708  * 3.  The arrays have same number of components and one array, say _a2_, has one
10709  *   tuple. Then
10710  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10711  *
10712  * Info on components is copied either from the first array (in the first case) or from
10713  * the array with maximal number of elements (getNbOfElems()).
10714  *  \param [in] a1 - a factor array.
10715  *  \param [in] a2 - another factor array.
10716  *  \return DataArrayInt * - the new instance of DataArrayInt.
10717  *          The caller is to delete this result array using decrRef() as it is no more
10718  *          needed.
10719  *  \throw If either \a a1 or \a a2 is NULL.
10720  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10721  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10722  *         none of them has number of tuples or components equal to 1.
10723  */
10724 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10725 {
10726   if(!a1 || !a2)
10727     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10728   int nbOfTuple=a1->getNumberOfTuples();
10729   int nbOfTuple2=a2->getNumberOfTuples();
10730   int nbOfComp=a1->getNumberOfComponents();
10731   int nbOfComp2=a2->getNumberOfComponents();
10732   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10733   if(nbOfTuple==nbOfTuple2)
10734     {
10735       if(nbOfComp==nbOfComp2)
10736         {
10737           ret=DataArrayInt::New();
10738           ret->alloc(nbOfTuple,nbOfComp);
10739           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10740           ret->copyStringInfoFrom(*a1);
10741         }
10742       else
10743         {
10744           int nbOfCompMin,nbOfCompMax;
10745           const DataArrayInt *aMin, *aMax;
10746           if(nbOfComp>nbOfComp2)
10747             {
10748               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10749               aMin=a2; aMax=a1;
10750             }
10751           else
10752             {
10753               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10754               aMin=a1; aMax=a2;
10755             }
10756           if(nbOfCompMin==1)
10757             {
10758               ret=DataArrayInt::New();
10759               ret->alloc(nbOfTuple,nbOfCompMax);
10760               const int *aMinPtr=aMin->getConstPointer();
10761               const int *aMaxPtr=aMax->getConstPointer();
10762               int *res=ret->getPointer();
10763               for(int i=0;i<nbOfTuple;i++)
10764                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10765               ret->copyStringInfoFrom(*aMax);
10766             }
10767           else
10768             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10769         }
10770     }
10771   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10772     {
10773       if(nbOfComp==nbOfComp2)
10774         {
10775           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10776           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10777           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10778           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10779           ret=DataArrayInt::New();
10780           ret->alloc(nbOfTupleMax,nbOfComp);
10781           int *res=ret->getPointer();
10782           for(int i=0;i<nbOfTupleMax;i++)
10783             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10784           ret->copyStringInfoFrom(*aMax);
10785         }
10786       else
10787         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10788     }
10789   else
10790     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10791   return ret.retn();
10792 }
10793
10794
10795 /*!
10796  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10797  * valid cases.
10798  * 1.  The arrays have same number of tuples and components. Then each value of
10799  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10800  *   _a_ [ i, j ] *= _other_ [ i, j ].
10801  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10802  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10803  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10804  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10805  *
10806  *  \param [in] other - an array to multiply to \a this one.
10807  *  \throw If \a other is NULL.
10808  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10809  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10810  *         \a other has number of both tuples and components not equal to 1.
10811  */
10812 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10813 {
10814   if(!other)
10815     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10816   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10817   checkAllocated(); other->checkAllocated();
10818   int nbOfTuple=getNumberOfTuples();
10819   int nbOfTuple2=other->getNumberOfTuples();
10820   int nbOfComp=getNumberOfComponents();
10821   int nbOfComp2=other->getNumberOfComponents();
10822   if(nbOfTuple==nbOfTuple2)
10823     {
10824       if(nbOfComp==nbOfComp2)
10825         {
10826           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10827         }
10828       else if(nbOfComp2==1)
10829         {
10830           int *ptr=getPointer();
10831           const int *ptrc=other->getConstPointer();
10832           for(int i=0;i<nbOfTuple;i++)
10833             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10834         }
10835       else
10836         throw INTERP_KERNEL::Exception(msg);
10837     }
10838   else if(nbOfTuple2==1)
10839     {
10840       if(nbOfComp2==nbOfComp)
10841         {
10842           int *ptr=getPointer();
10843           const int *ptrc=other->getConstPointer();
10844           for(int i=0;i<nbOfTuple;i++)
10845             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10846         }
10847       else
10848         throw INTERP_KERNEL::Exception(msg);
10849     }
10850   else
10851     throw INTERP_KERNEL::Exception(msg);
10852   declareAsNew();
10853 }
10854
10855
10856 /*!
10857  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10858  * valid cases.
10859  * 1.  The arrays have same number of tuples and components. Then each value of
10860  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10861  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10862  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10863  *   component. Then
10864  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10865  * 3.  The arrays have same number of components and one array, say _a2_, has one
10866  *   tuple. Then
10867  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10868  *
10869  * Info on components is copied either from the first array (in the first case) or from
10870  * the array with maximal number of elements (getNbOfElems()).
10871  *  \warning No check of division by zero is performed!
10872  *  \param [in] a1 - a numerator array.
10873  *  \param [in] a2 - a denominator array.
10874  *  \return DataArrayInt * - the new instance of DataArrayInt.
10875  *          The caller is to delete this result array using decrRef() as it is no more
10876  *          needed.
10877  *  \throw If either \a a1 or \a a2 is NULL.
10878  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10879  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10880  *         none of them has number of tuples or components equal to 1.
10881  */
10882 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10883 {
10884   if(!a1 || !a2)
10885     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10886   int nbOfTuple1=a1->getNumberOfTuples();
10887   int nbOfTuple2=a2->getNumberOfTuples();
10888   int nbOfComp1=a1->getNumberOfComponents();
10889   int nbOfComp2=a2->getNumberOfComponents();
10890   if(nbOfTuple2==nbOfTuple1)
10891     {
10892       if(nbOfComp1==nbOfComp2)
10893         {
10894           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10895           ret->alloc(nbOfTuple2,nbOfComp1);
10896           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10897           ret->copyStringInfoFrom(*a1);
10898           return ret.retn();
10899         }
10900       else if(nbOfComp2==1)
10901         {
10902           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10903           ret->alloc(nbOfTuple1,nbOfComp1);
10904           const int *a2Ptr=a2->getConstPointer();
10905           const int *a1Ptr=a1->getConstPointer();
10906           int *res=ret->getPointer();
10907           for(int i=0;i<nbOfTuple1;i++)
10908             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10909           ret->copyStringInfoFrom(*a1);
10910           return ret.retn();
10911         }
10912       else
10913         {
10914           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10915           return 0;
10916         }
10917     }
10918   else if(nbOfTuple2==1)
10919     {
10920       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10921       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10922       ret->alloc(nbOfTuple1,nbOfComp1);
10923       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10924       int *pt=ret->getPointer();
10925       for(int i=0;i<nbOfTuple1;i++)
10926         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10927       ret->copyStringInfoFrom(*a1);
10928       return ret.retn();
10929     }
10930   else
10931     {
10932       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10933       return 0;
10934     }
10935 }
10936
10937 /*!
10938  * Divide values of \a this array by values of another DataArrayInt. There are 3
10939  * valid cases.
10940  * 1.  The arrays have same number of tuples and components. Then each value of
10941  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10942  *   _a_ [ i, j ] /= _other_ [ i, j ].
10943  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10944  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10945  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10946  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10947  *
10948  *  \warning No check of division by zero is performed!
10949  *  \param [in] other - an array to divide \a this one by.
10950  *  \throw If \a other is NULL.
10951  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10952  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10953  *         \a other has number of both tuples and components not equal to 1.
10954  */
10955 void DataArrayInt::divideEqual(const DataArrayInt *other)
10956 {
10957   if(!other)
10958     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10959   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10960   checkAllocated(); other->checkAllocated();
10961   int nbOfTuple=getNumberOfTuples();
10962   int nbOfTuple2=other->getNumberOfTuples();
10963   int nbOfComp=getNumberOfComponents();
10964   int nbOfComp2=other->getNumberOfComponents();
10965   if(nbOfTuple==nbOfTuple2)
10966     {
10967       if(nbOfComp==nbOfComp2)
10968         {
10969           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10970         }
10971       else if(nbOfComp2==1)
10972         {
10973           int *ptr=getPointer();
10974           const int *ptrc=other->getConstPointer();
10975           for(int i=0;i<nbOfTuple;i++)
10976             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10977         }
10978       else
10979         throw INTERP_KERNEL::Exception(msg);
10980     }
10981   else if(nbOfTuple2==1)
10982     {
10983       if(nbOfComp2==nbOfComp)
10984         {
10985           int *ptr=getPointer();
10986           const int *ptrc=other->getConstPointer();
10987           for(int i=0;i<nbOfTuple;i++)
10988             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10989         }
10990       else
10991         throw INTERP_KERNEL::Exception(msg);
10992     }
10993   else
10994     throw INTERP_KERNEL::Exception(msg);
10995   declareAsNew();
10996 }
10997
10998
10999 /*!
11000  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11001  * valid cases.
11002  * 1.  The arrays have same number of tuples and components. Then each value of
11003  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11004  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11005  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11006  *   component. Then
11007  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11008  * 3.  The arrays have same number of components and one array, say _a2_, has one
11009  *   tuple. Then
11010  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11011  *
11012  * Info on components is copied either from the first array (in the first case) or from
11013  * the array with maximal number of elements (getNbOfElems()).
11014  *  \warning No check of division by zero is performed!
11015  *  \param [in] a1 - a dividend array.
11016  *  \param [in] a2 - a divisor array.
11017  *  \return DataArrayInt * - the new instance of DataArrayInt.
11018  *          The caller is to delete this result array using decrRef() as it is no more
11019  *          needed.
11020  *  \throw If either \a a1 or \a a2 is NULL.
11021  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11022  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11023  *         none of them has number of tuples or components equal to 1.
11024  */
11025 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11026 {
11027   if(!a1 || !a2)
11028     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11029   int nbOfTuple1=a1->getNumberOfTuples();
11030   int nbOfTuple2=a2->getNumberOfTuples();
11031   int nbOfComp1=a1->getNumberOfComponents();
11032   int nbOfComp2=a2->getNumberOfComponents();
11033   if(nbOfTuple2==nbOfTuple1)
11034     {
11035       if(nbOfComp1==nbOfComp2)
11036         {
11037           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11038           ret->alloc(nbOfTuple2,nbOfComp1);
11039           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11040           ret->copyStringInfoFrom(*a1);
11041           return ret.retn();
11042         }
11043       else if(nbOfComp2==1)
11044         {
11045           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11046           ret->alloc(nbOfTuple1,nbOfComp1);
11047           const int *a2Ptr=a2->getConstPointer();
11048           const int *a1Ptr=a1->getConstPointer();
11049           int *res=ret->getPointer();
11050           for(int i=0;i<nbOfTuple1;i++)
11051             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11052           ret->copyStringInfoFrom(*a1);
11053           return ret.retn();
11054         }
11055       else
11056         {
11057           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11058           return 0;
11059         }
11060     }
11061   else if(nbOfTuple2==1)
11062     {
11063       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11064       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11065       ret->alloc(nbOfTuple1,nbOfComp1);
11066       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11067       int *pt=ret->getPointer();
11068       for(int i=0;i<nbOfTuple1;i++)
11069         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11070       ret->copyStringInfoFrom(*a1);
11071       return ret.retn();
11072     }
11073   else
11074     {
11075       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11076       return 0;
11077     }
11078 }
11079
11080 /*!
11081  * Modify \a this array so that each value becomes a modulus of division of this value by
11082  * a value of another DataArrayInt. There are 3 valid cases.
11083  * 1.  The arrays have same number of tuples and components. Then each value of
11084  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11085  *   _a_ [ i, j ] %= _other_ [ i, j ].
11086  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11087  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11088  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11089  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11090  *
11091  *  \warning No check of division by zero is performed!
11092  *  \param [in] other - a divisor array.
11093  *  \throw If \a other is NULL.
11094  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11095  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11096  *         \a other has number of both tuples and components not equal to 1.
11097  */
11098 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11099 {
11100   if(!other)
11101     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11102   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11103   checkAllocated(); other->checkAllocated();
11104   int nbOfTuple=getNumberOfTuples();
11105   int nbOfTuple2=other->getNumberOfTuples();
11106   int nbOfComp=getNumberOfComponents();
11107   int nbOfComp2=other->getNumberOfComponents();
11108   if(nbOfTuple==nbOfTuple2)
11109     {
11110       if(nbOfComp==nbOfComp2)
11111         {
11112           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11113         }
11114       else if(nbOfComp2==1)
11115         {
11116           if(nbOfComp2==nbOfComp)
11117             {
11118               int *ptr=getPointer();
11119               const int *ptrc=other->getConstPointer();
11120               for(int i=0;i<nbOfTuple;i++)
11121                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11122             }
11123           else
11124             throw INTERP_KERNEL::Exception(msg);
11125         }
11126       else
11127         throw INTERP_KERNEL::Exception(msg);
11128     }
11129   else if(nbOfTuple2==1)
11130     {
11131       int *ptr=getPointer();
11132       const int *ptrc=other->getConstPointer();
11133       for(int i=0;i<nbOfTuple;i++)
11134         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11135     }
11136   else
11137     throw INTERP_KERNEL::Exception(msg);
11138   declareAsNew();
11139 }
11140
11141 /*!
11142  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11143  * valid cases.
11144  *
11145  *  \param [in] a1 - an array to pow up.
11146  *  \param [in] a2 - another array to sum up.
11147  *  \return DataArrayInt * - the new instance of DataArrayInt.
11148  *          The caller is to delete this result array using decrRef() as it is no more
11149  *          needed.
11150  *  \throw If either \a a1 or \a a2 is NULL.
11151  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11152  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11153  *  \throw If there is a negative value in \a a2.
11154  */
11155 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11156 {
11157   if(!a1 || !a2)
11158     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11159   int nbOfTuple=a1->getNumberOfTuples();
11160   int nbOfTuple2=a2->getNumberOfTuples();
11161   int nbOfComp=a1->getNumberOfComponents();
11162   int nbOfComp2=a2->getNumberOfComponents();
11163   if(nbOfTuple!=nbOfTuple2)
11164     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11165   if(nbOfComp!=1 || nbOfComp2!=1)
11166     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11167   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11168   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11169   int *ptr=ret->getPointer();
11170   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11171     {
11172       if(*ptr2>=0)
11173         {
11174           int tmp=1;
11175           for(int j=0;j<*ptr2;j++)
11176             tmp*=*ptr1;
11177           *ptr=tmp;
11178         }
11179       else
11180         {
11181           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11182           throw INTERP_KERNEL::Exception(oss.str().c_str());
11183         }
11184     }
11185   return ret.retn();
11186 }
11187
11188 /*!
11189  * Apply pow on values of another DataArrayInt to values of \a this one.
11190  *
11191  *  \param [in] other - an array to pow to \a this one.
11192  *  \throw If \a other is NULL.
11193  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11194  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11195  *  \throw If there is a negative value in \a other.
11196  */
11197 void DataArrayInt::powEqual(const DataArrayInt *other)
11198 {
11199   if(!other)
11200     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11201   int nbOfTuple=getNumberOfTuples();
11202   int nbOfTuple2=other->getNumberOfTuples();
11203   int nbOfComp=getNumberOfComponents();
11204   int nbOfComp2=other->getNumberOfComponents();
11205   if(nbOfTuple!=nbOfTuple2)
11206     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11207   if(nbOfComp!=1 || nbOfComp2!=1)
11208     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11209   int *ptr=getPointer();
11210   const int *ptrc=other->begin();
11211   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11212     {
11213       if(*ptrc>=0)
11214         {
11215           int tmp=1;
11216           for(int j=0;j<*ptrc;j++)
11217             tmp*=*ptr;
11218           *ptr=tmp;
11219         }
11220       else
11221         {
11222           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11223           throw INTERP_KERNEL::Exception(oss.str().c_str());
11224         }
11225     }
11226   declareAsNew();
11227 }
11228
11229 /*!
11230  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11231  * This map, if applied to \a start array, would make it sorted. For example, if
11232  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11233  * [5,6,0,3,2,7,1,4].
11234  *  \param [in] start - pointer to the first element of the array for which the
11235  *         permutation map is computed.
11236  *  \param [in] end - pointer specifying the end of the array \a start, so that
11237  *         the last value of \a start is \a end[ -1 ].
11238  *  \return int * - the result permutation array that the caller is to delete as it is no
11239  *         more needed.
11240  *  \throw If there are equal values in the input array.
11241  */
11242 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11243 {
11244   std::size_t sz=std::distance(start,end);
11245   int *ret=(int *)malloc(sz*sizeof(int));
11246   int *work=new int[sz];
11247   std::copy(start,end,work);
11248   std::sort(work,work+sz);
11249   if(std::unique(work,work+sz)!=work+sz)
11250     {
11251       delete [] work;
11252       free(ret);
11253       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11254     }
11255   std::map<int,int> m;
11256   for(int *workPt=work;workPt!=work+sz;workPt++)
11257     m[*workPt]=(int)std::distance(work,workPt);
11258   int *iter2=ret;
11259   for(const int *iter=start;iter!=end;iter++,iter2++)
11260     *iter2=m[*iter];
11261   delete [] work;
11262   return ret;
11263 }
11264
11265 /*!
11266  * Returns a new DataArrayInt containing an arithmetic progression
11267  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11268  * function.
11269  *  \param [in] begin - the start value of the result sequence.
11270  *  \param [in] end - limiting value, so that every value of the result array is less than
11271  *              \a end.
11272  *  \param [in] step - specifies the increment or decrement.
11273  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11274  *          array using decrRef() as it is no more needed.
11275  *  \throw If \a step == 0.
11276  *  \throw If \a end < \a begin && \a step > 0.
11277  *  \throw If \a end > \a begin && \a step < 0.
11278  */
11279 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11280 {
11281   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11282   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11283   ret->alloc(nbOfTuples,1);
11284   int *ptr=ret->getPointer();
11285   if(step>0)
11286     {
11287       for(int i=begin;i<end;i+=step,ptr++)
11288         *ptr=i;
11289     }
11290   else
11291     {
11292       for(int i=begin;i>end;i+=step,ptr++)
11293         *ptr=i;
11294     }
11295   return ret.retn();
11296 }
11297
11298 /*!
11299  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11300  * Server side.
11301  */
11302 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11303 {
11304   tinyInfo.resize(2);
11305   if(isAllocated())
11306     {
11307       tinyInfo[0]=getNumberOfTuples();
11308       tinyInfo[1]=getNumberOfComponents();
11309     }
11310   else
11311     {
11312       tinyInfo[0]=-1;
11313       tinyInfo[1]=-1;
11314     }
11315 }
11316
11317 /*!
11318  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11319  * Server side.
11320  */
11321 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11322 {
11323   if(isAllocated())
11324     {
11325       int nbOfCompo=getNumberOfComponents();
11326       tinyInfo.resize(nbOfCompo+1);
11327       tinyInfo[0]=getName();
11328       for(int i=0;i<nbOfCompo;i++)
11329         tinyInfo[i+1]=getInfoOnComponent(i);
11330     }
11331   else
11332     {
11333       tinyInfo.resize(1);
11334       tinyInfo[0]=getName();
11335     }
11336 }
11337
11338 /*!
11339  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11340  * This method returns if a feeding is needed.
11341  */
11342 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11343 {
11344   int nbOfTuple=tinyInfoI[0];
11345   int nbOfComp=tinyInfoI[1];
11346   if(nbOfTuple!=-1 || nbOfComp!=-1)
11347     {
11348       alloc(nbOfTuple,nbOfComp);
11349       return true;
11350     }
11351   return false;
11352 }
11353
11354 /*!
11355  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11356  * This method returns if a feeding is needed.
11357  */
11358 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11359 {
11360   setName(tinyInfoS[0]);
11361   if(isAllocated())
11362     {
11363       int nbOfCompo=tinyInfoI[1];
11364       for(int i=0;i<nbOfCompo;i++)
11365         setInfoOnComponent(i,tinyInfoS[i+1]);
11366     }
11367 }
11368
11369 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11370 {
11371   if(_da)
11372     {
11373       _da->incrRef();
11374       if(_da->isAllocated())
11375         {
11376           _nb_comp=da->getNumberOfComponents();
11377           _nb_tuple=da->getNumberOfTuples();
11378           _pt=da->getPointer();
11379         }
11380     }
11381 }
11382
11383 DataArrayIntIterator::~DataArrayIntIterator()
11384 {
11385   if(_da)
11386     _da->decrRef();
11387 }
11388
11389 DataArrayIntTuple *DataArrayIntIterator::nextt()
11390 {
11391   if(_tuple_id<_nb_tuple)
11392     {
11393       _tuple_id++;
11394       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11395       _pt+=_nb_comp;
11396       return ret;
11397     }
11398   else
11399     return 0;
11400 }
11401
11402 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11403 {
11404 }
11405
11406 std::string DataArrayIntTuple::repr() const
11407 {
11408   std::ostringstream oss; oss << "(";
11409   for(int i=0;i<_nb_of_compo-1;i++)
11410     oss << _pt[i] << ", ";
11411   oss << _pt[_nb_of_compo-1] << ")";
11412   return oss.str();
11413 }
11414
11415 int DataArrayIntTuple::intValue() const
11416 {
11417   if(_nb_of_compo==1)
11418     return *_pt;
11419   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11420 }
11421
11422 /*!
11423  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11424  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11425  * 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
11426  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11427  */
11428 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11429 {
11430   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11431     {
11432       DataArrayInt *ret=DataArrayInt::New();
11433       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11434       return ret;
11435     }
11436   else
11437     {
11438       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11439       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11440       throw INTERP_KERNEL::Exception(oss.str().c_str());
11441     }
11442 }