Salome HOME
First draft for dense matrix
[modules/med.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  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5589  * Server side.
5590  */
5591 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5592 {
5593   tinyInfo.resize(2);
5594   if(isAllocated())
5595     {
5596       tinyInfo[0]=getNumberOfTuples();
5597       tinyInfo[1]=getNumberOfComponents();
5598     }
5599   else
5600     {
5601       tinyInfo[0]=-1;
5602       tinyInfo[1]=-1;
5603     }
5604 }
5605
5606 /*!
5607  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5608  * Server side.
5609  */
5610 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5611 {
5612   if(isAllocated())
5613     {
5614       int nbOfCompo=getNumberOfComponents();
5615       tinyInfo.resize(nbOfCompo+1);
5616       tinyInfo[0]=getName();
5617       for(int i=0;i<nbOfCompo;i++)
5618         tinyInfo[i+1]=getInfoOnComponent(i);
5619     }
5620   else
5621     {
5622       tinyInfo.resize(1);
5623       tinyInfo[0]=getName();
5624     }
5625 }
5626
5627 /*!
5628  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5629  * This method returns if a feeding is needed.
5630  */
5631 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5632 {
5633   int nbOfTuple=tinyInfoI[0];
5634   int nbOfComp=tinyInfoI[1];
5635   if(nbOfTuple!=-1 || nbOfComp!=-1)
5636     {
5637       alloc(nbOfTuple,nbOfComp);
5638       return true;
5639     }
5640   return false;
5641 }
5642
5643 /*!
5644  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5645  */
5646 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5647 {
5648   setName(tinyInfoS[0]);
5649   if(isAllocated())
5650     {
5651       int nbOfCompo=getNumberOfComponents();
5652       for(int i=0;i<nbOfCompo;i++)
5653         setInfoOnComponent(i,tinyInfoS[i+1]);
5654     }
5655 }
5656
5657 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5658 {
5659   if(_da)
5660     {
5661       _da->incrRef();
5662       if(_da->isAllocated())
5663         {
5664           _nb_comp=da->getNumberOfComponents();
5665           _nb_tuple=da->getNumberOfTuples();
5666           _pt=da->getPointer();
5667         }
5668     }
5669 }
5670
5671 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5672 {
5673   if(_da)
5674     _da->decrRef();
5675 }
5676
5677 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5678 {
5679   if(_tuple_id<_nb_tuple)
5680     {
5681       _tuple_id++;
5682       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5683       _pt+=_nb_comp;
5684       return ret;
5685     }
5686   else
5687     return 0;
5688 }
5689
5690 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5691 {
5692 }
5693
5694
5695 std::string DataArrayDoubleTuple::repr() const
5696 {
5697   std::ostringstream oss; oss.precision(17); oss << "(";
5698   for(int i=0;i<_nb_of_compo-1;i++)
5699     oss << _pt[i] << ", ";
5700   oss << _pt[_nb_of_compo-1] << ")";
5701   return oss.str();
5702 }
5703
5704 double DataArrayDoubleTuple::doubleValue() const
5705 {
5706   if(_nb_of_compo==1)
5707     return *_pt;
5708   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5709 }
5710
5711 /*!
5712  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5713  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5714  * 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
5715  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5716  */
5717 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5718 {
5719   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5720     {
5721       DataArrayDouble *ret=DataArrayDouble::New();
5722       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5723       return ret;
5724     }
5725   else
5726     {
5727       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5728       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5729       throw INTERP_KERNEL::Exception(oss.str().c_str());
5730     }
5731 }
5732
5733 /*!
5734  * Returns a new instance of DataArrayInt. The caller is to delete this array
5735  * using decrRef() as it is no more needed. 
5736  */
5737 DataArrayInt *DataArrayInt::New()
5738 {
5739   return new DataArrayInt;
5740 }
5741
5742 /*!
5743  * Checks if raw data is allocated. Read more on the raw data
5744  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5745  *  \return bool - \a true if the raw data is allocated, \a false else.
5746  */
5747 bool DataArrayInt::isAllocated() const
5748 {
5749   return getConstPointer()!=0;
5750 }
5751
5752 /*!
5753  * Checks if raw data is allocated and throws an exception if it is not the case.
5754  *  \throw If the raw data is not allocated.
5755  */
5756 void DataArrayInt::checkAllocated() const
5757 {
5758   if(!isAllocated())
5759     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5760 }
5761
5762 /*!
5763  * This method desallocated \a this without modification of informations relative to the components.
5764  * After call of this method, DataArrayInt::isAllocated will return false.
5765  * If \a this is already not allocated, \a this is let unchanged.
5766  */
5767 void DataArrayInt::desallocate()
5768 {
5769   _mem.destroy();
5770 }
5771
5772 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5773 {
5774   std::size_t sz(_mem.getNbOfElemAllocated());
5775   sz*=sizeof(int);
5776   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5777 }
5778
5779 /*!
5780  * Returns the only one value in \a this, if and only if number of elements
5781  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5782  *  \return double - the sole value stored in \a this array.
5783  *  \throw If at least one of conditions stated above is not fulfilled.
5784  */
5785 int DataArrayInt::intValue() const
5786 {
5787   if(isAllocated())
5788     {
5789       if(getNbOfElems()==1)
5790         {
5791           return *getConstPointer();
5792         }
5793       else
5794         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5795     }
5796   else
5797     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5798 }
5799
5800 /*!
5801  * Returns an integer value characterizing \a this array, which is useful for a quick
5802  * comparison of many instances of DataArrayInt.
5803  *  \return int - the hash value.
5804  *  \throw If \a this is not allocated.
5805  */
5806 int DataArrayInt::getHashCode() const
5807 {
5808   checkAllocated();
5809   std::size_t nbOfElems=getNbOfElems();
5810   int ret=nbOfElems*65536;
5811   int delta=3;
5812   if(nbOfElems>48)
5813     delta=nbOfElems/8;
5814   int ret0=0;
5815   const int *pt=begin();
5816   for(std::size_t i=0;i<nbOfElems;i+=delta)
5817     ret0+=pt[i] & 0x1FFF;
5818   return ret+ret0;
5819 }
5820
5821 /*!
5822  * Checks the number of tuples.
5823  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5824  *  \throw If \a this is not allocated.
5825  */
5826 bool DataArrayInt::empty() const
5827 {
5828   checkAllocated();
5829   return getNumberOfTuples()==0;
5830 }
5831
5832 /*!
5833  * Returns a full copy of \a this. For more info on copying data arrays see
5834  * \ref MEDCouplingArrayBasicsCopyDeep.
5835  *  \return DataArrayInt * - a new instance of DataArrayInt.
5836  */
5837 DataArrayInt *DataArrayInt::deepCpy() const
5838 {
5839   return new DataArrayInt(*this);
5840 }
5841
5842 /*!
5843  * Returns either a \a deep or \a shallow copy of this array. For more info see
5844  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5845  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5846  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5847  *          == \a true) or \a this instance (if \a dCpy == \a false).
5848  */
5849 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5850 {
5851   if(dCpy)
5852     return deepCpy();
5853   else
5854     {
5855       incrRef();
5856       return const_cast<DataArrayInt *>(this);
5857     }
5858 }
5859
5860 /*!
5861  * Copies all the data from another DataArrayInt. For more info see
5862  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5863  *  \param [in] other - another instance of DataArrayInt to copy data from.
5864  *  \throw If the \a other is not allocated.
5865  */
5866 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5867 {
5868   other.checkAllocated();
5869   int nbOfTuples=other.getNumberOfTuples();
5870   int nbOfComp=other.getNumberOfComponents();
5871   allocIfNecessary(nbOfTuples,nbOfComp);
5872   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5873   int *pt=getPointer();
5874   const int *ptI=other.getConstPointer();
5875   for(std::size_t i=0;i<nbOfElems;i++)
5876     pt[i]=ptI[i];
5877   copyStringInfoFrom(other);
5878 }
5879
5880 /*!
5881  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5882  * 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.
5883  * If \a this has not already been allocated, number of components is set to one.
5884  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5885  * 
5886  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5887  */
5888 void DataArrayInt::reserve(std::size_t nbOfElems)
5889 {
5890   int nbCompo=getNumberOfComponents();
5891   if(nbCompo==1)
5892     {
5893       _mem.reserve(nbOfElems);
5894     }
5895   else if(nbCompo==0)
5896     {
5897       _mem.reserve(nbOfElems);
5898       _info_on_compo.resize(1);
5899     }
5900   else
5901     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5902 }
5903
5904 /*!
5905  * 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
5906  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5907  *
5908  * \param [in] val the value to be added in \a this
5909  * \throw If \a this has already been allocated with number of components different from one.
5910  * \sa DataArrayInt::pushBackValsSilent
5911  */
5912 void DataArrayInt::pushBackSilent(int val)
5913 {
5914   int nbCompo=getNumberOfComponents();
5915   if(nbCompo==1)
5916     _mem.pushBack(val);
5917   else if(nbCompo==0)
5918     {
5919       _info_on_compo.resize(1);
5920       _mem.pushBack(val);
5921     }
5922   else
5923     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5924 }
5925
5926 /*!
5927  * 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
5928  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5929  *
5930  *  \param [in] valsBg - an array of values to push at the end of \this.
5931  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5932  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5933  * \throw If \a this has already been allocated with number of components different from one.
5934  * \sa DataArrayInt::pushBackSilent
5935  */
5936 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5937 {
5938   int nbCompo=getNumberOfComponents();
5939   if(nbCompo==1)
5940     _mem.insertAtTheEnd(valsBg,valsEnd);
5941   else if(nbCompo==0)
5942     {
5943       _info_on_compo.resize(1);
5944       _mem.insertAtTheEnd(valsBg,valsEnd);
5945     }
5946   else
5947     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5948 }
5949
5950 /*!
5951  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5952  * \throw If \a this is already empty.
5953  * \throw If \a this has number of components different from one.
5954  */
5955 int DataArrayInt::popBackSilent()
5956 {
5957   if(getNumberOfComponents()==1)
5958     return _mem.popBack();
5959   else
5960     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5961 }
5962
5963 /*!
5964  * 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.
5965  *
5966  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5967  */
5968 void DataArrayInt::pack() const
5969 {
5970   _mem.pack();
5971 }
5972
5973 /*!
5974  * Allocates the raw data in memory. If exactly as same memory as needed already
5975  * allocated, it is not re-allocated.
5976  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5977  *  \param [in] nbOfCompo - number of components of data to allocate.
5978  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5979  */
5980 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5981 {
5982   if(isAllocated())
5983     {
5984       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5985         alloc(nbOfTuple,nbOfCompo);
5986     }
5987   else
5988     alloc(nbOfTuple,nbOfCompo);
5989 }
5990
5991 /*!
5992  * Allocates the raw data in memory. If the memory was already allocated, then it is
5993  * freed and re-allocated. See an example of this method use
5994  * \ref MEDCouplingArraySteps1WC "here".
5995  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5996  *  \param [in] nbOfCompo - number of components of data to allocate.
5997  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5998  */
5999 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6000 {
6001   if(nbOfTuple<0 || nbOfCompo<0)
6002     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6003   _info_on_compo.resize(nbOfCompo);
6004   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6005   declareAsNew();
6006 }
6007
6008 /*!
6009  * Assign zero to all values in \a this array. To know more on filling arrays see
6010  * \ref MEDCouplingArrayFill.
6011  * \throw If \a this is not allocated.
6012  */
6013 void DataArrayInt::fillWithZero()
6014 {
6015   checkAllocated();
6016   _mem.fillWithValue(0);
6017   declareAsNew();
6018 }
6019
6020 /*!
6021  * Assign \a val to all values in \a this array. To know more on filling arrays see
6022  * \ref MEDCouplingArrayFill.
6023  *  \param [in] val - the value to fill with.
6024  *  \throw If \a this is not allocated.
6025  */
6026 void DataArrayInt::fillWithValue(int val)
6027 {
6028   checkAllocated();
6029   _mem.fillWithValue(val);
6030   declareAsNew();
6031 }
6032
6033 /*!
6034  * Set all values in \a this array so that the i-th element equals to \a init + i
6035  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6036  *  \param [in] init - value to assign to the first element of array.
6037  *  \throw If \a this->getNumberOfComponents() != 1
6038  *  \throw If \a this is not allocated.
6039  */
6040 void DataArrayInt::iota(int init)
6041 {
6042   checkAllocated();
6043   if(getNumberOfComponents()!=1)
6044     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6045   int *ptr=getPointer();
6046   int ntuples=getNumberOfTuples();
6047   for(int i=0;i<ntuples;i++)
6048     ptr[i]=init+i;
6049   declareAsNew();
6050 }
6051
6052 /*!
6053  * Returns a textual and human readable representation of \a this instance of
6054  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6055  *  \return std::string - text describing \a this DataArrayInt.
6056  */
6057 std::string DataArrayInt::repr() const
6058 {
6059   std::ostringstream ret;
6060   reprStream(ret);
6061   return ret.str();
6062 }
6063
6064 std::string DataArrayInt::reprZip() const
6065 {
6066   std::ostringstream ret;
6067   reprZipStream(ret);
6068   return ret.str();
6069 }
6070
6071 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6072 {
6073   static const char SPACE[4]={' ',' ',' ',' '};
6074   checkAllocated();
6075   std::string idt(indent,' ');
6076   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6077   if(byteArr)
6078     {
6079       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6080       if(std::string(type)=="Int32")
6081         {
6082           const char *data(reinterpret_cast<const char *>(begin()));
6083           std::size_t sz(getNbOfElems()*sizeof(int));
6084           byteArr->insertAtTheEnd(data,data+sz);
6085           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6086         }
6087       else if(std::string(type)=="Int8")
6088         {
6089           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6090           std::copy(begin(),end(),(char *)tmp);
6091           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6092           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6093         }
6094       else if(std::string(type)=="UInt8")
6095         {
6096           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6097           std::copy(begin(),end(),(unsigned char *)tmp);
6098           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6099           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6100         }
6101       else
6102         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6103     }
6104   else
6105     {
6106       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6107       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6108     }
6109   ofs << std::endl << idt << "</DataArray>\n";
6110 }
6111
6112 void DataArrayInt::reprStream(std::ostream& stream) const
6113 {
6114   stream << "Name of int array : \"" << _name << "\"\n";
6115   reprWithoutNameStream(stream);
6116 }
6117
6118 void DataArrayInt::reprZipStream(std::ostream& stream) const
6119 {
6120   stream << "Name of int array : \"" << _name << "\"\n";
6121   reprZipWithoutNameStream(stream);
6122 }
6123
6124 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6125 {
6126   DataArray::reprWithoutNameStream(stream);
6127   _mem.repr(getNumberOfComponents(),stream);
6128 }
6129
6130 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6131 {
6132   DataArray::reprWithoutNameStream(stream);
6133   _mem.reprZip(getNumberOfComponents(),stream);
6134 }
6135
6136 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6137 {
6138   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6139   const int *data=getConstPointer();
6140   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6141   if(nbTuples*nbComp>=1)
6142     {
6143       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6144       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6145       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6146       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6147     }
6148   else
6149     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6150   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6151 }
6152
6153 /*!
6154  * Method that gives a quick overvien of \a this for python.
6155  */
6156 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6157 {
6158   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6159   stream << "DataArrayInt C++ instance at " << this << ". ";
6160   if(isAllocated())
6161     {
6162       int nbOfCompo=(int)_info_on_compo.size();
6163       if(nbOfCompo>=1)
6164         {
6165           int nbOfTuples=getNumberOfTuples();
6166           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6167           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6168         }
6169       else
6170         stream << "Number of components : 0.";
6171     }
6172   else
6173     stream << "*** No data allocated ****";
6174 }
6175
6176 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6177 {
6178   const int *data=begin();
6179   int nbOfTuples=getNumberOfTuples();
6180   int nbOfCompo=(int)_info_on_compo.size();
6181   std::ostringstream oss2; oss2 << "[";
6182   std::string oss2Str(oss2.str());
6183   bool isFinished=true;
6184   for(int i=0;i<nbOfTuples && isFinished;i++)
6185     {
6186       if(nbOfCompo>1)
6187         {
6188           oss2 << "(";
6189           for(int j=0;j<nbOfCompo;j++,data++)
6190             {
6191               oss2 << *data;
6192               if(j!=nbOfCompo-1) oss2 << ", ";
6193             }
6194           oss2 << ")";
6195         }
6196       else
6197         oss2 << *data++;
6198       if(i!=nbOfTuples-1) oss2 << ", ";
6199       std::string oss3Str(oss2.str());
6200       if(oss3Str.length()<maxNbOfByteInRepr)
6201         oss2Str=oss3Str;
6202       else
6203         isFinished=false;
6204     }
6205   stream << oss2Str;
6206   if(!isFinished)
6207     stream << "... ";
6208   stream << "]";
6209 }
6210
6211 /*!
6212  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6213  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6214  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6215  *         to \a this array.
6216  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6217  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6218  *  \throw If \a this->getNumberOfComponents() != 1
6219  *  \throw If any value of \a this can't be used as a valid index for 
6220  *         [\a indArrBg, \a indArrEnd).
6221  */
6222 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6223 {
6224   checkAllocated();
6225   if(getNumberOfComponents()!=1)
6226     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6227   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6228   int nbOfTuples=getNumberOfTuples();
6229   int *pt=getPointer();
6230   for(int i=0;i<nbOfTuples;i++,pt++)
6231     {
6232       if(*pt>=0 && *pt<nbElemsIn)
6233         *pt=indArrBg[*pt];
6234       else
6235         {
6236           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6237           throw INTERP_KERNEL::Exception(oss.str().c_str());
6238         }
6239     }
6240   declareAsNew();
6241 }
6242
6243 /*!
6244  * Computes distribution of values of \a this one-dimensional array between given value
6245  * ranges (casts). This method is typically useful for entity number spliting by types,
6246  * for example. 
6247  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6248  *           check of this is be done. If not, the result is not warranted. 
6249  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6250  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6251  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6252  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6253  *         should be more than every value in \a this array.
6254  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6255  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6256  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6257  *         (same number of tuples and components), the caller is to delete 
6258  *         using decrRef() as it is no more needed.
6259  *         This array contains indices of ranges for every value of \a this array. I.e.
6260  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6261  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6262  *         this in which cast it holds.
6263  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6264  *         array, the caller is to delete using decrRef() as it is no more needed.
6265  *         This array contains ranks of values of \a this array within ranges
6266  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6267  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6268  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6269  *         for each tuple its rank inside its cast. The rank is computed as difference
6270  *         between the value and the lowest value of range.
6271  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6272  *         ranges (casts) to which at least one value of \a this array belongs.
6273  *         Or, in other words, this param contains the casts that \a this contains.
6274  *         The caller is to delete this array using decrRef() as it is no more needed.
6275  *
6276  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6277  *            the output of this method will be : 
6278  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6279  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6280  * - \a castsPresent  : [0,1]
6281  *
6282  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6283  * range #1 and its rank within this range is 2; etc.
6284  *
6285  *  \throw If \a this->getNumberOfComponents() != 1.
6286  *  \throw If \a arrEnd - arrBg < 2.
6287  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6288  */
6289 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6290                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6291     {
6292   checkAllocated();
6293   if(getNumberOfComponents()!=1)
6294     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6295   int nbOfTuples=getNumberOfTuples();
6296   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6297   if(nbOfCast<2)
6298     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6299   nbOfCast--;
6300   const int *work=getConstPointer();
6301   typedef std::reverse_iterator<const int *> rintstart;
6302   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6303   rintstart end2(arrBg);
6304   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6305   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6306   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6307   ret1->alloc(nbOfTuples,1);
6308   ret2->alloc(nbOfTuples,1);
6309   int *ret1Ptr=ret1->getPointer();
6310   int *ret2Ptr=ret2->getPointer();
6311   std::set<std::size_t> castsDetected;
6312   for(int i=0;i<nbOfTuples;i++)
6313     {
6314       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6315       std::size_t pos=std::distance(bg,res);
6316       std::size_t pos2=nbOfCast-pos;
6317       if(pos2<nbOfCast)
6318         {
6319           ret1Ptr[i]=(int)pos2;
6320           ret2Ptr[i]=work[i]-arrBg[pos2];
6321           castsDetected.insert(pos2);
6322         }
6323       else
6324         {
6325           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6326           throw INTERP_KERNEL::Exception(oss.str().c_str());
6327         }
6328     }
6329   ret3->alloc((int)castsDetected.size(),1);
6330   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6331   castArr=ret1.retn();
6332   rankInsideCast=ret2.retn();
6333   castsPresent=ret3.retn();
6334     }
6335
6336 /*!
6337  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6338  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6339  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6340  * new value in place \a indArr[ \a v ] is i.
6341  *  \param [in] indArrBg - the array holding indices within the result array to assign
6342  *         indices of values of \a this array pointing to values of \a indArrBg.
6343  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6344  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6345  *  \return DataArrayInt * - the new instance of DataArrayInt.
6346  *          The caller is to delete this result array using decrRef() as it is no more
6347  *          needed.
6348  *  \throw If \a this->getNumberOfComponents() != 1.
6349  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6350  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6351  */
6352 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6353 {
6354   checkAllocated();
6355   if(getNumberOfComponents()!=1)
6356     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6357   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6358   int nbOfTuples=getNumberOfTuples();
6359   const int *pt=getConstPointer();
6360   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6361   ret->alloc(nbOfTuples,1);
6362   ret->fillWithValue(-1);
6363   int *tmp=ret->getPointer();
6364   for(int i=0;i<nbOfTuples;i++,pt++)
6365     {
6366       if(*pt>=0 && *pt<nbElemsIn)
6367         {
6368           int pos=indArrBg[*pt];
6369           if(pos>=0 && pos<nbOfTuples)
6370             tmp[pos]=i;
6371           else
6372             {
6373               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6374               throw INTERP_KERNEL::Exception(oss.str().c_str());
6375             }
6376         }
6377       else
6378         {
6379           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6380           throw INTERP_KERNEL::Exception(oss.str().c_str());
6381         }
6382     }
6383   return ret.retn();
6384 }
6385
6386 /*!
6387  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6388  * from values of \a this array, which is supposed to contain a renumbering map in 
6389  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6390  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6391  *  \param [in] newNbOfElem - the number of tuples in the result array.
6392  *  \return DataArrayInt * - the new instance of DataArrayInt.
6393  *          The caller is to delete this result array using decrRef() as it is no more
6394  *          needed.
6395  * 
6396  *  \if ENABLE_EXAMPLES
6397  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6398  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6399  *  \endif
6400  */
6401 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6402 {
6403   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6404   ret->alloc(newNbOfElem,1);
6405   int nbOfOldNodes=getNumberOfTuples();
6406   const int *old2New=getConstPointer();
6407   int *pt=ret->getPointer();
6408   for(int i=0;i!=nbOfOldNodes;i++)
6409     {
6410       int newp(old2New[i]);
6411       if(newp!=-1)
6412         {
6413           if(newp>=0 && newp<newNbOfElem)
6414             pt[newp]=i;
6415           else
6416             {
6417               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6418               throw INTERP_KERNEL::Exception(oss.str().c_str());
6419             }
6420         }
6421     }
6422   return ret.retn();
6423 }
6424
6425 /*!
6426  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6427  * 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]
6428  */
6429 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6430 {
6431   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6432   ret->alloc(newNbOfElem,1);
6433   int nbOfOldNodes=getNumberOfTuples();
6434   const int *old2New=getConstPointer();
6435   int *pt=ret->getPointer();
6436   for(int i=nbOfOldNodes-1;i>=0;i--)
6437     {
6438       int newp(old2New[i]);
6439       if(newp!=-1)
6440         {
6441           if(newp>=0 && newp<newNbOfElem)
6442             pt[newp]=i;
6443           else
6444             {
6445               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6446               throw INTERP_KERNEL::Exception(oss.str().c_str());
6447             }
6448         }
6449     }
6450   return ret.retn();
6451 }
6452
6453 /*!
6454  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6455  * from values of \a this array, which is supposed to contain a renumbering map in 
6456  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6457  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6458  *  \param [in] newNbOfElem - the number of tuples in the result array.
6459  *  \return DataArrayInt * - the new instance of DataArrayInt.
6460  *          The caller is to delete this result array using decrRef() as it is no more
6461  *          needed.
6462  * 
6463  *  \if ENABLE_EXAMPLES
6464  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6465  *
6466  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6467  *  \endif
6468  */
6469 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6470 {
6471   checkAllocated();
6472   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6473   ret->alloc(oldNbOfElem,1);
6474   const int *new2Old=getConstPointer();
6475   int *pt=ret->getPointer();
6476   std::fill(pt,pt+oldNbOfElem,-1);
6477   int nbOfNewElems=getNumberOfTuples();
6478   for(int i=0;i<nbOfNewElems;i++)
6479     {
6480       int v(new2Old[i]);
6481       if(v>=0 && v<oldNbOfElem)
6482         pt[v]=i;
6483       else
6484         {
6485           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6486           throw INTERP_KERNEL::Exception(oss.str().c_str());
6487         }
6488     }
6489   return ret.retn();
6490 }
6491
6492 /*!
6493  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6494  * mismatch is given.
6495  * 
6496  * \param [in] other the instance to be compared with \a this
6497  * \param [out] reason In case of inequality returns the reason.
6498  * \sa DataArrayInt::isEqual
6499  */
6500 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6501 {
6502   if(!areInfoEqualsIfNotWhy(other,reason))
6503     return false;
6504   return _mem.isEqual(other._mem,0,reason);
6505 }
6506
6507 /*!
6508  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6509  * \ref MEDCouplingArrayBasicsCompare.
6510  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6511  *  \return bool - \a true if the two arrays are equal, \a false else.
6512  */
6513 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6514 {
6515   std::string tmp;
6516   return isEqualIfNotWhy(other,tmp);
6517 }
6518
6519 /*!
6520  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6521  * \ref MEDCouplingArrayBasicsCompare.
6522  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6523  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6524  */
6525 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6526 {
6527   std::string tmp;
6528   return _mem.isEqual(other._mem,0,tmp);
6529 }
6530
6531 /*!
6532  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6533  * performed on sorted value sequences.
6534  * For more info see\ref MEDCouplingArrayBasicsCompare.
6535  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6536  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6537  */
6538 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6539 {
6540   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6541   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6542   a->sort();
6543   b->sort();
6544   return a->isEqualWithoutConsideringStr(*b);
6545 }
6546
6547 /*!
6548  * This method compares content of input vector \a v and \a this.
6549  * 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.
6550  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6551  *
6552  * \param [in] v - the vector of 'flags' to be compared with \a this.
6553  *
6554  * \throw If \a this is not sorted ascendingly.
6555  * \throw If \a this has not exactly one component.
6556  * \throw If \a this is not allocated.
6557  */
6558 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6559 {
6560   checkAllocated();
6561   if(getNumberOfComponents()!=1)
6562     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6563   const int *w(begin()),*end2(end());
6564   int refVal=-std::numeric_limits<int>::max();
6565   int i=0;
6566   std::vector<bool>::const_iterator it(v.begin());
6567   for(;it!=v.end();it++,i++)
6568     {
6569       if(*it)
6570         {
6571           if(w!=end2)
6572             {
6573               if(*w++==i)
6574                 {
6575                   if(i>refVal)
6576                     refVal=i;
6577                   else
6578                     {
6579                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6580                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6581                     }
6582                 }
6583               else
6584                 return false;
6585             }
6586           else
6587             return false;
6588         }
6589     }
6590   return w==end2;
6591 }
6592
6593 /*!
6594  * Sorts values of the array.
6595  *  \param [in] asc - \a true means ascending order, \a false, descending.
6596  *  \throw If \a this is not allocated.
6597  *  \throw If \a this->getNumberOfComponents() != 1.
6598  */
6599 void DataArrayInt::sort(bool asc)
6600 {
6601   checkAllocated();
6602   if(getNumberOfComponents()!=1)
6603     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6604   _mem.sort(asc);
6605   declareAsNew();
6606 }
6607
6608 /*!
6609  * Computes for each tuple the sum of number of components values in the tuple and return it.
6610  * 
6611  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6612  *          same number of tuples as \a this array and one component.
6613  *          The caller is to delete this result array using decrRef() as it is no more
6614  *          needed.
6615  *  \throw If \a this is not allocated.
6616  */
6617 DataArrayInt *DataArrayInt::sumPerTuple() const
6618 {
6619   checkAllocated();
6620   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6621   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6622   ret->alloc(nbOfTuple,1);
6623   const int *src(getConstPointer());
6624   int *dest(ret->getPointer());
6625   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6626     *dest=std::accumulate(src,src+nbOfComp,0);
6627   return ret.retn();
6628 }
6629
6630 /*!
6631  * Reverse the array values.
6632  *  \throw If \a this->getNumberOfComponents() < 1.
6633  *  \throw If \a this is not allocated.
6634  */
6635 void DataArrayInt::reverse()
6636 {
6637   checkAllocated();
6638   _mem.reverse(getNumberOfComponents());
6639   declareAsNew();
6640 }
6641
6642 /*!
6643  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6644  * If not an exception is thrown.
6645  *  \param [in] increasing - if \a true, the array values should be increasing.
6646  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6647  *         increasing arg.
6648  *  \throw If \a this->getNumberOfComponents() != 1.
6649  *  \throw If \a this is not allocated.
6650  */
6651 void DataArrayInt::checkMonotonic(bool increasing) const
6652 {
6653   if(!isMonotonic(increasing))
6654     {
6655       if (increasing)
6656         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6657       else
6658         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6659     }
6660 }
6661
6662 /*!
6663  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6664  *  \param [in] increasing - if \a true, array values should be increasing.
6665  *  \return bool - \a true if values change in accordance with \a increasing arg.
6666  *  \throw If \a this->getNumberOfComponents() != 1.
6667  *  \throw If \a this is not allocated.
6668  */
6669 bool DataArrayInt::isMonotonic(bool increasing) const
6670 {
6671   checkAllocated();
6672   if(getNumberOfComponents()!=1)
6673     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6674   int nbOfElements=getNumberOfTuples();
6675   const int *ptr=getConstPointer();
6676   if(nbOfElements==0)
6677     return true;
6678   int ref=ptr[0];
6679   if(increasing)
6680     {
6681       for(int i=1;i<nbOfElements;i++)
6682         {
6683           if(ptr[i]>=ref)
6684             ref=ptr[i];
6685           else
6686             return false;
6687         }
6688     }
6689   else
6690     {
6691       for(int i=1;i<nbOfElements;i++)
6692         {
6693           if(ptr[i]<=ref)
6694             ref=ptr[i];
6695           else
6696             return false;
6697         }
6698     }
6699   return true;
6700 }
6701
6702 /*!
6703  * This method check that array consistently INCREASING or DECREASING in value.
6704  */
6705 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6706 {
6707   checkAllocated();
6708   if(getNumberOfComponents()!=1)
6709     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6710   int nbOfElements=getNumberOfTuples();
6711   const int *ptr=getConstPointer();
6712   if(nbOfElements==0)
6713     return true;
6714   int ref=ptr[0];
6715   if(increasing)
6716     {
6717       for(int i=1;i<nbOfElements;i++)
6718         {
6719           if(ptr[i]>ref)
6720             ref=ptr[i];
6721           else
6722             return false;
6723         }
6724     }
6725   else
6726     {
6727       for(int i=1;i<nbOfElements;i++)
6728         {
6729           if(ptr[i]<ref)
6730             ref=ptr[i];
6731           else
6732             return false;
6733         }
6734     }
6735   return true;
6736 }
6737
6738 /*!
6739  * This method check that array consistently INCREASING or DECREASING in value.
6740  */
6741 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6742 {
6743   if(!isStrictlyMonotonic(increasing))
6744     {
6745       if (increasing)
6746         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6747       else
6748         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6749     }
6750 }
6751
6752 /*!
6753  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6754  * one-dimensional arrays that must be of the same length. The result array describes
6755  * correspondence between \a this and \a other arrays, so that 
6756  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6757  * not possible because some element in \a other is not in \a this, an exception is thrown.
6758  *  \param [in] other - an array to compute permutation to.
6759  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6760  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6761  * no more needed.
6762  *  \throw If \a this->getNumberOfComponents() != 1.
6763  *  \throw If \a other->getNumberOfComponents() != 1.
6764  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6765  *  \throw If \a other includes a value which is not in \a this array.
6766  * 
6767  *  \if ENABLE_EXAMPLES
6768  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6769  *
6770  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6771  *  \endif
6772  */
6773 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6774 {
6775   checkAllocated();
6776   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6777     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6778   int nbTuple=getNumberOfTuples();
6779   other.checkAllocated();
6780   if(nbTuple!=other.getNumberOfTuples())
6781     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6782   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6783   ret->alloc(nbTuple,1);
6784   ret->fillWithValue(-1);
6785   const int *pt=getConstPointer();
6786   std::map<int,int> mm;
6787   for(int i=0;i<nbTuple;i++)
6788     mm[pt[i]]=i;
6789   pt=other.getConstPointer();
6790   int *retToFill=ret->getPointer();
6791   for(int i=0;i<nbTuple;i++)
6792     {
6793       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6794       if(it==mm.end())
6795         {
6796           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6797           throw INTERP_KERNEL::Exception(oss.str().c_str());
6798         }
6799       retToFill[i]=(*it).second;
6800     }
6801   return ret.retn();
6802 }
6803
6804 /*!
6805  * Sets a C array to be used as raw data of \a this. The previously set info
6806  *  of components is retained and re-sized. 
6807  * For more info see \ref MEDCouplingArraySteps1.
6808  *  \param [in] array - the C array to be used as raw data of \a this.
6809  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6810  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6811  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6812  *                     \c free(\c array ) will be called.
6813  *  \param [in] nbOfTuple - new number of tuples in \a this.
6814  *  \param [in] nbOfCompo - new number of components in \a this.
6815  */
6816 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6817 {
6818   _info_on_compo.resize(nbOfCompo);
6819   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6820   declareAsNew();
6821 }
6822
6823 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6824 {
6825   _info_on_compo.resize(nbOfCompo);
6826   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6827   declareAsNew();
6828 }
6829
6830 /*!
6831  * Returns a new DataArrayInt holding the same values as \a this array but differently
6832  * arranged in memory. If \a this array holds 2 components of 3 values:
6833  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6834  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6835  *  \warning Do not confuse this method with transpose()!
6836  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6837  *          is to delete using decrRef() as it is no more needed.
6838  *  \throw If \a this is not allocated.
6839  */
6840 DataArrayInt *DataArrayInt::fromNoInterlace() const
6841 {
6842   checkAllocated();
6843   if(_mem.isNull())
6844     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6845   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6846   DataArrayInt *ret=DataArrayInt::New();
6847   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6848   return ret;
6849 }
6850
6851 /*!
6852  * Returns a new DataArrayInt holding the same values as \a this array but differently
6853  * arranged in memory. If \a this array holds 2 components of 3 values:
6854  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6855  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6856  *  \warning Do not confuse this method with transpose()!
6857  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6858  *          is to delete using decrRef() as it is no more needed.
6859  *  \throw If \a this is not allocated.
6860  */
6861 DataArrayInt *DataArrayInt::toNoInterlace() const
6862 {
6863   checkAllocated();
6864   if(_mem.isNull())
6865     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6866   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6867   DataArrayInt *ret=DataArrayInt::New();
6868   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6869   return ret;
6870 }
6871
6872 /*!
6873  * Permutes values of \a this array as required by \a old2New array. The values are
6874  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6875  * the same as in \this one.
6876  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6877  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6878  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6879  *     giving a new position for i-th old value.
6880  */
6881 void DataArrayInt::renumberInPlace(const int *old2New)
6882 {
6883   checkAllocated();
6884   int nbTuples=getNumberOfTuples();
6885   int nbOfCompo=getNumberOfComponents();
6886   int *tmp=new int[nbTuples*nbOfCompo];
6887   const int *iptr=getConstPointer();
6888   for(int i=0;i<nbTuples;i++)
6889     {
6890       int v=old2New[i];
6891       if(v>=0 && v<nbTuples)
6892         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6893       else
6894         {
6895           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6896           throw INTERP_KERNEL::Exception(oss.str().c_str());
6897         }
6898     }
6899   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6900   delete [] tmp;
6901   declareAsNew();
6902 }
6903
6904 /*!
6905  * Permutes values of \a this array as required by \a new2Old array. The values are
6906  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6907  * the same as in \this one.
6908  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6909  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6910  *     giving a previous position of i-th new value.
6911  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6912  *          is to delete using decrRef() as it is no more needed.
6913  */
6914 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6915 {
6916   checkAllocated();
6917   int nbTuples=getNumberOfTuples();
6918   int nbOfCompo=getNumberOfComponents();
6919   int *tmp=new int[nbTuples*nbOfCompo];
6920   const int *iptr=getConstPointer();
6921   for(int i=0;i<nbTuples;i++)
6922     {
6923       int v=new2Old[i];
6924       if(v>=0 && v<nbTuples)
6925         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6926       else
6927         {
6928           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6929           throw INTERP_KERNEL::Exception(oss.str().c_str());
6930         }
6931     }
6932   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6933   delete [] tmp;
6934   declareAsNew();
6935 }
6936
6937 /*!
6938  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6939  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6940  * Number of tuples in the result array remains the same as in \this one.
6941  * If a permutation reduction is needed, renumberAndReduce() should be used.
6942  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6943  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6944  *          giving a new position for i-th old value.
6945  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6946  *          is to delete using decrRef() as it is no more needed.
6947  *  \throw If \a this is not allocated.
6948  */
6949 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6950 {
6951   checkAllocated();
6952   int nbTuples=getNumberOfTuples();
6953   int nbOfCompo=getNumberOfComponents();
6954   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6955   ret->alloc(nbTuples,nbOfCompo);
6956   ret->copyStringInfoFrom(*this);
6957   const int *iptr=getConstPointer();
6958   int *optr=ret->getPointer();
6959   for(int i=0;i<nbTuples;i++)
6960     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6961   ret->copyStringInfoFrom(*this);
6962   return ret.retn();
6963 }
6964
6965 /*!
6966  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6967  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6968  * tuples in the result array remains the same as in \this one.
6969  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6970  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6971  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6972  *     giving a previous position of i-th new value.
6973  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6974  *          is to delete using decrRef() as it is no more needed.
6975  */
6976 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6977 {
6978   checkAllocated();
6979   int nbTuples=getNumberOfTuples();
6980   int nbOfCompo=getNumberOfComponents();
6981   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6982   ret->alloc(nbTuples,nbOfCompo);
6983   ret->copyStringInfoFrom(*this);
6984   const int *iptr=getConstPointer();
6985   int *optr=ret->getPointer();
6986   for(int i=0;i<nbTuples;i++)
6987     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6988   ret->copyStringInfoFrom(*this);
6989   return ret.retn();
6990 }
6991
6992 /*!
6993  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6994  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6995  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6996  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6997  * \a old2New[ i ] is negative, is missing from the result array.
6998  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6999  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7000  *     giving a new position for i-th old tuple and giving negative position for
7001  *     for i-th old tuple that should be omitted.
7002  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7003  *          is to delete using decrRef() as it is no more needed.
7004  */
7005 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7006 {
7007   checkAllocated();
7008   int nbTuples=getNumberOfTuples();
7009   int nbOfCompo=getNumberOfComponents();
7010   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7011   ret->alloc(newNbOfTuple,nbOfCompo);
7012   const int *iptr=getConstPointer();
7013   int *optr=ret->getPointer();
7014   for(int i=0;i<nbTuples;i++)
7015     {
7016       int w=old2New[i];
7017       if(w>=0)
7018         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7019     }
7020   ret->copyStringInfoFrom(*this);
7021   return ret.retn();
7022 }
7023
7024 /*!
7025  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7026  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7027  * \a new2OldBg array.
7028  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7029  * This method is equivalent to renumberAndReduce() except that convention in input is
7030  * \c new2old and \b not \c old2new.
7031  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7032  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7033  *              tuple index in \a this array to fill the i-th tuple in the new array.
7034  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7035  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7036  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7037  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7038  *          is to delete using decrRef() as it is no more needed.
7039  */
7040 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7041 {
7042   checkAllocated();
7043   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7044   int nbComp=getNumberOfComponents();
7045   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7046   ret->copyStringInfoFrom(*this);
7047   int *pt=ret->getPointer();
7048   const int *srcPt=getConstPointer();
7049   int i=0;
7050   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7051     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7052   ret->copyStringInfoFrom(*this);
7053   return ret.retn();
7054 }
7055
7056 /*!
7057  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7058  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7059  * \a new2OldBg array.
7060  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7061  * This method is equivalent to renumberAndReduce() except that convention in input is
7062  * \c new2old and \b not \c old2new.
7063  * This method is equivalent to selectByTupleId() except that it prevents coping data
7064  * from behind the end of \a this array.
7065  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7066  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7067  *              tuple index in \a this array to fill the i-th tuple in the new array.
7068  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7069  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7070  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7071  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7072  *          is to delete using decrRef() as it is no more needed.
7073  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7074  */
7075 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7076 {
7077   checkAllocated();
7078   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7079   int nbComp=getNumberOfComponents();
7080   int oldNbOfTuples=getNumberOfTuples();
7081   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7082   ret->copyStringInfoFrom(*this);
7083   int *pt=ret->getPointer();
7084   const int *srcPt=getConstPointer();
7085   int i=0;
7086   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7087     if(*w>=0 && *w<oldNbOfTuples)
7088       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7089     else
7090       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7091   ret->copyStringInfoFrom(*this);
7092   return ret.retn();
7093 }
7094
7095 /*!
7096  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7097  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7098  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7099  * command \c range( \a bg, \a end2, \a step ).
7100  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7101  * not constructed explicitly.
7102  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7103  *  \param [in] bg - index of the first tuple to copy from \a this array.
7104  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7105  *  \param [in] step - index increment to get index of the next tuple to copy.
7106  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7107  *          is to delete using decrRef() as it is no more needed.
7108  *  \sa DataArrayInt::substr.
7109  */
7110 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7111 {
7112   checkAllocated();
7113   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7114   int nbComp=getNumberOfComponents();
7115   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7116   ret->alloc(newNbOfTuples,nbComp);
7117   int *pt=ret->getPointer();
7118   const int *srcPt=getConstPointer()+bg*nbComp;
7119   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7120     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7121   ret->copyStringInfoFrom(*this);
7122   return ret.retn();
7123 }
7124
7125 /*!
7126  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7127  * of tuples specified by \a ranges parameter.
7128  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7129  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7130  *              of tuples in [\c begin,\c end) format.
7131  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7132  *          is to delete using decrRef() as it is no more needed.
7133  *  \throw If \a end < \a begin.
7134  *  \throw If \a end > \a this->getNumberOfTuples().
7135  *  \throw If \a this is not allocated.
7136  */
7137 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7138 {
7139   checkAllocated();
7140   int nbOfComp=getNumberOfComponents();
7141   int nbOfTuplesThis=getNumberOfTuples();
7142   if(ranges.empty())
7143     {
7144       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7145       ret->alloc(0,nbOfComp);
7146       ret->copyStringInfoFrom(*this);
7147       return ret.retn();
7148     }
7149   int ref=ranges.front().first;
7150   int nbOfTuples=0;
7151   bool isIncreasing=true;
7152   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7153     {
7154       if((*it).first<=(*it).second)
7155         {
7156           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7157             {
7158               nbOfTuples+=(*it).second-(*it).first;
7159               if(isIncreasing)
7160                 isIncreasing=ref<=(*it).first;
7161               ref=(*it).second;
7162             }
7163           else
7164             {
7165               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7166               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7167               throw INTERP_KERNEL::Exception(oss.str().c_str());
7168             }
7169         }
7170       else
7171         {
7172           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7173           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7174           throw INTERP_KERNEL::Exception(oss.str().c_str());
7175         }
7176     }
7177   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7178     return deepCpy();
7179   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7180   ret->alloc(nbOfTuples,nbOfComp);
7181   ret->copyStringInfoFrom(*this);
7182   const int *src=getConstPointer();
7183   int *work=ret->getPointer();
7184   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7185     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7186   return ret.retn();
7187 }
7188
7189 /*!
7190  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7191  * This map, if applied to \a this array, would make it sorted. For example, if
7192  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7193  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7194  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7195  * This method is useful for renumbering (in MED file for example). For more info
7196  * on renumbering see \ref MEDCouplingArrayRenumbering.
7197  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7198  *          array using decrRef() as it is no more needed.
7199  *  \throw If \a this is not allocated.
7200  *  \throw If \a this->getNumberOfComponents() != 1.
7201  *  \throw If there are equal values in \a this array.
7202  */
7203 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7204 {
7205   checkAllocated();
7206   if(getNumberOfComponents()!=1)
7207     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7208   int nbTuples=getNumberOfTuples();
7209   const int *pt=getConstPointer();
7210   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7211   DataArrayInt *ret=DataArrayInt::New();
7212   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7213   return ret;
7214 }
7215
7216 /*!
7217  * 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
7218  * input array \a ids2.
7219  * \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.
7220  * 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
7221  * inversely.
7222  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7223  *
7224  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7225  *          array using decrRef() as it is no more needed.
7226  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7227  * 
7228  */
7229 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7230 {
7231   if(!ids1 || !ids2)
7232     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7233   if(!ids1->isAllocated() || !ids2->isAllocated())
7234     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7235   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7236     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7237   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7238     {
7239       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 !";
7240       throw INTERP_KERNEL::Exception(oss.str().c_str());
7241     }
7242   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7243   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7244   p1->sort(true); p2->sort(true);
7245   if(!p1->isEqualWithoutConsideringStr(*p2))
7246     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7247   p1=ids1->checkAndPreparePermutation();
7248   p2=ids2->checkAndPreparePermutation();
7249   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7250   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7251   return p2.retn();
7252 }
7253
7254 /*!
7255  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7256  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7257  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7258  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7259  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7260  * The first of out arrays returns indices of elements of \a this array, grouped by their
7261  * place in the set \a B. The second out array is the index of the first one; it shows how
7262  * many elements of \a A are mapped into each element of \a B. <br>
7263  * For more info on
7264  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7265  * \b Example:
7266  * - \a this: [0,3,2,3,2,2,1,2]
7267  * - \a targetNb: 4
7268  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7269  * - \a arrI: [0,1,2,6,8]
7270  *
7271  * This result means: <br>
7272  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7273  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7274  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7275  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7276  * \a arrI[ 2+1 ]]); <br> etc.
7277  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7278  *         than the maximal value of \a A.
7279  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7280  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7281  *         this array using decrRef() as it is no more needed.
7282  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7283  *         elements of \a this. The caller is to delete this array using decrRef() as it
7284  *         is no more needed.
7285  *  \throw If \a this is not allocated.
7286  *  \throw If \a this->getNumberOfComponents() != 1.
7287  *  \throw If any value in \a this is more or equal to \a targetNb.
7288  */
7289 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7290 {
7291   checkAllocated();
7292   if(getNumberOfComponents()!=1)
7293     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7294   int nbOfTuples=getNumberOfTuples();
7295   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7296   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7297   retI->alloc(targetNb+1,1);
7298   const int *input=getConstPointer();
7299   std::vector< std::vector<int> > tmp(targetNb);
7300   for(int i=0;i<nbOfTuples;i++)
7301     {
7302       int tmp2=input[i];
7303       if(tmp2>=0 && tmp2<targetNb)
7304         tmp[tmp2].push_back(i);
7305       else
7306         {
7307           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7308           throw INTERP_KERNEL::Exception(oss.str().c_str());
7309         }
7310     }
7311   int *retIPtr=retI->getPointer();
7312   *retIPtr=0;
7313   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7314     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7315   if(nbOfTuples!=retI->getIJ(targetNb,0))
7316     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7317   ret->alloc(nbOfTuples,1);
7318   int *retPtr=ret->getPointer();
7319   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7320     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7321   arr=ret.retn();
7322   arrI=retI.retn();
7323 }
7324
7325
7326 /*!
7327  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7328  * from a zip representation of a surjective format (returned e.g. by
7329  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7330  * for example). The result array minimizes the permutation. <br>
7331  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7332  * \b Example: <br>
7333  * - \a nbOfOldTuples: 10 
7334  * - \a arr          : [0,3, 5,7,9]
7335  * - \a arrIBg       : [0,2,5]
7336  * - \a newNbOfTuples: 7
7337  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7338  *
7339  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7340  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7341  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7342  *         (indices of) equal values. Its every element (except the last one) points to
7343  *         the first element of a group of equal values.
7344  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7345  *          arrIBg is \a arrIEnd[ -1 ].
7346  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7347  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7348  *          array using decrRef() as it is no more needed.
7349  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7350  */
7351 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7352 {
7353   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7354   ret->alloc(nbOfOldTuples,1);
7355   int *pt=ret->getPointer();
7356   std::fill(pt,pt+nbOfOldTuples,-1);
7357   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7358   const int *cIPtr=arrIBg;
7359   for(int i=0;i<nbOfGrps;i++)
7360     pt[arr[cIPtr[i]]]=-(i+2);
7361   int newNb=0;
7362   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7363     {
7364       if(pt[iNode]<0)
7365         {
7366           if(pt[iNode]==-1)
7367             pt[iNode]=newNb++;
7368           else
7369             {
7370               int grpId=-(pt[iNode]+2);
7371               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7372                 {
7373                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7374                     pt[arr[j]]=newNb;
7375                   else
7376                     {
7377                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7378                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7379                     }
7380                 }
7381               newNb++;
7382             }
7383         }
7384     }
7385   newNbOfTuples=newNb;
7386   return ret.retn();
7387 }
7388
7389 /*!
7390  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7391  * which if applied to \a this array would make it sorted ascendingly.
7392  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7393  * \b Example: <br>
7394  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7395  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7396  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7397  *
7398  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7399  *          array using decrRef() as it is no more needed.
7400  *  \throw If \a this is not allocated.
7401  *  \throw If \a this->getNumberOfComponents() != 1.
7402  */
7403 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7404 {
7405   checkAllocated();
7406   if(getNumberOfComponents()!=1)
7407     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7408   int nbOfTuples=getNumberOfTuples();
7409   const int *pt=getConstPointer();
7410   std::map<int,int> m;
7411   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7412   ret->alloc(nbOfTuples,1);
7413   int *opt=ret->getPointer();
7414   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7415     {
7416       int val=*pt;
7417       std::map<int,int>::iterator it=m.find(val);
7418       if(it!=m.end())
7419         {
7420           *opt=(*it).second;
7421           (*it).second++;
7422         }
7423       else
7424         {
7425           *opt=0;
7426           m.insert(std::pair<int,int>(val,1));
7427         }
7428     }
7429   int sum=0;
7430   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7431     {
7432       int vt=(*it).second;
7433       (*it).second=sum;
7434       sum+=vt;
7435     }
7436   pt=getConstPointer();
7437   opt=ret->getPointer();
7438   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7439     *opt+=m[*pt];
7440   //
7441   return ret.retn();
7442 }
7443
7444 /*!
7445  * Checks if contents of \a this array are equal to that of an array filled with
7446  * iota(). This method is particularly useful for DataArrayInt instances that represent
7447  * a renumbering array to check the real need in renumbering. 
7448  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7449  *  \throw If \a this is not allocated.
7450  *  \throw If \a this->getNumberOfComponents() != 1.
7451  */
7452 bool DataArrayInt::isIdentity() const
7453 {
7454   checkAllocated();
7455   if(getNumberOfComponents()!=1)
7456     return false;
7457   int nbOfTuples=getNumberOfTuples();
7458   const int *pt=getConstPointer();
7459   for(int i=0;i<nbOfTuples;i++,pt++)
7460     if(*pt!=i)
7461       return false;
7462   return true;
7463 }
7464
7465 /*!
7466  * Checks if all values in \a this array are equal to \a val.
7467  *  \param [in] val - value to check equality of array values to.
7468  *  \return bool - \a true if all values are \a val.
7469  *  \throw If \a this is not allocated.
7470  *  \throw If \a this->getNumberOfComponents() != 1
7471  */
7472 bool DataArrayInt::isUniform(int val) const
7473 {
7474   checkAllocated();
7475   if(getNumberOfComponents()!=1)
7476     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7477   int nbOfTuples=getNumberOfTuples();
7478   const int *w=getConstPointer();
7479   const int *end2=w+nbOfTuples;
7480   for(;w!=end2;w++)
7481     if(*w!=val)
7482       return false;
7483   return true;
7484 }
7485
7486 /*!
7487  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7488  * array to the new one.
7489  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7490  */
7491 DataArrayDouble *DataArrayInt::convertToDblArr() const
7492 {
7493   checkAllocated();
7494   DataArrayDouble *ret=DataArrayDouble::New();
7495   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7496   std::size_t nbOfVals=getNbOfElems();
7497   const int *src=getConstPointer();
7498   double *dest=ret->getPointer();
7499   std::copy(src,src+nbOfVals,dest);
7500   ret->copyStringInfoFrom(*this);
7501   return ret;
7502 }
7503
7504 /*!
7505  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7506  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7507  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7508  * This method is a specialization of selectByTupleId2().
7509  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7510  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7511  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7512  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7513  *          is to delete using decrRef() as it is no more needed.
7514  *  \throw If \a tupleIdBg < 0.
7515  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7516     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7517  *  \sa DataArrayInt::selectByTupleId2
7518  */
7519 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7520 {
7521   checkAllocated();
7522   int nbt=getNumberOfTuples();
7523   if(tupleIdBg<0)
7524     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7525   if(tupleIdBg>nbt)
7526     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7527   int trueEnd=tupleIdEnd;
7528   if(tupleIdEnd!=-1)
7529     {
7530       if(tupleIdEnd>nbt)
7531         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7532     }
7533   else
7534     trueEnd=nbt;
7535   int nbComp=getNumberOfComponents();
7536   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7537   ret->alloc(trueEnd-tupleIdBg,nbComp);
7538   ret->copyStringInfoFrom(*this);
7539   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7540   return ret.retn();
7541 }
7542
7543 /*!
7544  * Changes the number of components within \a this array so that its raw data **does
7545  * not** change, instead splitting this data into tuples changes.
7546  *  \warning This method erases all (name and unit) component info set before!
7547  *  \param [in] newNbOfComp - number of components for \a this array to have.
7548  *  \throw If \a this is not allocated
7549  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7550  *  \throw If \a newNbOfCompo is lower than 1.
7551  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7552  *  \warning This method erases all (name and unit) component info set before!
7553  */
7554 void DataArrayInt::rearrange(int newNbOfCompo)
7555 {
7556   checkAllocated();
7557   if(newNbOfCompo<1)
7558     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7559   std::size_t nbOfElems=getNbOfElems();
7560   if(nbOfElems%newNbOfCompo!=0)
7561     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7562   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7563     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7564   _info_on_compo.clear();
7565   _info_on_compo.resize(newNbOfCompo);
7566   declareAsNew();
7567 }
7568
7569 /*!
7570  * Changes the number of components within \a this array to be equal to its number
7571  * of tuples, and inversely its number of tuples to become equal to its number of 
7572  * components. So that its raw data **does not** change, instead splitting this
7573  * data into tuples changes.
7574  *  \warning This method erases all (name and unit) component info set before!
7575  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7576  *  \throw If \a this is not allocated.
7577  *  \sa rearrange()
7578  */
7579 void DataArrayInt::transpose()
7580 {
7581   checkAllocated();
7582   int nbOfTuples=getNumberOfTuples();
7583   rearrange(nbOfTuples);
7584 }
7585
7586 /*!
7587  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7588  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7589  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7590  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7591  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7592  * components.  
7593  *  \param [in] newNbOfComp - number of components for the new array to have.
7594  *  \param [in] dftValue - value assigned to new values added to the new array.
7595  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7596  *          is to delete using decrRef() as it is no more needed.
7597  *  \throw If \a this is not allocated.
7598  */
7599 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7600 {
7601   checkAllocated();
7602   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7603   ret->alloc(getNumberOfTuples(),newNbOfComp);
7604   const int *oldc=getConstPointer();
7605   int *nc=ret->getPointer();
7606   int nbOfTuples=getNumberOfTuples();
7607   int oldNbOfComp=getNumberOfComponents();
7608   int dim=std::min(oldNbOfComp,newNbOfComp);
7609   for(int i=0;i<nbOfTuples;i++)
7610     {
7611       int j=0;
7612       for(;j<dim;j++)
7613         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7614       for(;j<newNbOfComp;j++)
7615         nc[newNbOfComp*i+j]=dftValue;
7616     }
7617   ret->setName(getName());
7618   for(int i=0;i<dim;i++)
7619     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7620   ret->setName(getName());
7621   return ret.retn();
7622 }
7623
7624 /*!
7625  * Changes number of tuples in the array. If the new number of tuples is smaller
7626  * than the current number the array is truncated, otherwise the array is extended.
7627  *  \param [in] nbOfTuples - new number of tuples. 
7628  *  \throw If \a this is not allocated.
7629  *  \throw If \a nbOfTuples is negative.
7630  */
7631 void DataArrayInt::reAlloc(int nbOfTuples)
7632 {
7633   if(nbOfTuples<0)
7634     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7635   checkAllocated();
7636   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7637   declareAsNew();
7638 }
7639
7640
7641 /*!
7642  * Returns a copy of \a this array composed of selected components.
7643  * The new DataArrayInt has the same number of tuples but includes components
7644  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7645  * can be either less, same or more than \a this->getNbOfElems().
7646  *  \param [in] compoIds - sequence of zero based indices of components to include
7647  *              into the new array.
7648  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7649  *          is to delete using decrRef() as it is no more needed.
7650  *  \throw If \a this is not allocated.
7651  *  \throw If a component index (\a i) is not valid: 
7652  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7653  *
7654  *  \if ENABLE_EXAMPLES
7655  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7656  *  \endif
7657  */
7658 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7659 {
7660   checkAllocated();
7661   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7662   int newNbOfCompo=(int)compoIds.size();
7663   int oldNbOfCompo=getNumberOfComponents();
7664   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7665     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7666   int nbOfTuples=getNumberOfTuples();
7667   ret->alloc(nbOfTuples,newNbOfCompo);
7668   ret->copyPartOfStringInfoFrom(*this,compoIds);
7669   const int *oldc=getConstPointer();
7670   int *nc=ret->getPointer();
7671   for(int i=0;i<nbOfTuples;i++)
7672     for(int j=0;j<newNbOfCompo;j++,nc++)
7673       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7674   return ret.retn();
7675 }
7676
7677 /*!
7678  * Appends components of another array to components of \a this one, tuple by tuple.
7679  * So that the number of tuples of \a this array remains the same and the number of 
7680  * components increases.
7681  *  \param [in] other - the DataArrayInt to append to \a this one.
7682  *  \throw If \a this is not allocated.
7683  *  \throw If \a this and \a other arrays have different number of tuples.
7684  *
7685  *  \if ENABLE_EXAMPLES
7686  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7687  *
7688  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7689  *  \endif
7690  */
7691 void DataArrayInt::meldWith(const DataArrayInt *other)
7692 {
7693   if(!other)
7694     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7695   checkAllocated();
7696   other->checkAllocated();
7697   int nbOfTuples=getNumberOfTuples();
7698   if(nbOfTuples!=other->getNumberOfTuples())
7699     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7700   int nbOfComp1=getNumberOfComponents();
7701   int nbOfComp2=other->getNumberOfComponents();
7702   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7703   int *w=newArr;
7704   const int *inp1=getConstPointer();
7705   const int *inp2=other->getConstPointer();
7706   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7707     {
7708       w=std::copy(inp1,inp1+nbOfComp1,w);
7709       w=std::copy(inp2,inp2+nbOfComp2,w);
7710     }
7711   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7712   std::vector<int> compIds(nbOfComp2);
7713   for(int i=0;i<nbOfComp2;i++)
7714     compIds[i]=nbOfComp1+i;
7715   copyPartOfStringInfoFrom2(compIds,*other);
7716 }
7717
7718 /*!
7719  * Copy all components in a specified order from another DataArrayInt.
7720  * The specified components become the first ones in \a this array.
7721  * Both numerical and textual data is copied. The number of tuples in \a this and
7722  * the other array can be different.
7723  *  \param [in] a - the array to copy data from.
7724  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7725  *              to be copied.
7726  *  \throw If \a a is NULL.
7727  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7728  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7729  *
7730  *  \if ENABLE_EXAMPLES
7731  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7732  *  \endif
7733  */
7734 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7735 {
7736   if(!a)
7737     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7738   checkAllocated();
7739   a->checkAllocated();
7740   copyPartOfStringInfoFrom2(compoIds,*a);
7741   std::size_t partOfCompoSz=compoIds.size();
7742   int nbOfCompo=getNumberOfComponents();
7743   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7744   const int *ac=a->getConstPointer();
7745   int *nc=getPointer();
7746   for(int i=0;i<nbOfTuples;i++)
7747     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7748       nc[nbOfCompo*i+compoIds[j]]=*ac;
7749 }
7750
7751 /*!
7752  * Copy all values from another DataArrayInt into specified tuples and components
7753  * of \a this array. Textual data is not copied.
7754  * The tree parameters defining set of indices of tuples and components are similar to
7755  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7756  *  \param [in] a - the array to copy values from.
7757  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7758  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7759  *              are located.
7760  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7761  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7762  *  \param [in] endComp - index of the component before which the components to assign
7763  *              to are located.
7764  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7765  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7766  *              must be equal to the number of columns to assign to, else an
7767  *              exception is thrown; if \a false, then it is only required that \a
7768  *              a->getNbOfElems() equals to number of values to assign to (this condition
7769  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7770  *              values to assign to is given by following Python expression:
7771  *              \a nbTargetValues = 
7772  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7773  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7774  *  \throw If \a a is NULL.
7775  *  \throw If \a a is not allocated.
7776  *  \throw If \a this is not allocated.
7777  *  \throw If parameters specifying tuples and components to assign to do not give a
7778  *            non-empty range of increasing indices.
7779  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7780  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7781  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7782  *
7783  *  \if ENABLE_EXAMPLES
7784  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7785  *  \endif
7786  */
7787 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7788 {
7789   if(!a)
7790     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7791   const char msg[]="DataArrayInt::setPartOfValues1";
7792   checkAllocated();
7793   a->checkAllocated();
7794   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7795   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7796   int nbComp=getNumberOfComponents();
7797   int nbOfTuples=getNumberOfTuples();
7798   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7799   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7800   bool assignTech=true;
7801   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7802     {
7803       if(strictCompoCompare)
7804         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7805     }
7806   else
7807     {
7808       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7809       assignTech=false;
7810     }
7811   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7812   const int *srcPt=a->getConstPointer();
7813   if(assignTech)
7814     {
7815       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7816         for(int j=0;j<newNbOfComp;j++,srcPt++)
7817           pt[j*stepComp]=*srcPt;
7818     }
7819   else
7820     {
7821       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7822         {
7823           const int *srcPt2=srcPt;
7824           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7825             pt[j*stepComp]=*srcPt2;
7826         }
7827     }
7828 }
7829
7830 /*!
7831  * Assign a given value to values at specified tuples and components of \a this array.
7832  * The tree parameters defining set of indices of tuples and components are similar to
7833  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7834  *  \param [in] a - the value to assign.
7835  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7836  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7837  *              are located.
7838  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7839  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7840  *  \param [in] endComp - index of the component before which the components to assign
7841  *              to are located.
7842  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7843  *  \throw If \a this is not allocated.
7844  *  \throw If parameters specifying tuples and components to assign to, do not give a
7845  *            non-empty range of increasing indices or indices are out of a valid range
7846  *            for \this array.
7847  *
7848  *  \if ENABLE_EXAMPLES
7849  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7850  *  \endif
7851  */
7852 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7853 {
7854   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7855   checkAllocated();
7856   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7857   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7858   int nbComp=getNumberOfComponents();
7859   int nbOfTuples=getNumberOfTuples();
7860   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7861   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7862   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7863   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7864     for(int j=0;j<newNbOfComp;j++)
7865       pt[j*stepComp]=a;
7866 }
7867
7868
7869 /*!
7870  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7871  * components of \a this array. Textual data is not copied.
7872  * The tuples and components to assign to are defined by C arrays of indices.
7873  * There are two *modes of usage*:
7874  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7875  *   of \a a is assigned to its own location within \a this array. 
7876  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7877  *   components of every specified tuple of \a this array. In this mode it is required
7878  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7879  * 
7880  *  \param [in] a - the array to copy values from.
7881  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7882  *              assign values of \a a to.
7883  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7884  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7885  *              \a bgTuples <= \a pi < \a endTuples.
7886  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7887  *              assign values of \a a to.
7888  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7889  *              pointer to a component index <em>(pi)</em> varies as this: 
7890  *              \a bgComp <= \a pi < \a endComp.
7891  *  \param [in] strictCompoCompare - this parameter is checked only if the
7892  *               *mode of usage* is the first; if it is \a true (default), 
7893  *               then \a a->getNumberOfComponents() must be equal 
7894  *               to the number of specified columns, else this is not required.
7895  *  \throw If \a a is NULL.
7896  *  \throw If \a a is not allocated.
7897  *  \throw If \a this is not allocated.
7898  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7899  *         out of a valid range for \a this array.
7900  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7901  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7902  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7903  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7904  *
7905  *  \if ENABLE_EXAMPLES
7906  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7907  *  \endif
7908  */
7909 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7910 {
7911   if(!a)
7912     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7913   const char msg[]="DataArrayInt::setPartOfValues2";
7914   checkAllocated();
7915   a->checkAllocated();
7916   int nbComp=getNumberOfComponents();
7917   int nbOfTuples=getNumberOfTuples();
7918   for(const int *z=bgComp;z!=endComp;z++)
7919     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7920   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7921   int newNbOfComp=(int)std::distance(bgComp,endComp);
7922   bool assignTech=true;
7923   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7924     {
7925       if(strictCompoCompare)
7926         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7927     }
7928   else
7929     {
7930       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7931       assignTech=false;
7932     }
7933   int *pt=getPointer();
7934   const int *srcPt=a->getConstPointer();
7935   if(assignTech)
7936     {    
7937       for(const int *w=bgTuples;w!=endTuples;w++)
7938         {
7939           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7940           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7941             {    
7942               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7943             }
7944         }
7945     }
7946   else
7947     {
7948       for(const int *w=bgTuples;w!=endTuples;w++)
7949         {
7950           const int *srcPt2=srcPt;
7951           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7952           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7953             {    
7954               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7955             }
7956         }
7957     }
7958 }
7959
7960 /*!
7961  * Assign a given value to values at specified tuples and components of \a this array.
7962  * The tuples and components to assign to are defined by C arrays of indices.
7963  *  \param [in] a - the value to assign.
7964  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7965  *              assign \a a to.
7966  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7967  *              pointer to a tuple index (\a pi) varies as this: 
7968  *              \a bgTuples <= \a pi < \a endTuples.
7969  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7970  *              assign \a a to.
7971  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7972  *              pointer to a component index (\a pi) varies as this: 
7973  *              \a bgComp <= \a pi < \a endComp.
7974  *  \throw If \a this is not allocated.
7975  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7976  *         out of a valid range for \a this array.
7977  *
7978  *  \if ENABLE_EXAMPLES
7979  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7980  *  \endif
7981  */
7982 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7983 {
7984   checkAllocated();
7985   int nbComp=getNumberOfComponents();
7986   int nbOfTuples=getNumberOfTuples();
7987   for(const int *z=bgComp;z!=endComp;z++)
7988     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7989   int *pt=getPointer();
7990   for(const int *w=bgTuples;w!=endTuples;w++)
7991     for(const int *z=bgComp;z!=endComp;z++)
7992       {
7993         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7994         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7995       }
7996 }
7997
7998 /*!
7999  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8000  * components of \a this array. Textual data is not copied.
8001  * The tuples to assign to are defined by a C array of indices.
8002  * The components to assign to are defined by three values similar to parameters of
8003  * the Python function \c range(\c start,\c stop,\c step).
8004  * There are two *modes of usage*:
8005  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8006  *   of \a a is assigned to its own location within \a this array. 
8007  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8008  *   components of every specified tuple of \a this array. In this mode it is required
8009  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8010  *
8011  *  \param [in] a - the array to copy values from.
8012  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8013  *              assign values of \a a to.
8014  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8015  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8016  *              \a bgTuples <= \a pi < \a endTuples.
8017  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8018  *  \param [in] endComp - index of the component before which the components to assign
8019  *              to are located.
8020  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8021  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8022  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8023  *               then \a a->getNumberOfComponents() must be equal 
8024  *               to the number of specified columns, else this is not required.
8025  *  \throw If \a a is NULL.
8026  *  \throw If \a a is not allocated.
8027  *  \throw If \a this is not allocated.
8028  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8029  *         \a this array.
8030  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8031  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8032  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8033  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8034  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8035  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8036  *  \throw If parameters specifying components to assign to, do not give a
8037  *            non-empty range of increasing indices or indices are out of a valid range
8038  *            for \this array.
8039  *
8040  *  \if ENABLE_EXAMPLES
8041  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8042  *  \endif
8043  */
8044 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8045 {
8046   if(!a)
8047     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8048   const char msg[]="DataArrayInt::setPartOfValues3";
8049   checkAllocated();
8050   a->checkAllocated();
8051   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8052   int nbComp=getNumberOfComponents();
8053   int nbOfTuples=getNumberOfTuples();
8054   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8055   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8056   bool assignTech=true;
8057   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8058     {
8059       if(strictCompoCompare)
8060         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8061     }
8062   else
8063     {
8064       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8065       assignTech=false;
8066     }
8067   int *pt=getPointer()+bgComp;
8068   const int *srcPt=a->getConstPointer();
8069   if(assignTech)
8070     {
8071       for(const int *w=bgTuples;w!=endTuples;w++)
8072         for(int j=0;j<newNbOfComp;j++,srcPt++)
8073           {
8074             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8075             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8076           }
8077     }
8078   else
8079     {
8080       for(const int *w=bgTuples;w!=endTuples;w++)
8081         {
8082           const int *srcPt2=srcPt;
8083           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8084             {
8085               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8086               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8087             }
8088         }
8089     }
8090 }
8091
8092 /*!
8093  * Assign a given value to values at specified tuples and components of \a this array.
8094  * The tuples to assign to are defined by a C array of indices.
8095  * The components to assign to are defined by three values similar to parameters of
8096  * the Python function \c range(\c start,\c stop,\c step).
8097  *  \param [in] a - the value to assign.
8098  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8099  *              assign \a a to.
8100  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8101  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8102  *              \a bgTuples <= \a pi < \a endTuples.
8103  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8104  *  \param [in] endComp - index of the component before which the components to assign
8105  *              to are located.
8106  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8107  *  \throw If \a this is not allocated.
8108  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8109  *         \a this array.
8110  *  \throw If parameters specifying components to assign to, do not give a
8111  *            non-empty range of increasing indices or indices are out of a valid range
8112  *            for \this array.
8113  *
8114  *  \if ENABLE_EXAMPLES
8115  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8116  *  \endif
8117  */
8118 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8119 {
8120   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8121   checkAllocated();
8122   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8123   int nbComp=getNumberOfComponents();
8124   int nbOfTuples=getNumberOfTuples();
8125   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8126   int *pt=getPointer()+bgComp;
8127   for(const int *w=bgTuples;w!=endTuples;w++)
8128     for(int j=0;j<newNbOfComp;j++)
8129       {
8130         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8131         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8132       }
8133 }
8134
8135 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8136 {
8137   if(!a)
8138     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8139   const char msg[]="DataArrayInt::setPartOfValues4";
8140   checkAllocated();
8141   a->checkAllocated();
8142   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8143   int newNbOfComp=(int)std::distance(bgComp,endComp);
8144   int nbComp=getNumberOfComponents();
8145   for(const int *z=bgComp;z!=endComp;z++)
8146     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8147   int nbOfTuples=getNumberOfTuples();
8148   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8149   bool assignTech=true;
8150   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8151     {
8152       if(strictCompoCompare)
8153         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8154     }
8155   else
8156     {
8157       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8158       assignTech=false;
8159     }
8160   const int *srcPt=a->getConstPointer();
8161   int *pt=getPointer()+bgTuples*nbComp;
8162   if(assignTech)
8163     {
8164       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8165         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8166           pt[*z]=*srcPt;
8167     }
8168   else
8169     {
8170       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8171         {
8172           const int *srcPt2=srcPt;
8173           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8174             pt[*z]=*srcPt2;
8175         }
8176     }
8177 }
8178
8179 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8180 {
8181   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8182   checkAllocated();
8183   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8184   int nbComp=getNumberOfComponents();
8185   for(const int *z=bgComp;z!=endComp;z++)
8186     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8187   int nbOfTuples=getNumberOfTuples();
8188   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8189   int *pt=getPointer()+bgTuples*nbComp;
8190   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8191     for(const int *z=bgComp;z!=endComp;z++)
8192       pt[*z]=a;
8193 }
8194
8195 /*!
8196  * Copy some tuples from another DataArrayInt into specified tuples
8197  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8198  * components.
8199  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8200  * All components of selected tuples are copied.
8201  *  \param [in] a - the array to copy values from.
8202  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8203  *              target tuples of \a this. \a tuplesSelec has two components, and the
8204  *              first component specifies index of the source tuple and the second
8205  *              one specifies index of the target tuple.
8206  *  \throw If \a this is not allocated.
8207  *  \throw If \a a is NULL.
8208  *  \throw If \a a is not allocated.
8209  *  \throw If \a tuplesSelec is NULL.
8210  *  \throw If \a tuplesSelec is not allocated.
8211  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8212  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8213  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8214  *         the corresponding (\a this or \a a) array.
8215  */
8216 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8217 {
8218   if(!a || !tuplesSelec)
8219     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8220   checkAllocated();
8221   a->checkAllocated();
8222   tuplesSelec->checkAllocated();
8223   int nbOfComp=getNumberOfComponents();
8224   if(nbOfComp!=a->getNumberOfComponents())
8225     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8226   if(tuplesSelec->getNumberOfComponents()!=2)
8227     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8228   int thisNt=getNumberOfTuples();
8229   int aNt=a->getNumberOfTuples();
8230   int *valsToSet=getPointer();
8231   const int *valsSrc=a->getConstPointer();
8232   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8233     {
8234       if(tuple[1]>=0 && tuple[1]<aNt)
8235         {
8236           if(tuple[0]>=0 && tuple[0]<thisNt)
8237             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8238           else
8239             {
8240               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8241               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8242               throw INTERP_KERNEL::Exception(oss.str().c_str());
8243             }
8244         }
8245       else
8246         {
8247           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8248           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8249           throw INTERP_KERNEL::Exception(oss.str().c_str());
8250         }
8251     }
8252 }
8253
8254 /*!
8255  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8256  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8257  * components.
8258  * The tuples to assign to are defined by index of the first tuple, and
8259  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8260  * The tuples to copy are defined by values of a DataArrayInt.
8261  * All components of selected tuples are copied.
8262  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8263  *              values to.
8264  *  \param [in] aBase - the array to copy values from.
8265  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8266  *  \throw If \a this is not allocated.
8267  *  \throw If \a aBase is NULL.
8268  *  \throw If \a aBase is not allocated.
8269  *  \throw If \a tuplesSelec is NULL.
8270  *  \throw If \a tuplesSelec is not allocated.
8271  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8272  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8273  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8274  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8275  *         \a aBase array.
8276  */
8277 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8278 {
8279   if(!aBase || !tuplesSelec)
8280     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8281   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8282   if(!a)
8283     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8284   checkAllocated();
8285   a->checkAllocated();
8286   tuplesSelec->checkAllocated();
8287   int nbOfComp=getNumberOfComponents();
8288   if(nbOfComp!=a->getNumberOfComponents())
8289     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8290   if(tuplesSelec->getNumberOfComponents()!=1)
8291     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8292   int thisNt=getNumberOfTuples();
8293   int aNt=a->getNumberOfTuples();
8294   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8295   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8296   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8297     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8298   const int *valsSrc=a->getConstPointer();
8299   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8300     {
8301       if(*tuple>=0 && *tuple<aNt)
8302         {
8303           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8304         }
8305       else
8306         {
8307           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8308           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8309           throw INTERP_KERNEL::Exception(oss.str().c_str());
8310         }
8311     }
8312 }
8313
8314 /*!
8315  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8316  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8317  * components.
8318  * The tuples to copy are defined by three values similar to parameters of
8319  * the Python function \c range(\c start,\c stop,\c step).
8320  * The tuples to assign to are defined by index of the first tuple, and
8321  * their number is defined by number of tuples to copy.
8322  * All components of selected tuples are copied.
8323  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8324  *              values to.
8325  *  \param [in] aBase - the array to copy values from.
8326  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8327  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8328  *              are located.
8329  *  \param [in] step - index increment to get index of the next tuple to copy.
8330  *  \throw If \a this is not allocated.
8331  *  \throw If \a aBase is NULL.
8332  *  \throw If \a aBase is not allocated.
8333  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8334  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8335  *  \throw If parameters specifying tuples to copy, do not give a
8336  *            non-empty range of increasing indices or indices are out of a valid range
8337  *            for the array \a aBase.
8338  */
8339 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8340 {
8341   if(!aBase)
8342     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8343   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8344   if(!a)
8345     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8346   checkAllocated();
8347   a->checkAllocated();
8348   int nbOfComp=getNumberOfComponents();
8349   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8350   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8351   if(nbOfComp!=a->getNumberOfComponents())
8352     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8353   int thisNt=getNumberOfTuples();
8354   int aNt=a->getNumberOfTuples();
8355   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8356   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8357     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8358   if(end2>aNt)
8359     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8360   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8361   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8362     {
8363       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8364     }
8365 }
8366
8367 /*!
8368  * Returns a value located at specified tuple and component.
8369  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8370  * parameters is checked. So this method is safe but expensive if used to go through
8371  * all values of \a this.
8372  *  \param [in] tupleId - index of tuple of interest.
8373  *  \param [in] compoId - index of component of interest.
8374  *  \return double - value located by \a tupleId and \a compoId.
8375  *  \throw If \a this is not allocated.
8376  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8377  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8378  */
8379 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8380 {
8381   checkAllocated();
8382   if(tupleId<0 || tupleId>=getNumberOfTuples())
8383     {
8384       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8385       throw INTERP_KERNEL::Exception(oss.str().c_str());
8386     }
8387   if(compoId<0 || compoId>=getNumberOfComponents())
8388     {
8389       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8390       throw INTERP_KERNEL::Exception(oss.str().c_str());
8391     }
8392   return _mem[tupleId*_info_on_compo.size()+compoId];
8393 }
8394
8395 /*!
8396  * Returns the first value of \a this. 
8397  *  \return int - the last value of \a this array.
8398  *  \throw If \a this is not allocated.
8399  *  \throw If \a this->getNumberOfComponents() != 1.
8400  *  \throw If \a this->getNumberOfTuples() < 1.
8401  */
8402 int DataArrayInt::front() const
8403 {
8404   checkAllocated();
8405   if(getNumberOfComponents()!=1)
8406     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8407   int nbOfTuples=getNumberOfTuples();
8408   if(nbOfTuples<1)
8409     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8410   return *(getConstPointer());
8411 }
8412
8413 /*!
8414  * Returns the last value of \a this. 
8415  *  \return int - the last value of \a this array.
8416  *  \throw If \a this is not allocated.
8417  *  \throw If \a this->getNumberOfComponents() != 1.
8418  *  \throw If \a this->getNumberOfTuples() < 1.
8419  */
8420 int DataArrayInt::back() const
8421 {
8422   checkAllocated();
8423   if(getNumberOfComponents()!=1)
8424     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8425   int nbOfTuples=getNumberOfTuples();
8426   if(nbOfTuples<1)
8427     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8428   return *(getConstPointer()+nbOfTuples-1);
8429 }
8430
8431 /*!
8432  * Assign pointer to one array to a pointer to another appay. Reference counter of
8433  * \a arrayToSet is incremented / decremented.
8434  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8435  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8436  */
8437 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8438 {
8439   if(newArray!=arrayToSet)
8440     {
8441       if(arrayToSet)
8442         arrayToSet->decrRef();
8443       arrayToSet=newArray;
8444       if(arrayToSet)
8445         arrayToSet->incrRef();
8446     }
8447 }
8448
8449 DataArrayIntIterator *DataArrayInt::iterator()
8450 {
8451   return new DataArrayIntIterator(this);
8452 }
8453
8454 /*!
8455  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8456  * given one.
8457  *  \param [in] val - the value to find within \a this.
8458  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8459  *          array using decrRef() as it is no more needed.
8460  *  \throw If \a this is not allocated.
8461  *  \throw If \a this->getNumberOfComponents() != 1.
8462  *  \sa DataArrayInt::getIdsEqualTuple
8463  */
8464 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8465 {
8466   checkAllocated();
8467   if(getNumberOfComponents()!=1)
8468     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8469   const int *cptr(getConstPointer());
8470   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8471   int nbOfTuples=getNumberOfTuples();
8472   for(int i=0;i<nbOfTuples;i++,cptr++)
8473     if(*cptr==val)
8474       ret->pushBackSilent(i);
8475   return ret.retn();
8476 }
8477
8478 /*!
8479  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8480  * equal to a given one. 
8481  *  \param [in] val - the value to ignore within \a this.
8482  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8483  *          array using decrRef() as it is no more needed.
8484  *  \throw If \a this is not allocated.
8485  *  \throw If \a this->getNumberOfComponents() != 1.
8486  */
8487 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8488 {
8489   checkAllocated();
8490   if(getNumberOfComponents()!=1)
8491     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8492   const int *cptr(getConstPointer());
8493   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8494   int nbOfTuples=getNumberOfTuples();
8495   for(int i=0;i<nbOfTuples;i++,cptr++)
8496     if(*cptr!=val)
8497       ret->pushBackSilent(i);
8498   return ret.retn();
8499 }
8500
8501 /*!
8502  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8503  * This method is an extension of  DataArrayInt::getIdsEqual method.
8504  *
8505  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8506  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8507  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8508  *          array using decrRef() as it is no more needed.
8509  *  \throw If \a this is not allocated.
8510  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8511  * \throw If \a this->getNumberOfComponents() is equal to 0.
8512  * \sa DataArrayInt::getIdsEqual
8513  */
8514 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8515 {
8516   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8517   checkAllocated();
8518   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8519     {
8520       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8521       throw INTERP_KERNEL::Exception(oss.str().c_str());
8522     }
8523   if(nbOfCompoExp==0)
8524     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8525   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8526   const int *bg(begin()),*end2(end()),*work(begin());
8527   while(work!=end2)
8528     {
8529       work=std::search(work,end2,tupleBg,tupleEnd);
8530       if(work!=end2)
8531         {
8532           std::size_t pos(std::distance(bg,work));
8533           if(pos%nbOfCompoExp==0)
8534             ret->pushBackSilent(pos/nbOfCompoExp);
8535           work++;
8536         }
8537     }
8538   return ret.retn();
8539 }
8540
8541 /*!
8542  * Assigns \a newValue to all elements holding \a oldValue within \a this
8543  * one-dimensional array.
8544  *  \param [in] oldValue - the value to replace.
8545  *  \param [in] newValue - the value to assign.
8546  *  \return int - number of replacements performed.
8547  *  \throw If \a this is not allocated.
8548  *  \throw If \a this->getNumberOfComponents() != 1.
8549  */
8550 int DataArrayInt::changeValue(int oldValue, int newValue)
8551 {
8552   checkAllocated();
8553   if(getNumberOfComponents()!=1)
8554     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8555   int *start=getPointer();
8556   int *end2=start+getNbOfElems();
8557   int ret=0;
8558   for(int *val=start;val!=end2;val++)
8559     {
8560       if(*val==oldValue)
8561         {
8562           *val=newValue;
8563           ret++;
8564         }
8565     }
8566   return ret;
8567 }
8568
8569 /*!
8570  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8571  * one of given values.
8572  *  \param [in] valsBg - an array of values to find within \a this array.
8573  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8574  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8575  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8576  *          array using decrRef() as it is no more needed.
8577  *  \throw If \a this->getNumberOfComponents() != 1.
8578  */
8579 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8580 {
8581   if(getNumberOfComponents()!=1)
8582     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8583   std::set<int> vals2(valsBg,valsEnd);
8584   const int *cptr=getConstPointer();
8585   std::vector<int> res;
8586   int nbOfTuples=getNumberOfTuples();
8587   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8588   for(int i=0;i<nbOfTuples;i++,cptr++)
8589     if(vals2.find(*cptr)!=vals2.end())
8590       ret->pushBackSilent(i);
8591   return ret.retn();
8592 }
8593
8594 /*!
8595  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8596  * equal to any of given values.
8597  *  \param [in] valsBg - an array of values to ignore within \a this array.
8598  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8599  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8600  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8601  *          array using decrRef() as it is no more needed.
8602  *  \throw If \a this->getNumberOfComponents() != 1.
8603  */
8604 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8605 {
8606   if(getNumberOfComponents()!=1)
8607     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8608   std::set<int> vals2(valsBg,valsEnd);
8609   const int *cptr=getConstPointer();
8610   std::vector<int> res;
8611   int nbOfTuples=getNumberOfTuples();
8612   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8613   for(int i=0;i<nbOfTuples;i++,cptr++)
8614     if(vals2.find(*cptr)==vals2.end())
8615       ret->pushBackSilent(i);
8616   return ret.retn();
8617 }
8618
8619 /*!
8620  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8621  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8622  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8623  * If any the tuple id is returned. If not -1 is returned.
8624  * 
8625  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8626  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8627  *
8628  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8629  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8630  */
8631 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8632 {
8633   checkAllocated();
8634   int nbOfCompo=getNumberOfComponents();
8635   if(nbOfCompo==0)
8636     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8637   if(nbOfCompo!=(int)tupl.size())
8638     {
8639       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8640       throw INTERP_KERNEL::Exception(oss.str().c_str());
8641     }
8642   const int *cptr=getConstPointer();
8643   std::size_t nbOfVals=getNbOfElems();
8644   for(const int *work=cptr;work!=cptr+nbOfVals;)
8645     {
8646       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8647       if(work!=cptr+nbOfVals)
8648         {
8649           if(std::distance(cptr,work)%nbOfCompo!=0)
8650             work++;
8651           else
8652             return std::distance(cptr,work)/nbOfCompo;
8653         }
8654     }
8655   return -1;
8656 }
8657
8658 /*!
8659  * This method searches the sequence specified in input parameter \b vals in \b this.
8660  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8661  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8662  * \sa DataArrayInt::locateTuple
8663  */
8664 int DataArrayInt::search(const std::vector<int>& vals) const
8665 {
8666   checkAllocated();
8667   int nbOfCompo=getNumberOfComponents();
8668   if(nbOfCompo!=1)
8669     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8670   const int *cptr=getConstPointer();
8671   std::size_t nbOfVals=getNbOfElems();
8672   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8673   if(loc!=cptr+nbOfVals)
8674     return std::distance(cptr,loc);
8675   return -1;
8676 }
8677
8678 /*!
8679  * This method expects to be called when number of components of this is equal to one.
8680  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8681  * If not any tuple contains \b value -1 is returned.
8682  * \sa DataArrayInt::presenceOfValue
8683  */
8684 int DataArrayInt::locateValue(int value) const
8685 {
8686   checkAllocated();
8687   if(getNumberOfComponents()!=1)
8688     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8689   const int *cptr=getConstPointer();
8690   int nbOfTuples=getNumberOfTuples();
8691   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8692   if(ret!=cptr+nbOfTuples)
8693     return std::distance(cptr,ret);
8694   return -1;
8695 }
8696
8697 /*!
8698  * This method expects to be called when number of components of this is equal to one.
8699  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8700  * If not any tuple contains one of the values contained in 'vals' false is returned.
8701  * \sa DataArrayInt::presenceOfValue
8702  */
8703 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8704 {
8705   checkAllocated();
8706   if(getNumberOfComponents()!=1)
8707     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8708   std::set<int> vals2(vals.begin(),vals.end());
8709   const int *cptr=getConstPointer();
8710   int nbOfTuples=getNumberOfTuples();
8711   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8712     if(vals2.find(*w)!=vals2.end())
8713       return std::distance(cptr,w);
8714   return -1;
8715 }
8716
8717 /*!
8718  * This method returns the number of values in \a this that are equals to input parameter \a value.
8719  * This method only works for single component array.
8720  *
8721  * \return a value in [ 0, \c this->getNumberOfTuples() )
8722  *
8723  * \throw If \a this is not allocated
8724  *
8725  */
8726 int DataArrayInt::count(int value) const
8727 {
8728   int ret=0;
8729   checkAllocated();
8730   if(getNumberOfComponents()!=1)
8731     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8732   const int *vals=begin();
8733   int nbOfTuples=getNumberOfTuples();
8734   for(int i=0;i<nbOfTuples;i++,vals++)
8735     if(*vals==value)
8736       ret++;
8737   return ret;
8738 }
8739
8740 /*!
8741  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8742  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8743  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8744  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8745  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8746  * \sa DataArrayInt::locateTuple
8747  */
8748 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8749 {
8750   return locateTuple(tupl)!=-1;
8751 }
8752
8753
8754 /*!
8755  * Returns \a true if a given value is present within \a this one-dimensional array.
8756  *  \param [in] value - the value to find within \a this array.
8757  *  \return bool - \a true in case if \a value is present within \a this array.
8758  *  \throw If \a this is not allocated.
8759  *  \throw If \a this->getNumberOfComponents() != 1.
8760  *  \sa locateValue()
8761  */
8762 bool DataArrayInt::presenceOfValue(int value) const
8763 {
8764   return locateValue(value)!=-1;
8765 }
8766
8767 /*!
8768  * This method expects to be called when number of components of this is equal to one.
8769  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8770  * If not any tuple contains one of the values contained in 'vals' false is returned.
8771  * \sa DataArrayInt::locateValue
8772  */
8773 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8774 {
8775   return locateValue(vals)!=-1;
8776 }
8777
8778 /*!
8779  * Accumulates values of each component of \a this array.
8780  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8781  *         by the caller, that is filled by this method with sum value for each
8782  *         component.
8783  *  \throw If \a this is not allocated.
8784  */
8785 void DataArrayInt::accumulate(int *res) const
8786 {
8787   checkAllocated();
8788   const int *ptr=getConstPointer();
8789   int nbTuple=getNumberOfTuples();
8790   int nbComps=getNumberOfComponents();
8791   std::fill(res,res+nbComps,0);
8792   for(int i=0;i<nbTuple;i++)
8793     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8794 }
8795
8796 int DataArrayInt::accumulate(int compId) const
8797 {
8798   checkAllocated();
8799   const int *ptr=getConstPointer();
8800   int nbTuple=getNumberOfTuples();
8801   int nbComps=getNumberOfComponents();
8802   if(compId<0 || compId>=nbComps)
8803     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8804   int ret=0;
8805   for(int i=0;i<nbTuple;i++)
8806     ret+=ptr[i*nbComps+compId];
8807   return ret;
8808 }
8809
8810 /*!
8811  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8812  * The returned array will have same number of components than \a this and number of tuples equal to
8813  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8814  *
8815  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8816  *
8817  * \param [in] bgOfIndex - begin (included) of the input index array.
8818  * \param [in] endOfIndex - end (excluded) of the input index array.
8819  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8820  * 
8821  * \throw If bgOfIndex or end is NULL.
8822  * \throw If input index array is not ascendingly sorted.
8823  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8824  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8825  */
8826 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8827 {
8828   if(!bgOfIndex || !endOfIndex)
8829     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8830   checkAllocated();
8831   int nbCompo=getNumberOfComponents();
8832   int nbOfTuples=getNumberOfTuples();
8833   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8834   if(sz<1)
8835     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8836   sz--;
8837   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8838   const int *w=bgOfIndex;
8839   if(*w<0 || *w>=nbOfTuples)
8840     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8841   const int *srcPt=begin()+(*w)*nbCompo;
8842   int *tmp=ret->getPointer();
8843   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8844     {
8845       std::fill(tmp,tmp+nbCompo,0);
8846       if(w[1]>=w[0])
8847         {
8848           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8849             {
8850               if(j>=0 && j<nbOfTuples)
8851                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8852               else
8853                 {
8854                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8855                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8856                 }
8857             }
8858         }
8859       else
8860         {
8861           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8862           throw INTERP_KERNEL::Exception(oss.str().c_str());
8863         }
8864     }
8865   ret->copyStringInfoFrom(*this);
8866   return ret.retn();
8867 }
8868
8869 /*!
8870  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8871  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8872  * offsetA2</em> and (2)
8873  * the number of component in the result array is same as that of each of given arrays.
8874  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8875  * Info on components is copied from the first of the given arrays. Number of components
8876  * in the given arrays must be the same.
8877  *  \param [in] a1 - an array to include in the result array.
8878  *  \param [in] a2 - another array to include in the result array.
8879  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8880  *  \return DataArrayInt * - the new instance of DataArrayInt.
8881  *          The caller is to delete this result array using decrRef() as it is no more
8882  *          needed.
8883  *  \throw If either \a a1 or \a a2 is NULL.
8884  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8885  */
8886 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8887 {
8888   if(!a1 || !a2)
8889     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8890   int nbOfComp=a1->getNumberOfComponents();
8891   if(nbOfComp!=a2->getNumberOfComponents())
8892     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8893   int nbOfTuple1=a1->getNumberOfTuples();
8894   int nbOfTuple2=a2->getNumberOfTuples();
8895   DataArrayInt *ret=DataArrayInt::New();
8896   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8897   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8898   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8899   ret->copyStringInfoFrom(*a1);
8900   return ret;
8901 }
8902
8903 /*!
8904  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8905  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8906  * the number of component in the result array is same as that of each of given arrays.
8907  * Info on components is copied from the first of the given arrays. Number of components
8908  * in the given arrays must be  the same.
8909  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
8910  * not the object itself.
8911  *  \param [in] arr - a sequence of arrays to include in the result array.
8912  *  \return DataArrayInt * - the new instance of DataArrayInt.
8913  *          The caller is to delete this result array using decrRef() as it is no more
8914  *          needed.
8915  *  \throw If all arrays within \a arr are NULL.
8916  *  \throw If getNumberOfComponents() of arrays within \a arr.
8917  */
8918 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8919 {
8920   std::vector<const DataArrayInt *> a;
8921   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8922     if(*it4)
8923       a.push_back(*it4);
8924   if(a.empty())
8925     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8926   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8927   int nbOfComp=(*it)->getNumberOfComponents();
8928   int nbt=(*it++)->getNumberOfTuples();
8929   for(int i=1;it!=a.end();it++,i++)
8930     {
8931       if((*it)->getNumberOfComponents()!=nbOfComp)
8932         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8933       nbt+=(*it)->getNumberOfTuples();
8934     }
8935   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8936   ret->alloc(nbt,nbOfComp);
8937   int *pt=ret->getPointer();
8938   for(it=a.begin();it!=a.end();it++)
8939     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8940   ret->copyStringInfoFrom(*(a[0]));
8941   return ret.retn();
8942 }
8943
8944 /*!
8945  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8946  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8947  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8948  * 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.
8949  * 
8950  * \return DataArrayInt * - a new object to be managed by the caller.
8951  */
8952 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8953 {
8954   int retSz=1;
8955   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8956     {
8957       if(*it4)
8958         {
8959           (*it4)->checkAllocated();
8960           if((*it4)->getNumberOfComponents()!=1)
8961             {
8962               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8963               throw INTERP_KERNEL::Exception(oss.str().c_str());
8964             }
8965           int nbTupl=(*it4)->getNumberOfTuples();
8966           if(nbTupl<1)
8967             {
8968               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8969               throw INTERP_KERNEL::Exception(oss.str().c_str());
8970             }
8971           if((*it4)->front()!=0)
8972             {
8973               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8974               throw INTERP_KERNEL::Exception(oss.str().c_str());
8975             }
8976           retSz+=nbTupl-1;
8977         }
8978       else
8979         {
8980           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8981           throw INTERP_KERNEL::Exception(oss.str().c_str());
8982         }
8983     }
8984   if(arrs.empty())
8985     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8986   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8987   ret->alloc(retSz,1);
8988   int *pt=ret->getPointer(); *pt++=0;
8989   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8990     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8991   ret->copyStringInfoFrom(*(arrs[0]));
8992   return ret.retn();
8993 }
8994
8995 /*!
8996  * Returns the maximal value and its location within \a this one-dimensional array.
8997  *  \param [out] tupleId - index of the tuple holding the maximal value.
8998  *  \return int - the maximal value among all values of \a this array.
8999  *  \throw If \a this->getNumberOfComponents() != 1
9000  *  \throw If \a this->getNumberOfTuples() < 1
9001  */
9002 int DataArrayInt::getMaxValue(int& tupleId) const
9003 {
9004   checkAllocated();
9005   if(getNumberOfComponents()!=1)
9006     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9007   int nbOfTuples=getNumberOfTuples();
9008   if(nbOfTuples<=0)
9009     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9010   const int *vals=getConstPointer();
9011   const int *loc=std::max_element(vals,vals+nbOfTuples);
9012   tupleId=(int)std::distance(vals,loc);
9013   return *loc;
9014 }
9015
9016 /*!
9017  * Returns the maximal value within \a this array that is allowed to have more than
9018  *  one component.
9019  *  \return int - the maximal value among all values of \a this array.
9020  *  \throw If \a this is not allocated.
9021  */
9022 int DataArrayInt::getMaxValueInArray() const
9023 {
9024   checkAllocated();
9025   const int *loc=std::max_element(begin(),end());
9026   return *loc;
9027 }
9028
9029 /*!
9030  * Returns the minimal value and its location within \a this one-dimensional array.
9031  *  \param [out] tupleId - index of the tuple holding the minimal value.
9032  *  \return int - the minimal value among all values of \a this array.
9033  *  \throw If \a this->getNumberOfComponents() != 1
9034  *  \throw If \a this->getNumberOfTuples() < 1
9035  */
9036 int DataArrayInt::getMinValue(int& tupleId) const
9037 {
9038   checkAllocated();
9039   if(getNumberOfComponents()!=1)
9040     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9041   int nbOfTuples=getNumberOfTuples();
9042   if(nbOfTuples<=0)
9043     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9044   const int *vals=getConstPointer();
9045   const int *loc=std::min_element(vals,vals+nbOfTuples);
9046   tupleId=(int)std::distance(vals,loc);
9047   return *loc;
9048 }
9049
9050 /*!
9051  * Returns the minimal value within \a this array that is allowed to have more than
9052  *  one component.
9053  *  \return int - the minimal value among all values of \a this array.
9054  *  \throw If \a this is not allocated.
9055  */
9056 int DataArrayInt::getMinValueInArray() const
9057 {
9058   checkAllocated();
9059   const int *loc=std::min_element(begin(),end());
9060   return *loc;
9061 }
9062
9063 /*!
9064  * Converts every value of \a this array to its absolute value.
9065  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9066  * should be called instead.
9067  *
9068  * \throw If \a this is not allocated.
9069  * \sa DataArrayInt::computeAbs
9070  */
9071 void DataArrayInt::abs()
9072 {
9073   checkAllocated();
9074   int *ptr(getPointer());
9075   std::size_t nbOfElems(getNbOfElems());
9076   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9077   declareAsNew();
9078 }
9079
9080 /*!
9081  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9082  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9083  *
9084  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9085  *         same number of tuples and component as \a this array.
9086  *         The caller is to delete this result array using decrRef() as it is no more
9087  *         needed.
9088  * \throw If \a this is not allocated.
9089  * \sa DataArrayInt::abs
9090  */
9091 DataArrayInt *DataArrayInt::computeAbs() const
9092 {
9093   checkAllocated();
9094   DataArrayInt *newArr(DataArrayInt::New());
9095   int nbOfTuples(getNumberOfTuples());
9096   int nbOfComp(getNumberOfComponents());
9097   newArr->alloc(nbOfTuples,nbOfComp);
9098   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9099   newArr->copyStringInfoFrom(*this);
9100   return newArr;
9101 }
9102
9103 /*!
9104  * Apply a liner function to a given component of \a this array, so that
9105  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9106  *  \param [in] a - the first coefficient of the function.
9107  *  \param [in] b - the second coefficient of the function.
9108  *  \param [in] compoId - the index of component to modify.
9109  *  \throw If \a this is not allocated.
9110  */
9111 void DataArrayInt::applyLin(int a, int b, int compoId)
9112 {
9113   checkAllocated();
9114   int *ptr=getPointer()+compoId;
9115   int nbOfComp=getNumberOfComponents();
9116   int nbOfTuple=getNumberOfTuples();
9117   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9118     *ptr=a*(*ptr)+b;
9119   declareAsNew();
9120 }
9121
9122 /*!
9123  * Apply a liner function to all elements of \a this array, so that
9124  * an element _x_ becomes \f$ a * x + b \f$.
9125  *  \param [in] a - the first coefficient of the function.
9126  *  \param [in] b - the second coefficient of the function.
9127  *  \throw If \a this is not allocated.
9128  */
9129 void DataArrayInt::applyLin(int a, int b)
9130 {
9131   checkAllocated();
9132   int *ptr=getPointer();
9133   std::size_t nbOfElems=getNbOfElems();
9134   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9135     *ptr=a*(*ptr)+b;
9136   declareAsNew();
9137 }
9138
9139 /*!
9140  * Returns a full copy of \a this array except that sign of all elements is reversed.
9141  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9142  *          same number of tuples and component as \a this array.
9143  *          The caller is to delete this result array using decrRef() as it is no more
9144  *          needed.
9145  *  \throw If \a this is not allocated.
9146  */
9147 DataArrayInt *DataArrayInt::negate() const
9148 {
9149   checkAllocated();
9150   DataArrayInt *newArr=DataArrayInt::New();
9151   int nbOfTuples=getNumberOfTuples();
9152   int nbOfComp=getNumberOfComponents();
9153   newArr->alloc(nbOfTuples,nbOfComp);
9154   const int *cptr=getConstPointer();
9155   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9156   newArr->copyStringInfoFrom(*this);
9157   return newArr;
9158 }
9159
9160 /*!
9161  * Modify all elements of \a this array, so that
9162  * an element _x_ becomes \f$ numerator / x \f$.
9163  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9164  *           array, all elements processed before detection of the zero element remain
9165  *           modified.
9166  *  \param [in] numerator - the numerator used to modify array elements.
9167  *  \throw If \a this is not allocated.
9168  *  \throw If there is an element equal to 0 in \a this array.
9169  */
9170 void DataArrayInt::applyInv(int numerator)
9171 {
9172   checkAllocated();
9173   int *ptr=getPointer();
9174   std::size_t nbOfElems=getNbOfElems();
9175   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9176     {
9177       if(*ptr!=0)
9178         {
9179           *ptr=numerator/(*ptr);
9180         }
9181       else
9182         {
9183           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9184           oss << " !";
9185           throw INTERP_KERNEL::Exception(oss.str().c_str());
9186         }
9187     }
9188   declareAsNew();
9189 }
9190
9191 /*!
9192  * Modify all elements of \a this array, so that
9193  * an element _x_ becomes \f$ x / val \f$.
9194  *  \param [in] val - the denominator used to modify array elements.
9195  *  \throw If \a this is not allocated.
9196  *  \throw If \a val == 0.
9197  */
9198 void DataArrayInt::applyDivideBy(int val)
9199 {
9200   if(val==0)
9201     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9202   checkAllocated();
9203   int *ptr=getPointer();
9204   std::size_t nbOfElems=getNbOfElems();
9205   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9206   declareAsNew();
9207 }
9208
9209 /*!
9210  * Modify all elements of \a this array, so that
9211  * an element _x_ becomes  <em> x % val </em>.
9212  *  \param [in] val - the divisor used to modify array elements.
9213  *  \throw If \a this is not allocated.
9214  *  \throw If \a val <= 0.
9215  */
9216 void DataArrayInt::applyModulus(int val)
9217 {
9218   if(val<=0)
9219     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9220   checkAllocated();
9221   int *ptr=getPointer();
9222   std::size_t nbOfElems=getNbOfElems();
9223   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9224   declareAsNew();
9225 }
9226
9227 /*!
9228  * This method works only on data array with one component.
9229  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9230  * this[*id] in [\b vmin,\b vmax)
9231  * 
9232  * \param [in] vmin begin of range. This value is included in range (included).
9233  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9234  * \return a newly allocated data array that the caller should deal with.
9235  *
9236  * \sa DataArrayInt::getIdsNotInRange
9237  */
9238 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9239 {
9240   checkAllocated();
9241   if(getNumberOfComponents()!=1)
9242     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9243   const int *cptr(begin());
9244   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9245   int nbOfTuples(getNumberOfTuples());
9246   for(int i=0;i<nbOfTuples;i++,cptr++)
9247     if(*cptr>=vmin && *cptr<vmax)
9248       ret->pushBackSilent(i);
9249   return ret.retn();
9250 }
9251
9252 /*!
9253  * This method works only on data array with one component.
9254  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9255  * this[*id] \b not in [\b vmin,\b vmax)
9256  * 
9257  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9258  * \param [in] vmax end of range. This value is included in range (included).
9259  * \return a newly allocated data array that the caller should deal with.
9260  * 
9261  * \sa DataArrayInt::getIdsInRange
9262  */
9263 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9264 {
9265   checkAllocated();
9266   if(getNumberOfComponents()!=1)
9267     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9268   const int *cptr(getConstPointer());
9269   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9270   int nbOfTuples(getNumberOfTuples());
9271   for(int i=0;i<nbOfTuples;i++,cptr++)
9272     if(*cptr<vmin || *cptr>=vmax)
9273       ret->pushBackSilent(i);
9274   return ret.retn();
9275 }
9276
9277 /*!
9278  * This method works only on data array with one component.
9279  * 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.
9280  * 
9281  * \param [in] vmin begin of range. This value is included in range (included).
9282  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9283  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9284 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9285 {
9286   checkAllocated();
9287   if(getNumberOfComponents()!=1)
9288     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9289   int nbOfTuples=getNumberOfTuples();
9290   bool ret=true;
9291   const int *cptr=getConstPointer();
9292   for(int i=0;i<nbOfTuples;i++,cptr++)
9293     {
9294       if(*cptr>=vmin && *cptr<vmax)
9295         { ret=ret && *cptr==i; }
9296       else
9297         {
9298           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9299           throw INTERP_KERNEL::Exception(oss.str().c_str());
9300         }
9301     }
9302   return ret;
9303 }
9304
9305 /*!
9306  * Modify all elements of \a this array, so that
9307  * an element _x_ becomes <em> val % x </em>.
9308  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9309  *           array, all elements processed before detection of the zero element remain
9310  *           modified.
9311  *  \param [in] val - the divident used to modify array elements.
9312  *  \throw If \a this is not allocated.
9313  *  \throw If there is an element equal to or less than 0 in \a this array.
9314  */
9315 void DataArrayInt::applyRModulus(int val)
9316 {
9317   checkAllocated();
9318   int *ptr=getPointer();
9319   std::size_t nbOfElems=getNbOfElems();
9320   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9321     {
9322       if(*ptr>0)
9323         {
9324           *ptr=val%(*ptr);
9325         }
9326       else
9327         {
9328           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9329           oss << " !";
9330           throw INTERP_KERNEL::Exception(oss.str().c_str());
9331         }
9332     }
9333   declareAsNew();
9334 }
9335
9336 /*!
9337  * Modify all elements of \a this array, so that
9338  * an element _x_ becomes <em> val ^ x </em>.
9339  *  \param [in] val - the value used to apply pow on all array elements.
9340  *  \throw If \a this is not allocated.
9341  *  \throw If \a val < 0.
9342  */
9343 void DataArrayInt::applyPow(int val)
9344 {
9345   checkAllocated();
9346   if(val<0)
9347     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9348   int *ptr=getPointer();
9349   std::size_t nbOfElems=getNbOfElems();
9350   if(val==0)
9351     {
9352       std::fill(ptr,ptr+nbOfElems,1);
9353       return ;
9354     }
9355   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9356     {
9357       int tmp=1;
9358       for(int j=0;j<val;j++)
9359         tmp*=*ptr;
9360       *ptr=tmp;
9361     }
9362   declareAsNew();
9363 }
9364
9365 /*!
9366  * Modify all elements of \a this array, so that
9367  * an element _x_ becomes \f$ val ^ x \f$.
9368  *  \param [in] val - the value used to apply pow on all array elements.
9369  *  \throw If \a this is not allocated.
9370  *  \throw If there is an element < 0 in \a this array.
9371  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9372  *           array, all elements processed before detection of the zero element remain
9373  *           modified.
9374  */
9375 void DataArrayInt::applyRPow(int val)
9376 {
9377   checkAllocated();
9378   int *ptr=getPointer();
9379   std::size_t nbOfElems=getNbOfElems();
9380   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9381     {
9382       if(*ptr>=0)
9383         {
9384           int tmp=1;
9385           for(int j=0;j<*ptr;j++)
9386             tmp*=val;
9387           *ptr=tmp;
9388         }
9389       else
9390         {
9391           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9392           oss << " !";
9393           throw INTERP_KERNEL::Exception(oss.str().c_str());
9394         }
9395     }
9396   declareAsNew();
9397 }
9398
9399 /*!
9400  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9401  * of components in the result array is a sum of the number of components of given arrays
9402  * and (2) the number of tuples in the result array is same as that of each of given
9403  * arrays. In other words the i-th tuple of result array includes all components of
9404  * i-th tuples of all given arrays.
9405  * Number of tuples in the given arrays must be the same.
9406  *  \param [in] a1 - an array to include in the result array.
9407  *  \param [in] a2 - another array to include in the result array.
9408  *  \return DataArrayInt * - the new instance of DataArrayInt.
9409  *          The caller is to delete this result array using decrRef() as it is no more
9410  *          needed.
9411  *  \throw If both \a a1 and \a a2 are NULL.
9412  *  \throw If any given array is not allocated.
9413  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9414  */
9415 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9416 {
9417   std::vector<const DataArrayInt *> arr(2);
9418   arr[0]=a1; arr[1]=a2;
9419   return Meld(arr);
9420 }
9421
9422 /*!
9423  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9424  * of components in the result array is a sum of the number of components of given arrays
9425  * and (2) the number of tuples in the result array is same as that of each of given
9426  * arrays. In other words the i-th tuple of result array includes all components of
9427  * i-th tuples of all given arrays.
9428  * Number of tuples in the given arrays must be  the same.
9429  *  \param [in] arr - a sequence of arrays to include in the result array.
9430  *  \return DataArrayInt * - the new instance of DataArrayInt.
9431  *          The caller is to delete this result array using decrRef() as it is no more
9432  *          needed.
9433  *  \throw If all arrays within \a arr are NULL.
9434  *  \throw If any given array is not allocated.
9435  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9436  */
9437 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9438 {
9439   std::vector<const DataArrayInt *> a;
9440   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9441     if(*it4)
9442       a.push_back(*it4);
9443   if(a.empty())
9444     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9445   std::vector<const DataArrayInt *>::const_iterator it;
9446   for(it=a.begin();it!=a.end();it++)
9447     (*it)->checkAllocated();
9448   it=a.begin();
9449   int nbOfTuples=(*it)->getNumberOfTuples();
9450   std::vector<int> nbc(a.size());
9451   std::vector<const int *> pts(a.size());
9452   nbc[0]=(*it)->getNumberOfComponents();
9453   pts[0]=(*it++)->getConstPointer();
9454   for(int i=1;it!=a.end();it++,i++)
9455     {
9456       if(nbOfTuples!=(*it)->getNumberOfTuples())
9457         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9458       nbc[i]=(*it)->getNumberOfComponents();
9459       pts[i]=(*it)->getConstPointer();
9460     }
9461   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9462   DataArrayInt *ret=DataArrayInt::New();
9463   ret->alloc(nbOfTuples,totalNbOfComp);
9464   int *retPtr=ret->getPointer();
9465   for(int i=0;i<nbOfTuples;i++)
9466     for(int j=0;j<(int)a.size();j++)
9467       {
9468         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9469         pts[j]+=nbc[j];
9470       }
9471   int k=0;
9472   for(int i=0;i<(int)a.size();i++)
9473     for(int j=0;j<nbc[i];j++,k++)
9474       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9475   return ret;
9476 }
9477
9478 /*!
9479  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9480  * The i-th item of the result array is an ID of a set of elements belonging to a
9481  * unique set of groups, which the i-th element is a part of. This set of elements
9482  * belonging to a unique set of groups is called \a family, so the result array contains
9483  * IDs of families each element belongs to.
9484  *
9485  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9486  * then there are 3 families:
9487  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9488  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9489  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9490  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9491  * stands for the element #3 which is in none of groups.
9492  *
9493  *  \param [in] groups - sequence of groups of element IDs.
9494  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9495  *         in \a groups.
9496  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9497  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9498  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9499  *         delete this array using decrRef() as it is no more needed.
9500  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9501  */
9502 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9503 {
9504   std::vector<const DataArrayInt *> groups2;
9505   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9506     if(*it4)
9507       groups2.push_back(*it4);
9508   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9509   ret->alloc(newNb,1);
9510   int *retPtr=ret->getPointer();
9511   std::fill(retPtr,retPtr+newNb,0);
9512   int fid=1;
9513   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9514     {
9515       const int *ptr=(*iter)->getConstPointer();
9516       std::size_t nbOfElem=(*iter)->getNbOfElems();
9517       int sfid=fid;
9518       for(int j=0;j<sfid;j++)
9519         {
9520           bool found=false;
9521           for(std::size_t i=0;i<nbOfElem;i++)
9522             {
9523               if(ptr[i]>=0 && ptr[i]<newNb)
9524                 {
9525                   if(retPtr[ptr[i]]==j)
9526                     {
9527                       retPtr[ptr[i]]=fid;
9528                       found=true;
9529                     }
9530                 }
9531               else
9532                 {
9533                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9534                   oss << ") !";
9535                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9536                 }
9537             }
9538           if(found)
9539             fid++;
9540         }
9541     }
9542   fidsOfGroups.clear();
9543   fidsOfGroups.resize(groups2.size());
9544   int grId=0;
9545   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9546     {
9547       std::set<int> tmp;
9548       const int *ptr=(*iter)->getConstPointer();
9549       std::size_t nbOfElem=(*iter)->getNbOfElems();
9550       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9551         tmp.insert(retPtr[*p]);
9552       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9553     }
9554   return ret.retn();
9555 }
9556
9557 /*!
9558  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9559  * arrays. The result array does not contain any duplicates and its values
9560  * are sorted in ascending order.
9561  *  \param [in] arr - sequence of DataArrayInt's to unite.
9562  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9563  *         array using decrRef() as it is no more needed.
9564  *  \throw If any \a arr[i] is not allocated.
9565  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9566  */
9567 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9568 {
9569   std::vector<const DataArrayInt *> a;
9570   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9571     if(*it4)
9572       a.push_back(*it4);
9573   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9574     {
9575       (*it)->checkAllocated();
9576       if((*it)->getNumberOfComponents()!=1)
9577         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9578     }
9579   //
9580   std::set<int> r;
9581   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9582     {
9583       const int *pt=(*it)->getConstPointer();
9584       int nbOfTuples=(*it)->getNumberOfTuples();
9585       r.insert(pt,pt+nbOfTuples);
9586     }
9587   DataArrayInt *ret=DataArrayInt::New();
9588   ret->alloc((int)r.size(),1);
9589   std::copy(r.begin(),r.end(),ret->getPointer());
9590   return ret;
9591 }
9592
9593 /*!
9594  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9595  * arrays. The result array does not contain any duplicates and its values
9596  * are sorted in ascending order.
9597  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9598  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9599  *         array using decrRef() as it is no more needed.
9600  *  \throw If any \a arr[i] is not allocated.
9601  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9602  */
9603 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9604 {
9605   std::vector<const DataArrayInt *> a;
9606   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9607     if(*it4)
9608       a.push_back(*it4);
9609   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9610     {
9611       (*it)->checkAllocated();
9612       if((*it)->getNumberOfComponents()!=1)
9613         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9614     }
9615   //
9616   std::set<int> r;
9617   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9618     {
9619       const int *pt=(*it)->getConstPointer();
9620       int nbOfTuples=(*it)->getNumberOfTuples();
9621       std::set<int> s1(pt,pt+nbOfTuples);
9622       if(it!=a.begin())
9623         {
9624           std::set<int> r2;
9625           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9626           r=r2;
9627         }
9628       else
9629         r=s1;
9630     }
9631   DataArrayInt *ret(DataArrayInt::New());
9632   ret->alloc((int)r.size(),1);
9633   std::copy(r.begin(),r.end(),ret->getPointer());
9634   return ret;
9635 }
9636
9637 /// @cond INTERNAL
9638 namespace ParaMEDMEMImpl
9639 {
9640   class OpSwitchedOn
9641   {
9642   public:
9643     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9644     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9645   private:
9646     int *_pt;
9647     int _cnt;
9648   };
9649
9650   class OpSwitchedOff
9651   {
9652   public:
9653     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9654     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9655   private:
9656     int *_pt;
9657     int _cnt;
9658   };
9659 }
9660 /// @endcond
9661
9662 /*!
9663  * This method returns the list of ids in ascending mode so that v[id]==true.
9664  */
9665 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9666 {
9667   int sz((int)std::count(v.begin(),v.end(),true));
9668   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9669   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
9670   return ret.retn();
9671 }
9672
9673 /*!
9674  * This method returns the list of ids in ascending mode so that v[id]==false.
9675  */
9676 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9677 {
9678   int sz((int)std::count(v.begin(),v.end(),false));
9679   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9680   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
9681   return ret.retn();
9682 }
9683
9684 /*!
9685  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9686  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9687  *
9688  * \param [in] v the input data structure to be translate into skyline format.
9689  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9690  * \param [out] dataIndex the second element of the skyline format.
9691  */
9692 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9693 {
9694   int sz((int)v.size());
9695   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9696   ret1->alloc(sz+1,1);
9697   int *pt(ret1->getPointer()); *pt=0;
9698   for(int i=0;i<sz;i++,pt++)
9699     pt[1]=pt[0]+(int)v[i].size();
9700   ret0->alloc(ret1->back(),1);
9701   pt=ret0->getPointer();
9702   for(int i=0;i<sz;i++)
9703     pt=std::copy(v[i].begin(),v[i].end(),pt);
9704   data=ret0.retn(); dataIndex=ret1.retn();
9705 }
9706
9707 /*!
9708  * Returns a new DataArrayInt which contains a complement of elements of \a this
9709  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9710  * \a nbOfElement) not present in \a this array.
9711  *  \param [in] nbOfElement - maximal size of the result array.
9712  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9713  *         array using decrRef() as it is no more needed.
9714  *  \throw If \a this is not allocated.
9715  *  \throw If \a this->getNumberOfComponents() != 1.
9716  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9717  *         nbOfElement ).
9718  */
9719 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9720 {
9721   checkAllocated();
9722   if(getNumberOfComponents()!=1)
9723     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9724   std::vector<bool> tmp(nbOfElement);
9725   const int *pt=getConstPointer();
9726   int nbOfTuples=getNumberOfTuples();
9727   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9728     if(*w>=0 && *w<nbOfElement)
9729       tmp[*w]=true;
9730     else
9731       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9732   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9733   DataArrayInt *ret=DataArrayInt::New();
9734   ret->alloc(nbOfRetVal,1);
9735   int j=0;
9736   int *retPtr=ret->getPointer();
9737   for(int i=0;i<nbOfElement;i++)
9738     if(!tmp[i])
9739       retPtr[j++]=i;
9740   return ret;
9741 }
9742
9743 /*!
9744  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9745  * from an \a other one-dimensional array.
9746  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9747  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9748  *         caller is to delete this array using decrRef() as it is no more needed.
9749  *  \throw If \a other is NULL.
9750  *  \throw If \a other is not allocated.
9751  *  \throw If \a other->getNumberOfComponents() != 1.
9752  *  \throw If \a this is not allocated.
9753  *  \throw If \a this->getNumberOfComponents() != 1.
9754  *  \sa DataArrayInt::buildSubstractionOptimized()
9755  */
9756 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9757 {
9758   if(!other)
9759     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9760   checkAllocated();
9761   other->checkAllocated();
9762   if(getNumberOfComponents()!=1)
9763     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9764   if(other->getNumberOfComponents()!=1)
9765     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9766   const int *pt=getConstPointer();
9767   int nbOfTuples=getNumberOfTuples();
9768   std::set<int> s1(pt,pt+nbOfTuples);
9769   pt=other->getConstPointer();
9770   nbOfTuples=other->getNumberOfTuples();
9771   std::set<int> s2(pt,pt+nbOfTuples);
9772   std::vector<int> r;
9773   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9774   DataArrayInt *ret=DataArrayInt::New();
9775   ret->alloc((int)r.size(),1);
9776   std::copy(r.begin(),r.end(),ret->getPointer());
9777   return ret;
9778 }
9779
9780 /*!
9781  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9782  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9783  * 
9784  * \param [in] other an array with one component and expected to be sorted ascendingly.
9785  * \ret list of ids in \a this but not in \a other.
9786  * \sa DataArrayInt::buildSubstraction
9787  */
9788 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9789 {
9790   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9791   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9792   checkAllocated(); other->checkAllocated();
9793   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9794   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9795   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9796   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9797   for(;work1!=pt1End;work1++)
9798     {
9799       if(work2!=pt2End && *work1==*work2)
9800         work2++;
9801       else
9802         ret->pushBackSilent(*work1);
9803     }
9804   return ret.retn();
9805 }
9806
9807
9808 /*!
9809  * Returns a new DataArrayInt which contains all elements of \a this and a given
9810  * one-dimensional arrays. The result array does not contain any duplicates
9811  * and its values are sorted in ascending order.
9812  *  \param [in] other - an array to unite with \a this one.
9813  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9814  *         array using decrRef() as it is no more needed.
9815  *  \throw If \a this or \a other is not allocated.
9816  *  \throw If \a this->getNumberOfComponents() != 1.
9817  *  \throw If \a other->getNumberOfComponents() != 1.
9818  */
9819 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9820 {
9821   std::vector<const DataArrayInt *>arrs(2);
9822   arrs[0]=this; arrs[1]=other;
9823   return BuildUnion(arrs);
9824 }
9825
9826
9827 /*!
9828  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9829  * one-dimensional arrays. The result array does not contain any duplicates
9830  * and its values are sorted in ascending order.
9831  *  \param [in] other - an array to intersect with \a this one.
9832  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9833  *         array using decrRef() as it is no more needed.
9834  *  \throw If \a this or \a other is not allocated.
9835  *  \throw If \a this->getNumberOfComponents() != 1.
9836  *  \throw If \a other->getNumberOfComponents() != 1.
9837  */
9838 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9839 {
9840   std::vector<const DataArrayInt *>arrs(2);
9841   arrs[0]=this; arrs[1]=other;
9842   return BuildIntersection(arrs);
9843 }
9844
9845 /*!
9846  * This method can be applied on allocated with one component DataArrayInt instance.
9847  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9848  * 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]
9849  * 
9850  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9851  * \throw if \a this is not allocated or if \a this has not exactly one component.
9852  */
9853 DataArrayInt *DataArrayInt::buildUnique() const
9854 {
9855   checkAllocated();
9856   if(getNumberOfComponents()!=1)
9857     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9858   int nbOfTuples=getNumberOfTuples();
9859   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9860   int *data=tmp->getPointer();
9861   int *last=std::unique(data,data+nbOfTuples);
9862   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9863   ret->alloc(std::distance(data,last),1);
9864   std::copy(data,last,ret->getPointer());
9865   return ret.retn();
9866 }
9867
9868 /*!
9869  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9870  * "index" array. Such "index" array is returned for example by 
9871  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9872  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9873  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9874  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9875  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9876  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9877  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9878  *          The caller is to delete this array using decrRef() as it is no more needed. 
9879  *  \throw If \a this is not allocated.
9880  *  \throw If \a this->getNumberOfComponents() != 1.
9881  *  \throw If \a this->getNumberOfTuples() < 2.
9882  *
9883  *  \b Example: <br> 
9884  *         - this contains [1,3,6,7,7,9,15]
9885  *         - result array contains [2,3,1,0,2,6],
9886  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9887  *
9888  * \sa DataArrayInt::computeOffsets2
9889  */
9890 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9891 {
9892   checkAllocated();
9893   if(getNumberOfComponents()!=1)
9894     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9895   int nbOfTuples=getNumberOfTuples();
9896   if(nbOfTuples<2)
9897     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9898   const int *ptr=getConstPointer();
9899   DataArrayInt *ret=DataArrayInt::New();
9900   ret->alloc(nbOfTuples-1,1);
9901   int *out=ret->getPointer();
9902   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9903   return ret;
9904 }
9905
9906 /*!
9907  * Modifies \a this one-dimensional array so that value of each element \a x
9908  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9909  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9910  * and components remains the same.<br>
9911  * This method is useful for allToAllV in MPI with contiguous policy. This method
9912  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9913  * this one.
9914  *  \throw If \a this is not allocated.
9915  *  \throw If \a this->getNumberOfComponents() != 1.
9916  *
9917  *  \b Example: <br>
9918  *          - Before \a this contains [3,5,1,2,0,8]
9919  *          - After \a this contains  [0,3,8,9,11,11]<br>
9920  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9921  *          array is retained and thus there is no space to store the last element.
9922  */
9923 void DataArrayInt::computeOffsets()
9924 {
9925   checkAllocated();
9926   if(getNumberOfComponents()!=1)
9927     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9928   int nbOfTuples=getNumberOfTuples();
9929   if(nbOfTuples==0)
9930     return ;
9931   int *work=getPointer();
9932   int tmp=work[0];
9933   work[0]=0;
9934   for(int i=1;i<nbOfTuples;i++)
9935     {
9936       int tmp2=work[i];
9937       work[i]=work[i-1]+tmp;
9938       tmp=tmp2;
9939     }
9940   declareAsNew();
9941 }
9942
9943
9944 /*!
9945  * Modifies \a this one-dimensional array so that value of each element \a x
9946  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9947  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9948  * components remains the same and number of tuples is inceamented by one.<br>
9949  * This method is useful for allToAllV in MPI with contiguous policy. This method
9950  * differs from computeOffsets() in that the number of tuples is changed by this one.
9951  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9952  *  \throw If \a this is not allocated.
9953  *  \throw If \a this->getNumberOfComponents() != 1.
9954  *
9955  *  \b Example: <br>
9956  *          - Before \a this contains [3,5,1,2,0,8]
9957  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9958  * \sa DataArrayInt::deltaShiftIndex
9959  */
9960 void DataArrayInt::computeOffsets2()
9961 {
9962   checkAllocated();
9963   if(getNumberOfComponents()!=1)
9964     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9965   int nbOfTuples=getNumberOfTuples();
9966   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9967   if(nbOfTuples==0)
9968     return ;
9969   const int *work=getConstPointer();
9970   ret[0]=0;
9971   for(int i=0;i<nbOfTuples;i++)
9972     ret[i+1]=work[i]+ret[i];
9973   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9974   declareAsNew();
9975 }
9976
9977 /*!
9978  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9979  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9980  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9981  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9982  * filling completely one of the ranges in \a this.
9983  *
9984  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9985  * \param [out] rangeIdsFetched the range ids fetched
9986  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9987  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9988  *
9989  * \sa DataArrayInt::computeOffsets2
9990  *
9991  *  \b Example: <br>
9992  *          - \a this : [0,3,7,9,15,18]
9993  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9994  *          - \a rangeIdsFetched result array: [0,2,4]
9995  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9996  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9997  * <br>
9998  */
9999 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10000 {
10001   if(!listOfIds)
10002     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10003   listOfIds->checkAllocated(); checkAllocated();
10004   if(listOfIds->getNumberOfComponents()!=1)
10005     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10006   if(getNumberOfComponents()!=1)
10007     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10008   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10009   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10010   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10011   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10012   while(tupPtr!=tupEnd && offPtr!=offEnd)
10013     {
10014       if(*tupPtr==*offPtr)
10015         {
10016           int i=offPtr[0];
10017           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10018           if(i==offPtr[1])
10019             {
10020               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10021               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10022               offPtr++;
10023             }
10024         }
10025       else
10026         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10027     }
10028   rangeIdsFetched=ret0.retn();
10029   idsInInputListThatFetch=ret1.retn();
10030 }
10031
10032 /*!
10033  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10034  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10035  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10036  * beginning within the "iota" array. And \a this is a one-dimensional array
10037  * considered as a selector of groups described by \a offsets to include into the result array.
10038  *  \throw If \a offsets is NULL.
10039  *  \throw If \a offsets is not allocated.
10040  *  \throw If \a offsets->getNumberOfComponents() != 1.
10041  *  \throw If \a offsets is not monotonically increasing.
10042  *  \throw If \a this is not allocated.
10043  *  \throw If \a this->getNumberOfComponents() != 1.
10044  *  \throw If any element of \a this is not a valid index for \a offsets array.
10045  *
10046  *  \b Example: <br>
10047  *          - \a this: [0,2,3]
10048  *          - \a offsets: [0,3,6,10,14,20]
10049  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10050  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10051  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10052  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10053  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10054  */
10055 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10056 {
10057   if(!offsets)
10058     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10059   checkAllocated();
10060   if(getNumberOfComponents()!=1)
10061     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10062   offsets->checkAllocated();
10063   if(offsets->getNumberOfComponents()!=1)
10064     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10065   int othNbTuples=offsets->getNumberOfTuples()-1;
10066   int nbOfTuples=getNumberOfTuples();
10067   int retNbOftuples=0;
10068   const int *work=getConstPointer();
10069   const int *offPtr=offsets->getConstPointer();
10070   for(int i=0;i<nbOfTuples;i++)
10071     {
10072       int val=work[i];
10073       if(val>=0 && val<othNbTuples)
10074         {
10075           int delta=offPtr[val+1]-offPtr[val];
10076           if(delta>=0)
10077             retNbOftuples+=delta;
10078           else
10079             {
10080               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10081               throw INTERP_KERNEL::Exception(oss.str().c_str());
10082             }
10083         }
10084       else
10085         {
10086           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10087           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10088           throw INTERP_KERNEL::Exception(oss.str().c_str());
10089         }
10090     }
10091   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10092   ret->alloc(retNbOftuples,1);
10093   int *retPtr=ret->getPointer();
10094   for(int i=0;i<nbOfTuples;i++)
10095     {
10096       int val=work[i];
10097       int start=offPtr[val];
10098       int off=offPtr[val+1]-start;
10099       for(int j=0;j<off;j++,retPtr++)
10100         *retPtr=start+j;
10101     }
10102   return ret.retn();
10103 }
10104
10105 /*!
10106  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10107  * scaled array (monotonically increasing).
10108 from that of \a this and \a
10109  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10110  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10111  * beginning within the "iota" array. And \a this is a one-dimensional array
10112  * considered as a selector of groups described by \a offsets to include into the result array.
10113  *  \throw If \a  is NULL.
10114  *  \throw If \a this is not allocated.
10115  *  \throw If \a this->getNumberOfComponents() != 1.
10116  *  \throw If \a this->getNumberOfTuples() == 0.
10117  *  \throw If \a this is not monotonically increasing.
10118  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10119  *
10120  *  \b Example: <br>
10121  *          - \a bg , \a stop and \a step : (0,5,2)
10122  *          - \a this: [0,3,6,10,14,20]
10123  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10124  */
10125 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10126 {
10127   if(!isAllocated())
10128     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10129   if(getNumberOfComponents()!=1)
10130     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10131   int nbOfTuples(getNumberOfTuples());
10132   if(nbOfTuples==0)
10133     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10134   const int *ids(begin());
10135   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10136   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10137     {
10138       if(pos>=0 && pos<nbOfTuples-1)
10139         {
10140           int delta(ids[pos+1]-ids[pos]);
10141           sz+=delta;
10142           if(delta<0)
10143             {
10144               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10145               throw INTERP_KERNEL::Exception(oss.str().c_str());
10146             }          
10147         }
10148       else
10149         {
10150           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10151           throw INTERP_KERNEL::Exception(oss.str().c_str());
10152         }
10153     }
10154   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10155   int *retPtr(ret->getPointer());
10156   pos=bg;
10157   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10158     {
10159       int delta(ids[pos+1]-ids[pos]);
10160       for(int j=0;j<delta;j++,retPtr++)
10161         *retPtr=pos;
10162     }
10163   return ret.retn();
10164 }
10165
10166 /*!
10167  * 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.
10168  * 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
10169  * in tuple **i** of returned DataArrayInt.
10170  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10171  *
10172  * 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)]
10173  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10174  * 
10175  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10176  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10177  * \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
10178  *        is thrown if no ranges in \a ranges contains value in \a this.
10179  * 
10180  * \sa DataArrayInt::findIdInRangeForEachTuple
10181  */
10182 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10183 {
10184   if(!ranges)
10185     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10186   if(ranges->getNumberOfComponents()!=2)
10187     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10188   checkAllocated();
10189   if(getNumberOfComponents()!=1)
10190     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10191   int nbTuples=getNumberOfTuples();
10192   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10193   int nbOfRanges=ranges->getNumberOfTuples();
10194   const int *rangesPtr=ranges->getConstPointer();
10195   int *retPtr=ret->getPointer();
10196   const int *inPtr=getConstPointer();
10197   for(int i=0;i<nbTuples;i++,retPtr++)
10198     {
10199       int val=inPtr[i];
10200       bool found=false;
10201       for(int j=0;j<nbOfRanges && !found;j++)
10202         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10203           { *retPtr=j; found=true; }
10204       if(found)
10205         continue;
10206       else
10207         {
10208           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10209           throw INTERP_KERNEL::Exception(oss.str().c_str());
10210         }
10211     }
10212   return ret.retn();
10213 }
10214
10215 /*!
10216  * 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.
10217  * 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
10218  * in tuple **i** of returned DataArrayInt.
10219  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10220  *
10221  * 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)]
10222  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10223  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10224  * 
10225  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10226  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10227  * \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
10228  *        is thrown if no ranges in \a ranges contains value in \a this.
10229  * \sa DataArrayInt::findRangeIdForEachTuple
10230  */
10231 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10232 {
10233   if(!ranges)
10234     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10235   if(ranges->getNumberOfComponents()!=2)
10236     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10237   checkAllocated();
10238   if(getNumberOfComponents()!=1)
10239     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10240   int nbTuples=getNumberOfTuples();
10241   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10242   int nbOfRanges=ranges->getNumberOfTuples();
10243   const int *rangesPtr=ranges->getConstPointer();
10244   int *retPtr=ret->getPointer();
10245   const int *inPtr=getConstPointer();
10246   for(int i=0;i<nbTuples;i++,retPtr++)
10247     {
10248       int val=inPtr[i];
10249       bool found=false;
10250       for(int j=0;j<nbOfRanges && !found;j++)
10251         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10252           { *retPtr=val-rangesPtr[2*j]; found=true; }
10253       if(found)
10254         continue;
10255       else
10256         {
10257           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10258           throw INTERP_KERNEL::Exception(oss.str().c_str());
10259         }
10260     }
10261   return ret.retn();
10262 }
10263
10264 /*!
10265  * 
10266  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10267  *             \a nbTimes  should be at least equal to 1.
10268  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10269  * \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.
10270  */
10271 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10272 {
10273   checkAllocated();
10274   if(getNumberOfComponents()!=1)
10275     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10276   if(nbTimes<1)
10277     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10278   int nbTuples=getNumberOfTuples();
10279   const int *inPtr=getConstPointer();
10280   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10281   int *retPtr=ret->getPointer();
10282   for(int i=0;i<nbTuples;i++,inPtr++)
10283     {
10284       int val=*inPtr;
10285       for(int j=0;j<nbTimes;j++,retPtr++)
10286         *retPtr=val;
10287     }
10288   ret->copyStringInfoFrom(*this);
10289   return ret.retn();
10290 }
10291
10292 /*!
10293  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10294  * But the number of components can be different from one.
10295  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10296  */
10297 DataArrayInt *DataArrayInt::getDifferentValues() const
10298 {
10299   checkAllocated();
10300   std::set<int> ret;
10301   ret.insert(begin(),end());
10302   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10303   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10304   return ret2.retn();
10305 }
10306
10307 /*!
10308  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10309  * them it tells which tuple id have this id.
10310  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10311  * This method returns two arrays having same size.
10312  * 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.
10313  * 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]]
10314  */
10315 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10316 {
10317   checkAllocated();
10318   if(getNumberOfComponents()!=1)
10319     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10320   int id=0;
10321   std::map<int,int> m,m2,m3;
10322   for(const int *w=begin();w!=end();w++)
10323     m[*w]++;
10324   differentIds.resize(m.size());
10325   std::vector<DataArrayInt *> ret(m.size());
10326   std::vector<int *> retPtr(m.size());
10327   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10328     {
10329       m2[(*it).first]=id;
10330       ret[id]=DataArrayInt::New();
10331       ret[id]->alloc((*it).second,1);
10332       retPtr[id]=ret[id]->getPointer();
10333       differentIds[id]=(*it).first;
10334     }
10335   id=0;
10336   for(const int *w=begin();w!=end();w++,id++)
10337     {
10338       retPtr[m2[*w]][m3[*w]++]=id;
10339     }
10340   return ret;
10341 }
10342
10343 /*!
10344  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10345  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10346  *
10347  * \param [in] nbOfSlices - number of slices expected.
10348  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10349  * 
10350  * \sa DataArray::GetSlice
10351  * \throw If \a this is not allocated or not with exactly one component.
10352  * \throw If an element in \a this if < 0.
10353  */
10354 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10355 {
10356   if(!isAllocated() || getNumberOfComponents()!=1)
10357     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10358   if(nbOfSlices<=0)
10359     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10360   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10361   int sumPerSlc(sum/nbOfSlices),pos(0);
10362   const int *w(begin());
10363   std::vector< std::pair<int,int> > ret(nbOfSlices);
10364   for(int i=0;i<nbOfSlices;i++)
10365     {
10366       std::pair<int,int> p(pos,-1);
10367       int locSum(0);
10368       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10369       if(i!=nbOfSlices-1)
10370         p.second=pos;
10371       else
10372         p.second=nbOfTuples;
10373       ret[i]=p;
10374     }
10375   return ret;
10376 }
10377
10378 /*!
10379  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10380  * valid cases.
10381  * 1.  The arrays have same number of tuples and components. Then each value of
10382  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10383  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10384  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10385  *   component. Then
10386  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10387  * 3.  The arrays have same number of components and one array, say _a2_, has one
10388  *   tuple. Then
10389  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10390  *
10391  * Info on components is copied either from the first array (in the first case) or from
10392  * the array with maximal number of elements (getNbOfElems()).
10393  *  \param [in] a1 - an array to sum up.
10394  *  \param [in] a2 - another array to sum up.
10395  *  \return DataArrayInt * - the new instance of DataArrayInt.
10396  *          The caller is to delete this result array using decrRef() as it is no more
10397  *          needed.
10398  *  \throw If either \a a1 or \a a2 is NULL.
10399  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10400  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10401  *         none of them has number of tuples or components equal to 1.
10402  */
10403 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10404 {
10405   if(!a1 || !a2)
10406     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10407   int nbOfTuple=a1->getNumberOfTuples();
10408   int nbOfTuple2=a2->getNumberOfTuples();
10409   int nbOfComp=a1->getNumberOfComponents();
10410   int nbOfComp2=a2->getNumberOfComponents();
10411   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10412   if(nbOfTuple==nbOfTuple2)
10413     {
10414       if(nbOfComp==nbOfComp2)
10415         {
10416           ret=DataArrayInt::New();
10417           ret->alloc(nbOfTuple,nbOfComp);
10418           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10419           ret->copyStringInfoFrom(*a1);
10420         }
10421       else
10422         {
10423           int nbOfCompMin,nbOfCompMax;
10424           const DataArrayInt *aMin, *aMax;
10425           if(nbOfComp>nbOfComp2)
10426             {
10427               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10428               aMin=a2; aMax=a1;
10429             }
10430           else
10431             {
10432               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10433               aMin=a1; aMax=a2;
10434             }
10435           if(nbOfCompMin==1)
10436             {
10437               ret=DataArrayInt::New();
10438               ret->alloc(nbOfTuple,nbOfCompMax);
10439               const int *aMinPtr=aMin->getConstPointer();
10440               const int *aMaxPtr=aMax->getConstPointer();
10441               int *res=ret->getPointer();
10442               for(int i=0;i<nbOfTuple;i++)
10443                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10444               ret->copyStringInfoFrom(*aMax);
10445             }
10446           else
10447             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10448         }
10449     }
10450   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10451     {
10452       if(nbOfComp==nbOfComp2)
10453         {
10454           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10455           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10456           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10457           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10458           ret=DataArrayInt::New();
10459           ret->alloc(nbOfTupleMax,nbOfComp);
10460           int *res=ret->getPointer();
10461           for(int i=0;i<nbOfTupleMax;i++)
10462             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10463           ret->copyStringInfoFrom(*aMax);
10464         }
10465       else
10466         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10467     }
10468   else
10469     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10470   return ret.retn();
10471 }
10472
10473 /*!
10474  * Adds values of another DataArrayInt to values of \a this one. There are 3
10475  * valid cases.
10476  * 1.  The arrays have same number of tuples and components. Then each value of
10477  *   \a other array is added to the corresponding value of \a this array, i.e.:
10478  *   _a_ [ i, j ] += _other_ [ i, j ].
10479  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10480  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10481  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10482  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10483  *
10484  *  \param [in] other - an array to add to \a this one.
10485  *  \throw If \a other is NULL.
10486  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10487  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10488  *         \a other has number of both tuples and components not equal to 1.
10489  */
10490 void DataArrayInt::addEqual(const DataArrayInt *other)
10491 {
10492   if(!other)
10493     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10494   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10495   checkAllocated(); other->checkAllocated();
10496   int nbOfTuple=getNumberOfTuples();
10497   int nbOfTuple2=other->getNumberOfTuples();
10498   int nbOfComp=getNumberOfComponents();
10499   int nbOfComp2=other->getNumberOfComponents();
10500   if(nbOfTuple==nbOfTuple2)
10501     {
10502       if(nbOfComp==nbOfComp2)
10503         {
10504           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10505         }
10506       else if(nbOfComp2==1)
10507         {
10508           int *ptr=getPointer();
10509           const int *ptrc=other->getConstPointer();
10510           for(int i=0;i<nbOfTuple;i++)
10511             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10512         }
10513       else
10514         throw INTERP_KERNEL::Exception(msg);
10515     }
10516   else if(nbOfTuple2==1)
10517     {
10518       if(nbOfComp2==nbOfComp)
10519         {
10520           int *ptr=getPointer();
10521           const int *ptrc=other->getConstPointer();
10522           for(int i=0;i<nbOfTuple;i++)
10523             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10524         }
10525       else
10526         throw INTERP_KERNEL::Exception(msg);
10527     }
10528   else
10529     throw INTERP_KERNEL::Exception(msg);
10530   declareAsNew();
10531 }
10532
10533 /*!
10534  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10535  * valid cases.
10536  * 1.  The arrays have same number of tuples and components. Then each value of
10537  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10538  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10539  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10540  *   component. Then
10541  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10542  * 3.  The arrays have same number of components and one array, say _a2_, has one
10543  *   tuple. Then
10544  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10545  *
10546  * Info on components is copied either from the first array (in the first case) or from
10547  * the array with maximal number of elements (getNbOfElems()).
10548  *  \param [in] a1 - an array to subtract from.
10549  *  \param [in] a2 - an array to subtract.
10550  *  \return DataArrayInt * - the new instance of DataArrayInt.
10551  *          The caller is to delete this result array using decrRef() as it is no more
10552  *          needed.
10553  *  \throw If either \a a1 or \a a2 is NULL.
10554  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10555  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10556  *         none of them has number of tuples or components equal to 1.
10557  */
10558 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10559 {
10560   if(!a1 || !a2)
10561     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10562   int nbOfTuple1=a1->getNumberOfTuples();
10563   int nbOfTuple2=a2->getNumberOfTuples();
10564   int nbOfComp1=a1->getNumberOfComponents();
10565   int nbOfComp2=a2->getNumberOfComponents();
10566   if(nbOfTuple2==nbOfTuple1)
10567     {
10568       if(nbOfComp1==nbOfComp2)
10569         {
10570           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10571           ret->alloc(nbOfTuple2,nbOfComp1);
10572           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10573           ret->copyStringInfoFrom(*a1);
10574           return ret.retn();
10575         }
10576       else if(nbOfComp2==1)
10577         {
10578           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10579           ret->alloc(nbOfTuple1,nbOfComp1);
10580           const int *a2Ptr=a2->getConstPointer();
10581           const int *a1Ptr=a1->getConstPointer();
10582           int *res=ret->getPointer();
10583           for(int i=0;i<nbOfTuple1;i++)
10584             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10585           ret->copyStringInfoFrom(*a1);
10586           return ret.retn();
10587         }
10588       else
10589         {
10590           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10591           return 0;
10592         }
10593     }
10594   else if(nbOfTuple2==1)
10595     {
10596       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10597       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10598       ret->alloc(nbOfTuple1,nbOfComp1);
10599       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10600       int *pt=ret->getPointer();
10601       for(int i=0;i<nbOfTuple1;i++)
10602         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10603       ret->copyStringInfoFrom(*a1);
10604       return ret.retn();
10605     }
10606   else
10607     {
10608       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10609       return 0;
10610     }
10611 }
10612
10613 /*!
10614  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10615  * valid cases.
10616  * 1.  The arrays have same number of tuples and components. Then each value of
10617  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10618  *   _a_ [ i, j ] -= _other_ [ i, j ].
10619  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10620  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10621  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10622  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10623  *
10624  *  \param [in] other - an array to subtract from \a this one.
10625  *  \throw If \a other is NULL.
10626  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10627  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10628  *         \a other has number of both tuples and components not equal to 1.
10629  */
10630 void DataArrayInt::substractEqual(const DataArrayInt *other)
10631 {
10632   if(!other)
10633     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10634   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10635   checkAllocated(); other->checkAllocated();
10636   int nbOfTuple=getNumberOfTuples();
10637   int nbOfTuple2=other->getNumberOfTuples();
10638   int nbOfComp=getNumberOfComponents();
10639   int nbOfComp2=other->getNumberOfComponents();
10640   if(nbOfTuple==nbOfTuple2)
10641     {
10642       if(nbOfComp==nbOfComp2)
10643         {
10644           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10645         }
10646       else if(nbOfComp2==1)
10647         {
10648           int *ptr=getPointer();
10649           const int *ptrc=other->getConstPointer();
10650           for(int i=0;i<nbOfTuple;i++)
10651             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10652         }
10653       else
10654         throw INTERP_KERNEL::Exception(msg);
10655     }
10656   else if(nbOfTuple2==1)
10657     {
10658       int *ptr=getPointer();
10659       const int *ptrc=other->getConstPointer();
10660       for(int i=0;i<nbOfTuple;i++)
10661         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10662     }
10663   else
10664     throw INTERP_KERNEL::Exception(msg);
10665   declareAsNew();
10666 }
10667
10668 /*!
10669  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10670  * valid cases.
10671  * 1.  The arrays have same number of tuples and components. Then each value of
10672  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10673  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10674  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10675  *   component. Then
10676  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10677  * 3.  The arrays have same number of components and one array, say _a2_, has one
10678  *   tuple. Then
10679  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10680  *
10681  * Info on components is copied either from the first array (in the first case) or from
10682  * the array with maximal number of elements (getNbOfElems()).
10683  *  \param [in] a1 - a factor array.
10684  *  \param [in] a2 - another factor array.
10685  *  \return DataArrayInt * - the new instance of DataArrayInt.
10686  *          The caller is to delete this result array using decrRef() as it is no more
10687  *          needed.
10688  *  \throw If either \a a1 or \a a2 is NULL.
10689  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10690  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10691  *         none of them has number of tuples or components equal to 1.
10692  */
10693 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10694 {
10695   if(!a1 || !a2)
10696     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10697   int nbOfTuple=a1->getNumberOfTuples();
10698   int nbOfTuple2=a2->getNumberOfTuples();
10699   int nbOfComp=a1->getNumberOfComponents();
10700   int nbOfComp2=a2->getNumberOfComponents();
10701   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10702   if(nbOfTuple==nbOfTuple2)
10703     {
10704       if(nbOfComp==nbOfComp2)
10705         {
10706           ret=DataArrayInt::New();
10707           ret->alloc(nbOfTuple,nbOfComp);
10708           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10709           ret->copyStringInfoFrom(*a1);
10710         }
10711       else
10712         {
10713           int nbOfCompMin,nbOfCompMax;
10714           const DataArrayInt *aMin, *aMax;
10715           if(nbOfComp>nbOfComp2)
10716             {
10717               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10718               aMin=a2; aMax=a1;
10719             }
10720           else
10721             {
10722               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10723               aMin=a1; aMax=a2;
10724             }
10725           if(nbOfCompMin==1)
10726             {
10727               ret=DataArrayInt::New();
10728               ret->alloc(nbOfTuple,nbOfCompMax);
10729               const int *aMinPtr=aMin->getConstPointer();
10730               const int *aMaxPtr=aMax->getConstPointer();
10731               int *res=ret->getPointer();
10732               for(int i=0;i<nbOfTuple;i++)
10733                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10734               ret->copyStringInfoFrom(*aMax);
10735             }
10736           else
10737             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10738         }
10739     }
10740   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10741     {
10742       if(nbOfComp==nbOfComp2)
10743         {
10744           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10745           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10746           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10747           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10748           ret=DataArrayInt::New();
10749           ret->alloc(nbOfTupleMax,nbOfComp);
10750           int *res=ret->getPointer();
10751           for(int i=0;i<nbOfTupleMax;i++)
10752             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10753           ret->copyStringInfoFrom(*aMax);
10754         }
10755       else
10756         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10757     }
10758   else
10759     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10760   return ret.retn();
10761 }
10762
10763
10764 /*!
10765  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10766  * valid cases.
10767  * 1.  The arrays have same number of tuples and components. Then each value of
10768  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10769  *   _a_ [ i, j ] *= _other_ [ i, j ].
10770  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10771  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10772  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10773  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10774  *
10775  *  \param [in] other - an array to multiply to \a this one.
10776  *  \throw If \a other is NULL.
10777  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10778  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10779  *         \a other has number of both tuples and components not equal to 1.
10780  */
10781 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10782 {
10783   if(!other)
10784     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10785   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10786   checkAllocated(); other->checkAllocated();
10787   int nbOfTuple=getNumberOfTuples();
10788   int nbOfTuple2=other->getNumberOfTuples();
10789   int nbOfComp=getNumberOfComponents();
10790   int nbOfComp2=other->getNumberOfComponents();
10791   if(nbOfTuple==nbOfTuple2)
10792     {
10793       if(nbOfComp==nbOfComp2)
10794         {
10795           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10796         }
10797       else if(nbOfComp2==1)
10798         {
10799           int *ptr=getPointer();
10800           const int *ptrc=other->getConstPointer();
10801           for(int i=0;i<nbOfTuple;i++)
10802             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10803         }
10804       else
10805         throw INTERP_KERNEL::Exception(msg);
10806     }
10807   else if(nbOfTuple2==1)
10808     {
10809       if(nbOfComp2==nbOfComp)
10810         {
10811           int *ptr=getPointer();
10812           const int *ptrc=other->getConstPointer();
10813           for(int i=0;i<nbOfTuple;i++)
10814             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10815         }
10816       else
10817         throw INTERP_KERNEL::Exception(msg);
10818     }
10819   else
10820     throw INTERP_KERNEL::Exception(msg);
10821   declareAsNew();
10822 }
10823
10824
10825 /*!
10826  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10827  * valid cases.
10828  * 1.  The arrays have same number of tuples and components. Then each value of
10829  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10830  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10831  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10832  *   component. Then
10833  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10834  * 3.  The arrays have same number of components and one array, say _a2_, has one
10835  *   tuple. Then
10836  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10837  *
10838  * Info on components is copied either from the first array (in the first case) or from
10839  * the array with maximal number of elements (getNbOfElems()).
10840  *  \warning No check of division by zero is performed!
10841  *  \param [in] a1 - a numerator array.
10842  *  \param [in] a2 - a denominator array.
10843  *  \return DataArrayInt * - the new instance of DataArrayInt.
10844  *          The caller is to delete this result array using decrRef() as it is no more
10845  *          needed.
10846  *  \throw If either \a a1 or \a a2 is NULL.
10847  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10848  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10849  *         none of them has number of tuples or components equal to 1.
10850  */
10851 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10852 {
10853   if(!a1 || !a2)
10854     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10855   int nbOfTuple1=a1->getNumberOfTuples();
10856   int nbOfTuple2=a2->getNumberOfTuples();
10857   int nbOfComp1=a1->getNumberOfComponents();
10858   int nbOfComp2=a2->getNumberOfComponents();
10859   if(nbOfTuple2==nbOfTuple1)
10860     {
10861       if(nbOfComp1==nbOfComp2)
10862         {
10863           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10864           ret->alloc(nbOfTuple2,nbOfComp1);
10865           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10866           ret->copyStringInfoFrom(*a1);
10867           return ret.retn();
10868         }
10869       else if(nbOfComp2==1)
10870         {
10871           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10872           ret->alloc(nbOfTuple1,nbOfComp1);
10873           const int *a2Ptr=a2->getConstPointer();
10874           const int *a1Ptr=a1->getConstPointer();
10875           int *res=ret->getPointer();
10876           for(int i=0;i<nbOfTuple1;i++)
10877             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10878           ret->copyStringInfoFrom(*a1);
10879           return ret.retn();
10880         }
10881       else
10882         {
10883           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10884           return 0;
10885         }
10886     }
10887   else if(nbOfTuple2==1)
10888     {
10889       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10890       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10891       ret->alloc(nbOfTuple1,nbOfComp1);
10892       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10893       int *pt=ret->getPointer();
10894       for(int i=0;i<nbOfTuple1;i++)
10895         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10896       ret->copyStringInfoFrom(*a1);
10897       return ret.retn();
10898     }
10899   else
10900     {
10901       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10902       return 0;
10903     }
10904 }
10905
10906 /*!
10907  * Divide values of \a this array by values of another DataArrayInt. There are 3
10908  * valid cases.
10909  * 1.  The arrays have same number of tuples and components. Then each value of
10910  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10911  *   _a_ [ i, j ] /= _other_ [ i, j ].
10912  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10913  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10914  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10915  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10916  *
10917  *  \warning No check of division by zero is performed!
10918  *  \param [in] other - an array to divide \a this one by.
10919  *  \throw If \a other is NULL.
10920  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10921  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10922  *         \a other has number of both tuples and components not equal to 1.
10923  */
10924 void DataArrayInt::divideEqual(const DataArrayInt *other)
10925 {
10926   if(!other)
10927     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10928   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10929   checkAllocated(); other->checkAllocated();
10930   int nbOfTuple=getNumberOfTuples();
10931   int nbOfTuple2=other->getNumberOfTuples();
10932   int nbOfComp=getNumberOfComponents();
10933   int nbOfComp2=other->getNumberOfComponents();
10934   if(nbOfTuple==nbOfTuple2)
10935     {
10936       if(nbOfComp==nbOfComp2)
10937         {
10938           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10939         }
10940       else if(nbOfComp2==1)
10941         {
10942           int *ptr=getPointer();
10943           const int *ptrc=other->getConstPointer();
10944           for(int i=0;i<nbOfTuple;i++)
10945             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10946         }
10947       else
10948         throw INTERP_KERNEL::Exception(msg);
10949     }
10950   else if(nbOfTuple2==1)
10951     {
10952       if(nbOfComp2==nbOfComp)
10953         {
10954           int *ptr=getPointer();
10955           const int *ptrc=other->getConstPointer();
10956           for(int i=0;i<nbOfTuple;i++)
10957             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10958         }
10959       else
10960         throw INTERP_KERNEL::Exception(msg);
10961     }
10962   else
10963     throw INTERP_KERNEL::Exception(msg);
10964   declareAsNew();
10965 }
10966
10967
10968 /*!
10969  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10970  * valid cases.
10971  * 1.  The arrays have same number of tuples and components. Then each value of
10972  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10973  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10974  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10975  *   component. Then
10976  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10977  * 3.  The arrays have same number of components and one array, say _a2_, has one
10978  *   tuple. Then
10979  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10980  *
10981  * Info on components is copied either from the first array (in the first case) or from
10982  * the array with maximal number of elements (getNbOfElems()).
10983  *  \warning No check of division by zero is performed!
10984  *  \param [in] a1 - a dividend array.
10985  *  \param [in] a2 - a divisor array.
10986  *  \return DataArrayInt * - the new instance of DataArrayInt.
10987  *          The caller is to delete this result array using decrRef() as it is no more
10988  *          needed.
10989  *  \throw If either \a a1 or \a a2 is NULL.
10990  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10991  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10992  *         none of them has number of tuples or components equal to 1.
10993  */
10994 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10995 {
10996   if(!a1 || !a2)
10997     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10998   int nbOfTuple1=a1->getNumberOfTuples();
10999   int nbOfTuple2=a2->getNumberOfTuples();
11000   int nbOfComp1=a1->getNumberOfComponents();
11001   int nbOfComp2=a2->getNumberOfComponents();
11002   if(nbOfTuple2==nbOfTuple1)
11003     {
11004       if(nbOfComp1==nbOfComp2)
11005         {
11006           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11007           ret->alloc(nbOfTuple2,nbOfComp1);
11008           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11009           ret->copyStringInfoFrom(*a1);
11010           return ret.retn();
11011         }
11012       else if(nbOfComp2==1)
11013         {
11014           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11015           ret->alloc(nbOfTuple1,nbOfComp1);
11016           const int *a2Ptr=a2->getConstPointer();
11017           const int *a1Ptr=a1->getConstPointer();
11018           int *res=ret->getPointer();
11019           for(int i=0;i<nbOfTuple1;i++)
11020             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11021           ret->copyStringInfoFrom(*a1);
11022           return ret.retn();
11023         }
11024       else
11025         {
11026           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11027           return 0;
11028         }
11029     }
11030   else if(nbOfTuple2==1)
11031     {
11032       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11033       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11034       ret->alloc(nbOfTuple1,nbOfComp1);
11035       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11036       int *pt=ret->getPointer();
11037       for(int i=0;i<nbOfTuple1;i++)
11038         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11039       ret->copyStringInfoFrom(*a1);
11040       return ret.retn();
11041     }
11042   else
11043     {
11044       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11045       return 0;
11046     }
11047 }
11048
11049 /*!
11050  * Modify \a this array so that each value becomes a modulus of division of this value by
11051  * a value of another DataArrayInt. There are 3 valid cases.
11052  * 1.  The arrays have same number of tuples and components. Then each value of
11053  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11054  *   _a_ [ i, j ] %= _other_ [ i, j ].
11055  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11056  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11057  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11058  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11059  *
11060  *  \warning No check of division by zero is performed!
11061  *  \param [in] other - a divisor array.
11062  *  \throw If \a other is NULL.
11063  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11064  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11065  *         \a other has number of both tuples and components not equal to 1.
11066  */
11067 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11068 {
11069   if(!other)
11070     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11071   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11072   checkAllocated(); other->checkAllocated();
11073   int nbOfTuple=getNumberOfTuples();
11074   int nbOfTuple2=other->getNumberOfTuples();
11075   int nbOfComp=getNumberOfComponents();
11076   int nbOfComp2=other->getNumberOfComponents();
11077   if(nbOfTuple==nbOfTuple2)
11078     {
11079       if(nbOfComp==nbOfComp2)
11080         {
11081           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11082         }
11083       else if(nbOfComp2==1)
11084         {
11085           if(nbOfComp2==nbOfComp)
11086             {
11087               int *ptr=getPointer();
11088               const int *ptrc=other->getConstPointer();
11089               for(int i=0;i<nbOfTuple;i++)
11090                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11091             }
11092           else
11093             throw INTERP_KERNEL::Exception(msg);
11094         }
11095       else
11096         throw INTERP_KERNEL::Exception(msg);
11097     }
11098   else if(nbOfTuple2==1)
11099     {
11100       int *ptr=getPointer();
11101       const int *ptrc=other->getConstPointer();
11102       for(int i=0;i<nbOfTuple;i++)
11103         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11104     }
11105   else
11106     throw INTERP_KERNEL::Exception(msg);
11107   declareAsNew();
11108 }
11109
11110 /*!
11111  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11112  * valid cases.
11113  *
11114  *  \param [in] a1 - an array to pow up.
11115  *  \param [in] a2 - another array to sum up.
11116  *  \return DataArrayInt * - the new instance of DataArrayInt.
11117  *          The caller is to delete this result array using decrRef() as it is no more
11118  *          needed.
11119  *  \throw If either \a a1 or \a a2 is NULL.
11120  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11121  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11122  *  \throw If there is a negative value in \a a2.
11123  */
11124 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11125 {
11126   if(!a1 || !a2)
11127     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11128   int nbOfTuple=a1->getNumberOfTuples();
11129   int nbOfTuple2=a2->getNumberOfTuples();
11130   int nbOfComp=a1->getNumberOfComponents();
11131   int nbOfComp2=a2->getNumberOfComponents();
11132   if(nbOfTuple!=nbOfTuple2)
11133     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11134   if(nbOfComp!=1 || nbOfComp2!=1)
11135     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11136   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11137   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11138   int *ptr=ret->getPointer();
11139   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11140     {
11141       if(*ptr2>=0)
11142         {
11143           int tmp=1;
11144           for(int j=0;j<*ptr2;j++)
11145             tmp*=*ptr1;
11146           *ptr=tmp;
11147         }
11148       else
11149         {
11150           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11151           throw INTERP_KERNEL::Exception(oss.str().c_str());
11152         }
11153     }
11154   return ret.retn();
11155 }
11156
11157 /*!
11158  * Apply pow on values of another DataArrayInt to values of \a this one.
11159  *
11160  *  \param [in] other - an array to pow to \a this one.
11161  *  \throw If \a other is NULL.
11162  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11163  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11164  *  \throw If there is a negative value in \a other.
11165  */
11166 void DataArrayInt::powEqual(const DataArrayInt *other)
11167 {
11168   if(!other)
11169     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11170   int nbOfTuple=getNumberOfTuples();
11171   int nbOfTuple2=other->getNumberOfTuples();
11172   int nbOfComp=getNumberOfComponents();
11173   int nbOfComp2=other->getNumberOfComponents();
11174   if(nbOfTuple!=nbOfTuple2)
11175     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11176   if(nbOfComp!=1 || nbOfComp2!=1)
11177     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11178   int *ptr=getPointer();
11179   const int *ptrc=other->begin();
11180   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11181     {
11182       if(*ptrc>=0)
11183         {
11184           int tmp=1;
11185           for(int j=0;j<*ptrc;j++)
11186             tmp*=*ptr;
11187           *ptr=tmp;
11188         }
11189       else
11190         {
11191           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11192           throw INTERP_KERNEL::Exception(oss.str().c_str());
11193         }
11194     }
11195   declareAsNew();
11196 }
11197
11198 /*!
11199  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11200  * This map, if applied to \a start array, would make it sorted. For example, if
11201  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11202  * [5,6,0,3,2,7,1,4].
11203  *  \param [in] start - pointer to the first element of the array for which the
11204  *         permutation map is computed.
11205  *  \param [in] end - pointer specifying the end of the array \a start, so that
11206  *         the last value of \a start is \a end[ -1 ].
11207  *  \return int * - the result permutation array that the caller is to delete as it is no
11208  *         more needed.
11209  *  \throw If there are equal values in the input array.
11210  */
11211 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11212 {
11213   std::size_t sz=std::distance(start,end);
11214   int *ret=(int *)malloc(sz*sizeof(int));
11215   int *work=new int[sz];
11216   std::copy(start,end,work);
11217   std::sort(work,work+sz);
11218   if(std::unique(work,work+sz)!=work+sz)
11219     {
11220       delete [] work;
11221       free(ret);
11222       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11223     }
11224   std::map<int,int> m;
11225   for(int *workPt=work;workPt!=work+sz;workPt++)
11226     m[*workPt]=(int)std::distance(work,workPt);
11227   int *iter2=ret;
11228   for(const int *iter=start;iter!=end;iter++,iter2++)
11229     *iter2=m[*iter];
11230   delete [] work;
11231   return ret;
11232 }
11233
11234 /*!
11235  * Returns a new DataArrayInt containing an arithmetic progression
11236  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11237  * function.
11238  *  \param [in] begin - the start value of the result sequence.
11239  *  \param [in] end - limiting value, so that every value of the result array is less than
11240  *              \a end.
11241  *  \param [in] step - specifies the increment or decrement.
11242  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11243  *          array using decrRef() as it is no more needed.
11244  *  \throw If \a step == 0.
11245  *  \throw If \a end < \a begin && \a step > 0.
11246  *  \throw If \a end > \a begin && \a step < 0.
11247  */
11248 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11249 {
11250   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11251   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11252   ret->alloc(nbOfTuples,1);
11253   int *ptr=ret->getPointer();
11254   if(step>0)
11255     {
11256       for(int i=begin;i<end;i+=step,ptr++)
11257         *ptr=i;
11258     }
11259   else
11260     {
11261       for(int i=begin;i>end;i+=step,ptr++)
11262         *ptr=i;
11263     }
11264   return ret.retn();
11265 }
11266
11267 /*!
11268  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11269  * Server side.
11270  */
11271 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11272 {
11273   tinyInfo.resize(2);
11274   if(isAllocated())
11275     {
11276       tinyInfo[0]=getNumberOfTuples();
11277       tinyInfo[1]=getNumberOfComponents();
11278     }
11279   else
11280     {
11281       tinyInfo[0]=-1;
11282       tinyInfo[1]=-1;
11283     }
11284 }
11285
11286 /*!
11287  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11288  * Server side.
11289  */
11290 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11291 {
11292   if(isAllocated())
11293     {
11294       int nbOfCompo=getNumberOfComponents();
11295       tinyInfo.resize(nbOfCompo+1);
11296       tinyInfo[0]=getName();
11297       for(int i=0;i<nbOfCompo;i++)
11298         tinyInfo[i+1]=getInfoOnComponent(i);
11299     }
11300   else
11301     {
11302       tinyInfo.resize(1);
11303       tinyInfo[0]=getName();
11304     }
11305 }
11306
11307 /*!
11308  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11309  * This method returns if a feeding is needed.
11310  */
11311 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11312 {
11313   int nbOfTuple=tinyInfoI[0];
11314   int nbOfComp=tinyInfoI[1];
11315   if(nbOfTuple!=-1 || nbOfComp!=-1)
11316     {
11317       alloc(nbOfTuple,nbOfComp);
11318       return true;
11319     }
11320   return false;
11321 }
11322
11323 /*!
11324  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11325  * This method returns if a feeding is needed.
11326  */
11327 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11328 {
11329   setName(tinyInfoS[0]);
11330   if(isAllocated())
11331     {
11332       int nbOfCompo=tinyInfoI[1];
11333       for(int i=0;i<nbOfCompo;i++)
11334         setInfoOnComponent(i,tinyInfoS[i+1]);
11335     }
11336 }
11337
11338 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11339 {
11340   if(_da)
11341     {
11342       _da->incrRef();
11343       if(_da->isAllocated())
11344         {
11345           _nb_comp=da->getNumberOfComponents();
11346           _nb_tuple=da->getNumberOfTuples();
11347           _pt=da->getPointer();
11348         }
11349     }
11350 }
11351
11352 DataArrayIntIterator::~DataArrayIntIterator()
11353 {
11354   if(_da)
11355     _da->decrRef();
11356 }
11357
11358 DataArrayIntTuple *DataArrayIntIterator::nextt()
11359 {
11360   if(_tuple_id<_nb_tuple)
11361     {
11362       _tuple_id++;
11363       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11364       _pt+=_nb_comp;
11365       return ret;
11366     }
11367   else
11368     return 0;
11369 }
11370
11371 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11372 {
11373 }
11374
11375 std::string DataArrayIntTuple::repr() const
11376 {
11377   std::ostringstream oss; oss << "(";
11378   for(int i=0;i<_nb_of_compo-1;i++)
11379     oss << _pt[i] << ", ";
11380   oss << _pt[_nb_of_compo-1] << ")";
11381   return oss.str();
11382 }
11383
11384 int DataArrayIntTuple::intValue() const
11385 {
11386   if(_nb_of_compo==1)
11387     return *_pt;
11388   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11389 }
11390
11391 /*!
11392  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11393  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11394  * 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
11395  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11396  */
11397 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11398 {
11399   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11400     {
11401       DataArrayInt *ret=DataArrayInt::New();
11402       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11403       return ret;
11404     }
11405   else
11406     {
11407       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11408       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11409       throw INTERP_KERNEL::Exception(oss.str().c_str());
11410     }
11411 }