Salome HOME
9c2fda8fa2970156c018b98427efe2e7928d62e9
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  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.
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 "InterpKernelExprParser.hxx"
27
28 #include <set>
29 #include <cmath>
30 #include <limits>
31 #include <numeric>
32 #include <algorithm>
33 #include <functional>
34
35 typedef double (*MYFUNCPTR)(double);
36
37 using namespace ParaMEDMEM;
38
39 template<int SPACEDIM>
40 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
41 {
42   const double *coordsPtr=getConstPointer();
43   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
44   std::vector<bool> isDone(nbNodes);
45   for(int i=0;i<nbNodes;i++)
46     {
47       if(!isDone[i])
48         {
49           std::vector<int> intersectingElems;
50           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
51           if(intersectingElems.size()>1)
52             {
53               std::vector<int> commonNodes;
54               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
55                 if(*it!=i)
56                   if(*it>=limitNodeId)
57                     {
58                       commonNodes.push_back(*it);
59                       isDone[*it]=true;
60                     }
61               if(!commonNodes.empty())
62                 {
63                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
64                   c->pushBackSilent(i);
65                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
66                 }
67             }
68         }
69     }
70 }
71
72 template<int SPACEDIM>
73 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
74                                                 DataArrayInt *c, DataArrayInt *cI)
75 {
76   for(int i=0;i<nbOfTuples;i++)
77     {
78       std::vector<int> intersectingElems;
79       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
80       std::vector<int> commonNodes;
81       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
82         commonNodes.push_back(*it);
83       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
84       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
85     }
86 }
87
88 template<int SPACEDIM>
89 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
90 {
91   double distOpt(dist);
92   const double *p(pos);
93   int *r(res);
94   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
95     {
96       while(true)
97         {
98           int elem=-1;
99           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
100           if(ret!=std::numeric_limits<double>::max())
101             {
102               distOpt=std::max(ret,1e-4);
103               *r=elem;
104               break;
105             }
106           else
107             { distOpt=2*distOpt; continue; }
108         }
109     }
110 }
111
112 std::size_t DataArray::getHeapMemorySize() const
113 {
114   std::size_t sz1=_name.capacity();
115   std::size_t sz2=_info_on_compo.capacity();
116   std::size_t sz3=0;
117   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
118     sz3+=(*it).capacity();
119   return sz1+sz2+sz3;
120 }
121
122 /*!
123  * Sets the attribute \a _name of \a this array.
124  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
125  *  \param [in] name - new array name
126  */
127 void DataArray::setName(const char *name)
128 {
129   _name=name;
130 }
131
132 /*!
133  * Copies textual data from an \a other DataArray. The copied data are
134  * - the name attribute,
135  * - the information of components.
136  *
137  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
138  *
139  *  \param [in] other - another instance of DataArray to copy the textual data from.
140  *  \throw If number of components of \a this array differs from that of the \a other.
141  */
142 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
143 {
144   if(_info_on_compo.size()!=other._info_on_compo.size())
145     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
146   _name=other._name;
147   _info_on_compo=other._info_on_compo;
148 }
149
150 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
151 {
152   int nbOfCompoOth=other.getNumberOfComponents();
153   std::size_t newNbOfCompo=compoIds.size();
154   for(std::size_t i=0;i<newNbOfCompo;i++)
155     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
156       {
157         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
158         throw INTERP_KERNEL::Exception(oss.str().c_str());
159       }
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
162 }
163
164 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
165 {
166   int nbOfCompo=getNumberOfComponents();
167   std::size_t partOfCompoToSet=compoIds.size();
168   if((int)partOfCompoToSet!=other.getNumberOfComponents())
169     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
170   for(std::size_t i=0;i<partOfCompoToSet;i++)
171     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
172       {
173         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
174         throw INTERP_KERNEL::Exception(oss.str().c_str());
175       }
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
178 }
179
180 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
181 {
182   std::ostringstream oss;
183   if(_name!=other._name)
184     {
185       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
186       reason=oss.str();
187       return false;
188     }
189   if(_info_on_compo!=other._info_on_compo)
190     {
191       oss << "Components DataArray mismatch : \nThis components=";
192       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
193         oss << "\"" << *it << "\",";
194       oss << "\nOther components=";
195       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
196         oss << "\"" << *it << "\",";
197       reason=oss.str();
198       return false;
199     }
200   return true;
201 }
202
203 /*!
204  * Compares textual information of \a this DataArray with that of an \a other one.
205  * The compared data are
206  * - the name attribute,
207  * - the information of components.
208  *
209  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
210  *  \param [in] other - another instance of DataArray to compare the textual data of.
211  *  \return bool - \a true if the textual information is same, \a false else.
212  */
213 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
214 {
215   std::string tmp;
216   return areInfoEqualsIfNotWhy(other,tmp);
217 }
218
219 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
220 {
221   stream << "Number of components : "<< getNumberOfComponents() << "\n";
222   stream << "Info of these components : ";
223   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
224     stream << "\"" << *iter << "\"   ";
225   stream << "\n";
226 }
227
228 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
229 {
230   std::ostringstream ret;
231   reprCppStream(varName,ret);
232   return ret.str();
233 }
234
235 /*!
236  * Sets information on all components. To know more on format of this information
237  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
238  *  \param [in] info - a vector of strings.
239  *  \throw If size of \a info differs from the number of components of \a this.
240  */
241 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
242 {
243   if(getNumberOfComponents()!=(int)info.size())
244     {
245       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
246       throw INTERP_KERNEL::Exception(oss.str().c_str());
247     }
248   _info_on_compo=info;
249 }
250
251 /*!
252  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
253  * type of \a this and \a aBase.
254  *
255  * \throw If \a aBase and \a this do not have the same type.
256  *
257  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
258  */
259 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
260 {
261   if(!aBase)
262     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
263   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
264   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
265   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
266   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
267   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
268   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
269   if(this1 && a1)
270     {
271       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
272       return ;
273     }
274   if(this2 && a2)
275     {
276       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
277       return ;
278     }
279   if(this3 && a3)
280     {
281       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
282       return ;
283     }
284   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
285 }
286
287 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
288 {
289   int nbOfCompo=(int)_info_on_compo.size();
290   std::vector<std::string> ret(nbOfCompo);
291   for(int i=0;i<nbOfCompo;i++)
292     ret[i]=getVarOnComponent(i);
293   return ret;
294 }
295
296 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
297 {
298   int nbOfCompo=(int)_info_on_compo.size();
299   std::vector<std::string> ret(nbOfCompo);
300   for(int i=0;i<nbOfCompo;i++)
301     ret[i]=getUnitOnComponent(i);
302   return ret;
303 }
304
305 /*!
306  * Returns information on a component specified by an index.
307  * To know more on format of this information
308  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
309  *  \param [in] i - the index (zero based) of the component of interest.
310  *  \return std::string - a string containing the information on \a i-th component.
311  *  \throw If \a i is not a valid component index.
312  */
313 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
314 {
315   if(i<(int)_info_on_compo.size() && i>=0)
316     return _info_on_compo[i];
317   else
318     {
319       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();
320       throw INTERP_KERNEL::Exception(oss.str().c_str());
321     }
322 }
323
324 /*!
325  * Returns the var part of the full information of the \a i-th component.
326  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
327  * \c getVarOnComponent(0) returns "SIGXY".
328  * If a unit part of information is not detected by presence of
329  * two square brackets, then the full information is returned.
330  * To read more about the component information format, see
331  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
332  *  \param [in] i - the index (zero based) of the component of interest.
333  *  \return std::string - a string containing the var information, or the full info.
334  *  \throw If \a i is not a valid component index.
335  */
336 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
337 {
338   if(i<(int)_info_on_compo.size() && i>=0)
339     {
340       return GetVarNameFromInfo(_info_on_compo[i]);
341     }
342   else
343     {
344       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();
345       throw INTERP_KERNEL::Exception(oss.str().c_str());
346     }
347 }
348
349 /*!
350  * Returns the unit part of the full information of the \a i-th component.
351  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
352  * \c getUnitOnComponent(0) returns " N/m^2".
353  * If a unit part of information is not detected by presence of
354  * two square brackets, then an empty string is returned.
355  * To read more about the component information format, see
356  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
357  *  \param [in] i - the index (zero based) of the component of interest.
358  *  \return std::string - a string containing the unit information, if any, or "".
359  *  \throw If \a i is not a valid component index.
360  */
361 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
362 {
363   if(i<(int)_info_on_compo.size() && i>=0)
364     {
365       return GetUnitFromInfo(_info_on_compo[i]);
366     }
367   else
368     {
369       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();
370       throw INTERP_KERNEL::Exception(oss.str().c_str());
371     }
372 }
373
374 /*!
375  * Returns the var part of the full component information.
376  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
377  * If a unit part of information is not detected by presence of
378  * two square brackets, then the whole \a info is returned.
379  * To read more about the component information format, see
380  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
381  *  \param [in] info - the full component information.
382  *  \return std::string - a string containing only var information, or the \a info.
383  */
384 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
385 {
386   std::size_t p1=info.find_last_of('[');
387   std::size_t p2=info.find_last_of(']');
388   if(p1==std::string::npos || p2==std::string::npos)
389     return info;
390   if(p1>p2)
391     return info;
392   if(p1==0)
393     return std::string();
394   std::size_t p3=info.find_last_not_of(' ',p1-1);
395   return info.substr(0,p3+1);
396 }
397
398 /*!
399  * Returns the unit part of the full component information.
400  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
401  * If a unit part of information is not detected by presence of
402  * two square brackets, then an empty string is returned.
403  * To read more about the component information format, see
404  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
405  *  \param [in] info - the full component information.
406  *  \return std::string - a string containing only unit information, if any, or "".
407  */
408 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
409 {
410   std::size_t p1=info.find_last_of('[');
411   std::size_t p2=info.find_last_of(']');
412   if(p1==std::string::npos || p2==std::string::npos)
413     return std::string();
414   if(p1>p2)
415     return std::string();
416   return info.substr(p1+1,p2-p1-1);
417 }
418
419 /*!
420  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
421  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
422  * the number of component in the result array is same as that of each of given arrays.
423  * Info on components is copied from the first of the given arrays. Number of components
424  * in the given arrays must be  the same.
425  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
426  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
427  *          The caller is to delete this result array using decrRef() as it is no more
428  *          needed.
429  *  \throw If all arrays within \a arrs are NULL.
430  *  \throw If all not null arrays in \a arrs have not the same type.
431  *  \throw If getNumberOfComponents() of arrays within \a arrs.
432  */
433 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs) throw(INTERP_KERNEL::Exception)
434 {
435   std::vector<const DataArray *> arr2;
436   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
437     if(*it)
438       arr2.push_back(*it);
439   if(arr2.empty())
440     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
441   std::vector<const DataArrayDouble *> arrd;
442   std::vector<const DataArrayInt *> arri;
443   std::vector<const DataArrayChar *> arrc;
444   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
445     {
446       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
447       if(a)
448         { arrd.push_back(a); continue; }
449       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
450       if(b)
451         { arri.push_back(b); continue; }
452       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
453       if(c)
454         { arrc.push_back(c); continue; }
455       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
456     }
457   if(arr2.size()==arrd.size())
458     return DataArrayDouble::Aggregate(arrd);
459   if(arr2.size()==arri.size())
460     return DataArrayInt::Aggregate(arri);
461   if(arr2.size()==arrc.size())
462     return DataArrayChar::Aggregate(arrc);
463   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
464 }
465
466 /*!
467  * Sets information on a component specified by an index.
468  * To know more on format of this information
469  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
470  *  \warning Don't pass NULL as \a info!
471  *  \param [in] i - the index (zero based) of the component of interest.
472  *  \param [in] info - the string containing the information.
473  *  \throw If \a i is not a valid component index.
474  */
475 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
476 {
477   if(i<(int)_info_on_compo.size() && i>=0)
478     _info_on_compo[i]=info;
479   else
480     {
481       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();
482       throw INTERP_KERNEL::Exception(oss.str().c_str());
483     }
484 }
485
486 /*!
487  * Sets information on all components. This method can change number of components
488  * at certain conditions; if the conditions are not respected, an exception is thrown.
489  * The number of components can be changed in \a this only if \a this is not allocated.
490  * The condition of number of components must not be changed.
491  *
492  * To know more on format of the component information see
493  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
494  *  \param [in] info - a vector of component infos.
495  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
496  */
497 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
498 {
499   if(getNumberOfComponents()!=(int)info.size())
500     {
501       if(!isAllocated())
502         _info_on_compo=info;
503       else
504         {
505           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 !";
506           throw INTERP_KERNEL::Exception(oss.str().c_str());
507         }
508     }
509   else
510     _info_on_compo=info;
511 }
512
513 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
514 {
515   if(getNumberOfTuples()!=nbOfTuples)
516     {
517       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
518       throw INTERP_KERNEL::Exception(oss.str().c_str());
519     }
520 }
521
522 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
523 {
524   if(getNumberOfComponents()!=nbOfCompo)
525     {
526       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
527       throw INTERP_KERNEL::Exception(oss.str().c_str());
528     }
529 }
530
531 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
532 {
533   if(getNbOfElems()!=nbOfElems)
534     {
535       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538 }
539
540 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
541 {
542    if(getNumberOfTuples()!=other.getNumberOfTuples())
543     {
544       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547   if(getNumberOfComponents()!=other.getNumberOfComponents())
548     {
549       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
550       throw INTERP_KERNEL::Exception(oss.str().c_str());
551     }
552 }
553
554 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
555 {
556   checkNbOfTuples(nbOfTuples,msg);
557   checkNbOfComps(nbOfCompo,msg);
558 }
559
560 /*!
561  * Simply this method checks that \b value is in [0,\b ref).
562  */
563 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
564 {
565   if(value<0 || value>=ref)
566     {
567       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570 }
571
572 /*!
573  * This method checks that [\b start, \b end) is compliant with ref length \b value.
574  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
575  */
576 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
577 {
578   if(start<0 || start>=value)
579     {
580       if(value!=start || end!=start)
581         {
582           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
583           throw INTERP_KERNEL::Exception(oss.str().c_str());
584         }
585     }
586   if(end<0 || end>value)
587     {
588       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
589       throw INTERP_KERNEL::Exception(oss.str().c_str());
590     }
591 }
592
593 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
594 {
595   if(value<0 || value>ref)
596     {
597       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
598       throw INTERP_KERNEL::Exception(oss.str().c_str());
599     }
600 }
601
602 /*!
603  * 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, 
604  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
605  *
606  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
607  *
608  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
609  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
610  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
611  * \param [in] sliceId - the slice id considered
612  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
613  * \param [out] startSlice - the start of the slice considered
614  * \param [out] stopSlice - the stop of the slice consided
615  * 
616  * \throw If \a step == 0
617  * \throw If \a nbOfSlices not > 0
618  * \throw If \a sliceId not in [0,nbOfSlices)
619  */
620 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
621 {
622   if(nbOfSlices<=0)
623     {
624       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
625       throw INTERP_KERNEL::Exception(oss.str().c_str());
626     }
627   if(sliceId<0 || sliceId>=nbOfSlices)
628     {
629       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
630       throw INTERP_KERNEL::Exception(oss.str().c_str());
631     }
632   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
633   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
634   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
635   if(sliceId<nbOfSlices-1)
636     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
637   else
638     stopSlice=stop;
639 }
640
641 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
642 {
643   if(end<begin)
644     {
645       std::ostringstream oss; oss << msg << " : end before begin !";
646       throw INTERP_KERNEL::Exception(oss.str().c_str());
647     }
648   if(end==begin)
649     return 0;
650   if(step<=0)
651     {
652       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
653       throw INTERP_KERNEL::Exception(oss.str().c_str());
654     }
655   return (end-1-begin)/step+1;
656 }
657
658 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
659 {
660   if(step==0)
661     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
662   if(end<begin && step>0)
663     {
664       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
665       throw INTERP_KERNEL::Exception(oss.str().c_str());
666     }
667   if(begin<end && step<0)
668     {
669       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
670       throw INTERP_KERNEL::Exception(oss.str().c_str());
671     }
672   if(begin!=end)
673     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
674   else
675     return 0;
676 }
677
678 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
679 {
680   if(step!=0)
681     {
682       if(step>0)
683         {
684           if(begin<=value && value<end)
685             {
686               if((value-begin)%step==0)
687                 return (value-begin)/step;
688               else
689                 return -1;
690             }
691           else
692             return -1;
693         }
694       else
695         {
696           if(begin>=value && value>end)
697             {
698               if((begin-value)%(-step)==0)
699                 return (begin-value)/(-step);
700               else
701                 return -1;
702             }
703           else
704             return -1;
705         }
706     }
707   else
708     return -1;
709 }
710
711 /*!
712  * Returns a new instance of DataArrayDouble. The caller is to delete this array
713  * using decrRef() as it is no more needed. 
714  */
715 DataArrayDouble *DataArrayDouble::New()
716 {
717   return new DataArrayDouble;
718 }
719
720 /*!
721  * Checks if raw data is allocated. Read more on the raw data
722  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
723  *  \return bool - \a true if the raw data is allocated, \a false else.
724  */
725 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
726 {
727   return getConstPointer()!=0;
728 }
729
730 /*!
731  * Checks if raw data is allocated and throws an exception if it is not the case.
732  *  \throw If the raw data is not allocated.
733  */
734 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
735 {
736   if(!isAllocated())
737     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
738 }
739
740 /*!
741  * This method desallocated \a this without modification of informations relative to the components.
742  * After call of this method, DataArrayDouble::isAllocated will return false.
743  * If \a this is already not allocated, \a this is let unchanged.
744  */
745 void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
746 {
747   _mem.destroy();
748 }
749
750 std::size_t DataArrayDouble::getHeapMemorySize() const
751 {
752   std::size_t sz=_mem.getNbOfElemAllocated();
753   sz*=sizeof(double);
754   return DataArray::getHeapMemorySize()+sz;
755 }
756
757 /*!
758  * Returns the only one value in \a this, if and only if number of elements
759  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
760  *  \return double - the sole value stored in \a this array.
761  *  \throw If at least one of conditions stated above is not fulfilled.
762  */
763 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
764 {
765   if(isAllocated())
766     {
767       if(getNbOfElems()==1)
768         {
769           return *getConstPointer();
770         }
771       else
772         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
773     }
774   else
775     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
776 }
777
778 /*!
779  * Checks the number of tuples.
780  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
781  *  \throw If \a this is not allocated.
782  */
783 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
784 {
785   checkAllocated();
786   return getNumberOfTuples()==0;
787 }
788
789 /*!
790  * Returns a full copy of \a this. For more info on copying data arrays see
791  * \ref MEDCouplingArrayBasicsCopyDeep.
792  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
793  *          delete this array using decrRef() as it is no more needed. 
794  */
795 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
796 {
797   return new DataArrayDouble(*this);
798 }
799
800 /*!
801  * Returns either a \a deep or \a shallow copy of this array. For more info see
802  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
803  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
804  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
805  *          == \a true) or \a this instance (if \a dCpy == \a false).
806  */
807 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
808 {
809   if(dCpy)
810     return deepCpy();
811   else
812     {
813       incrRef();
814       return const_cast<DataArrayDouble *>(this);
815     }
816 }
817
818 /*!
819  * Copies all the data from another DataArrayDouble. For more info see
820  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
821  *  \param [in] other - another instance of DataArrayDouble to copy data from.
822  *  \throw If the \a other is not allocated.
823  */
824 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
825 {
826   other.checkAllocated();
827   int nbOfTuples=other.getNumberOfTuples();
828   int nbOfComp=other.getNumberOfComponents();
829   allocIfNecessary(nbOfTuples,nbOfComp);
830   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
831   double *pt=getPointer();
832   const double *ptI=other.getConstPointer();
833   for(std::size_t i=0;i<nbOfElems;i++)
834     pt[i]=ptI[i];
835   copyStringInfoFrom(other);
836 }
837
838 /*!
839  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
840  * 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.
841  * If \a this has not already been allocated, number of components is set to one.
842  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
843  * 
844  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
845  */
846 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
847 {
848   int nbCompo=getNumberOfComponents();
849   if(nbCompo==1)
850     {
851       _mem.reserve(nbOfElems);
852     }
853   else if(nbCompo==0)
854     {
855       _mem.reserve(nbOfElems);
856       _info_on_compo.resize(1);
857     }
858   else
859     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
860 }
861
862 /*!
863  * 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
864  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
865  *
866  * \param [in] val the value to be added in \a this
867  * \throw If \a this has already been allocated with number of components different from one.
868  * \sa DataArrayDouble::pushBackValsSilent
869  */
870 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
871 {
872   int nbCompo=getNumberOfComponents();
873   if(nbCompo==1)
874     _mem.pushBack(val);
875   else if(nbCompo==0)
876     {
877       _info_on_compo.resize(1);
878       _mem.pushBack(val);
879     }
880   else
881     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
882 }
883
884 /*!
885  * 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
886  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
887  *
888  *  \param [in] valsBg - an array of values to push at the end of \this.
889  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
890  *              the last value of \a valsBg is \a valsEnd[ -1 ].
891  * \throw If \a this has already been allocated with number of components different from one.
892  * \sa DataArrayDouble::pushBackSilent
893  */
894 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
895 {
896   int nbCompo=getNumberOfComponents();
897   if(nbCompo==1)
898     _mem.insertAtTheEnd(valsBg,valsEnd);
899   else if(nbCompo==0)
900     {
901       _info_on_compo.resize(1);
902       _mem.insertAtTheEnd(valsBg,valsEnd);
903     }
904   else
905     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
906 }
907
908 /*!
909  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
910  * \throw If \a this is already empty.
911  * \throw If \a this has number of components different from one.
912  */
913 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
914 {
915   if(getNumberOfComponents()==1)
916     return _mem.popBack();
917   else
918     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
919 }
920
921 /*!
922  * 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.
923  *
924  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
925  */
926 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
927 {
928   _mem.pack();
929 }
930
931 /*!
932  * Allocates the raw data in memory. If exactly same memory as needed already
933  * allocated, it is not re-allocated.
934  *  \param [in] nbOfTuple - number of tuples of data to allocate.
935  *  \param [in] nbOfCompo - number of components of data to allocate.
936  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
937  */
938 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
939 {
940   if(isAllocated())
941     {
942       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
943         alloc(nbOfTuple,nbOfCompo);
944     }
945   else
946     alloc(nbOfTuple,nbOfCompo);
947 }
948
949 /*!
950  * Allocates the raw data in memory. If the memory was already allocated, then it is
951  * freed and re-allocated. See an example of this method use
952  * \ref MEDCouplingArraySteps1WC "here".
953  *  \param [in] nbOfTuple - number of tuples of data to allocate.
954  *  \param [in] nbOfCompo - number of components of data to allocate.
955  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
956  */
957 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
958 {
959   if(nbOfTuple<0 || nbOfCompo<0)
960     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
961   _info_on_compo.resize(nbOfCompo);
962   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
963   declareAsNew();
964 }
965
966 /*!
967  * Assign zero to all values in \a this array. To know more on filling arrays see
968  * \ref MEDCouplingArrayFill.
969  * \throw If \a this is not allocated.
970  */
971 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
972 {
973   checkAllocated();
974   _mem.fillWithValue(0.);
975   declareAsNew();
976 }
977
978 /*!
979  * Assign \a val to all values in \a this array. To know more on filling arrays see
980  * \ref MEDCouplingArrayFill.
981  *  \param [in] val - the value to fill with.
982  *  \throw If \a this is not allocated.
983  */
984 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
985 {
986   checkAllocated();
987   _mem.fillWithValue(val);
988   declareAsNew();
989 }
990
991 /*!
992  * Set all values in \a this array so that the i-th element equals to \a init + i
993  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
994  *  \param [in] init - value to assign to the first element of array.
995  *  \throw If \a this->getNumberOfComponents() != 1
996  *  \throw If \a this is not allocated.
997  */
998 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
999 {
1000   checkAllocated();
1001   if(getNumberOfComponents()!=1)
1002     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1003   double *ptr=getPointer();
1004   int ntuples=getNumberOfTuples();
1005   for(int i=0;i<ntuples;i++)
1006     ptr[i]=init+double(i);
1007   declareAsNew();
1008 }
1009
1010 /*!
1011  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1012  *  \param [in] val - value to check equality of array values to.
1013  *  \param [in] eps - precision to check the equality.
1014  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1015  *                 \a false else.
1016  *  \throw If \a this->getNumberOfComponents() != 1
1017  *  \throw If \a this is not allocated.
1018  */
1019 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
1020 {
1021   checkAllocated();
1022   if(getNumberOfComponents()!=1)
1023     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1024   int nbOfTuples=getNumberOfTuples();
1025   const double *w=getConstPointer();
1026   const double *end2=w+nbOfTuples;
1027   const double vmin=val-eps;
1028   const double vmax=val+eps;
1029   for(;w!=end2;w++)
1030     if(*w<vmin || *w>vmax)
1031       return false;
1032   return true;
1033 }
1034
1035 /*!
1036  * Sorts values of the array.
1037  *  \param [in] asc - \a true means ascending order, \a false, descending.
1038  *  \throw If \a this is not allocated.
1039  *  \throw If \a this->getNumberOfComponents() != 1.
1040  */
1041 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
1042 {
1043   checkAllocated();
1044   if(getNumberOfComponents()!=1)
1045     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1046   _mem.sort(asc);
1047   declareAsNew();
1048 }
1049
1050 /*!
1051  * Reverse the array values.
1052  *  \throw If \a this->getNumberOfComponents() < 1.
1053  *  \throw If \a this is not allocated.
1054  */
1055 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
1056 {
1057   checkAllocated();
1058   _mem.reverse(getNumberOfComponents());
1059   declareAsNew();
1060 }
1061
1062 /*!
1063  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1064  * with at least absolute difference value of |\a eps| at each step.
1065  * If not an exception is thrown.
1066  *  \param [in] increasing - if \a true, the array values should be increasing.
1067  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1068  *                    the values are considered different.
1069  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1070  *         increasing arg.
1071  *  \throw If \a this->getNumberOfComponents() != 1.
1072  *  \throw If \a this is not allocated.
1073  */
1074 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1075 {
1076   if(!isMonotonic(increasing,eps))
1077     {
1078       if (increasing)
1079         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1080       else
1081         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1082     }
1083 }
1084
1085 /*!
1086  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1087  * with at least absolute difference value of |\a eps| at each step.
1088  *  \param [in] increasing - if \a true, array values should be increasing.
1089  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1090  *                    the values are considered different.
1091  *  \return bool - \a true if values change in accordance with \a increasing arg.
1092  *  \throw If \a this->getNumberOfComponents() != 1.
1093  *  \throw If \a this is not allocated.
1094  */
1095 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1096 {
1097   checkAllocated();
1098   if(getNumberOfComponents()!=1)
1099     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1100   int nbOfElements=getNumberOfTuples();
1101   const double *ptr=getConstPointer();
1102   if(nbOfElements==0)
1103     return true;
1104   double ref=ptr[0];
1105   double absEps=fabs(eps);
1106   if(increasing)
1107     {
1108       for(int i=1;i<nbOfElements;i++)
1109         {
1110           if(ptr[i]<(ref+absEps))
1111             return false;
1112           ref=ptr[i];
1113         }
1114       return true;
1115     }
1116   else
1117     {
1118       for(int i=1;i<nbOfElements;i++)
1119         {
1120           if(ptr[i]>(ref-absEps))
1121             return false;
1122           ref=ptr[i];
1123         }
1124       return true;
1125     }
1126 }
1127
1128 /*!
1129  * Returns a textual and human readable representation of \a this instance of
1130  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1131  *  \return std::string - text describing \a this DataArrayDouble.
1132  */
1133 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1134 {
1135   std::ostringstream ret;
1136   reprStream(ret);
1137   return ret.str();
1138 }
1139
1140 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1141 {
1142   std::ostringstream ret;
1143   reprZipStream(ret);
1144   return ret.str();
1145 }
1146
1147 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1148 {
1149   std::string idt(indent,' ');
1150   ofs.precision(17);
1151   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1152   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1153   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1154   ofs << std::endl << idt << "</DataArray>\n";
1155 }
1156
1157 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1158 {
1159   stream << "Name of double array : \"" << _name << "\"\n";
1160   reprWithoutNameStream(stream);
1161 }
1162
1163 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1164 {
1165   stream << "Name of double array : \"" << _name << "\"\n";
1166   reprZipWithoutNameStream(stream);
1167 }
1168
1169 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1170 {
1171   DataArray::reprWithoutNameStream(stream);
1172   stream.precision(17);
1173   _mem.repr(getNumberOfComponents(),stream);
1174 }
1175
1176 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1177 {
1178   DataArray::reprWithoutNameStream(stream);
1179   stream.precision(17);
1180   _mem.reprZip(getNumberOfComponents(),stream);
1181 }
1182
1183 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1184 {
1185   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1186   const double *data=getConstPointer();
1187   stream.precision(17);
1188   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1189   if(nbTuples*nbComp>=1)
1190     {
1191       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1192       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1193       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1194       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1195     }
1196   else
1197     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1198   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1199 }
1200
1201 /*!
1202  * Method that gives a quick overvien of \a this for python.
1203  */
1204 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1205 {
1206   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1207   stream << "DataArrayDouble C++ instance at " << this << ". ";
1208   if(isAllocated())
1209     {
1210       int nbOfCompo=(int)_info_on_compo.size();
1211       if(nbOfCompo>=1)
1212         {
1213           int nbOfTuples=getNumberOfTuples();
1214           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1215           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1216         }
1217       else
1218         stream << "Number of components : 0.";
1219     }
1220   else
1221     stream << "*** No data allocated ****";
1222 }
1223
1224 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1225 {
1226   const double *data=begin();
1227   int nbOfTuples=getNumberOfTuples();
1228   int nbOfCompo=(int)_info_on_compo.size();
1229   std::ostringstream oss2; oss2 << "[";
1230   oss2.precision(17);
1231   std::string oss2Str(oss2.str());
1232   bool isFinished=true;
1233   for(int i=0;i<nbOfTuples && isFinished;i++)
1234     {
1235       if(nbOfCompo>1)
1236         {
1237           oss2 << "(";
1238           for(int j=0;j<nbOfCompo;j++,data++)
1239             {
1240               oss2 << *data;
1241               if(j!=nbOfCompo-1) oss2 << ", ";
1242             }
1243           oss2 << ")";
1244         }
1245       else
1246         oss2 << *data++;
1247       if(i!=nbOfTuples-1) oss2 << ", ";
1248       std::string oss3Str(oss2.str());
1249       if(oss3Str.length()<maxNbOfByteInRepr)
1250         oss2Str=oss3Str;
1251       else
1252         isFinished=false;
1253     }
1254   stream << oss2Str;
1255   if(!isFinished)
1256     stream << "... ";
1257   stream << "]";
1258 }
1259
1260 /*!
1261  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1262  * mismatch is given.
1263  * 
1264  * \param [in] other the instance to be compared with \a this
1265  * \param [in] prec the precision to compare numeric data of the arrays.
1266  * \param [out] reason In case of inequality returns the reason.
1267  * \sa DataArrayDouble::isEqual
1268  */
1269 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1270 {
1271   if(!areInfoEqualsIfNotWhy(other,reason))
1272     return false;
1273   return _mem.isEqual(other._mem,prec,reason);
1274 }
1275
1276 /*!
1277  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1278  * \ref MEDCouplingArrayBasicsCompare.
1279  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1280  *  \param [in] prec - precision value to compare numeric data of the arrays.
1281  *  \return bool - \a true if the two arrays are equal, \a false else.
1282  */
1283 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1284 {
1285   std::string tmp;
1286   return isEqualIfNotWhy(other,prec,tmp);
1287 }
1288
1289 /*!
1290  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1291  * \ref MEDCouplingArrayBasicsCompare.
1292  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1293  *  \param [in] prec - precision value to compare numeric data of the arrays.
1294  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1295  */
1296 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1297 {
1298   std::string tmp;
1299   return _mem.isEqual(other._mem,prec,tmp);
1300 }
1301
1302 /*!
1303  * Changes number of tuples in the array. If the new number of tuples is smaller
1304  * than the current number the array is truncated, otherwise the array is extended.
1305  *  \param [in] nbOfTuples - new number of tuples. 
1306  *  \throw If \a this is not allocated.
1307  *  \throw If \a nbOfTuples is negative.
1308  */
1309 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1310 {
1311   if(nbOfTuples<0)
1312     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1313   checkAllocated();
1314   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1315   declareAsNew();
1316 }
1317
1318 /*!
1319  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1320  * array to the new one.
1321  *  \return DataArrayInt * - the new instance of DataArrayInt.
1322  */
1323 DataArrayInt *DataArrayDouble::convertToIntArr() const
1324 {
1325   DataArrayInt *ret=DataArrayInt::New();
1326   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1327   std::size_t nbOfVals=getNbOfElems();
1328   const double *src=getConstPointer();
1329   int *dest=ret->getPointer();
1330   std::copy(src,src+nbOfVals,dest);
1331   ret->copyStringInfoFrom(*this);
1332   return ret;
1333 }
1334
1335 /*!
1336  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1337  * arranged in memory. If \a this array holds 2 components of 3 values:
1338  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1339  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1340  *  \warning Do not confuse this method with transpose()!
1341  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1342  *          is to delete using decrRef() as it is no more needed.
1343  *  \throw If \a this is not allocated.
1344  */
1345 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1346 {
1347   if(_mem.isNull())
1348     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1349   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1350   DataArrayDouble *ret=DataArrayDouble::New();
1351   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1352   return ret;
1353 }
1354
1355 /*!
1356  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1357  * arranged in memory. If \a this array holds 2 components of 3 values:
1358  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1359  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1360  *  \warning Do not confuse this method with transpose()!
1361  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1362  *          is to delete using decrRef() as it is no more needed.
1363  *  \throw If \a this is not allocated.
1364  */
1365 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1366 {
1367   if(_mem.isNull())
1368     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1369   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1370   DataArrayDouble *ret=DataArrayDouble::New();
1371   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1372   return ret;
1373 }
1374
1375 /*!
1376  * Permutes values of \a this array as required by \a old2New array. The values are
1377  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1378  * the same as in \this one.
1379  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1380  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1381  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1382  *     giving a new position for i-th old value.
1383  */
1384 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1385 {
1386   checkAllocated();
1387   int nbTuples=getNumberOfTuples();
1388   int nbOfCompo=getNumberOfComponents();
1389   double *tmp=new double[nbTuples*nbOfCompo];
1390   const double *iptr=getConstPointer();
1391   for(int i=0;i<nbTuples;i++)
1392     {
1393       int v=old2New[i];
1394       if(v>=0 && v<nbTuples)
1395         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1396       else
1397         {
1398           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1399           throw INTERP_KERNEL::Exception(oss.str().c_str());
1400         }
1401     }
1402   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1403   delete [] tmp;
1404   declareAsNew();
1405 }
1406
1407 /*!
1408  * Permutes values of \a this array as required by \a new2Old array. The values are
1409  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1410  * the same as in \this one.
1411  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1412  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1413  *     giving a previous position of i-th new value.
1414  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1415  *          is to delete using decrRef() as it is no more needed.
1416  */
1417 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1418 {
1419   checkAllocated();
1420   int nbTuples=getNumberOfTuples();
1421   int nbOfCompo=getNumberOfComponents();
1422   double *tmp=new double[nbTuples*nbOfCompo];
1423   const double *iptr=getConstPointer();
1424   for(int i=0;i<nbTuples;i++)
1425     {
1426       int v=new2Old[i];
1427       if(v>=0 && v<nbTuples)
1428         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1429       else
1430         {
1431           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1432           throw INTERP_KERNEL::Exception(oss.str().c_str());
1433         }
1434     }
1435   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1436   delete [] tmp;
1437   declareAsNew();
1438 }
1439
1440 /*!
1441  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1442  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1443  * Number of tuples in the result array remains the same as in \this one.
1444  * If a permutation reduction is needed, renumberAndReduce() should be used.
1445  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1446  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1447  *          giving a new position for i-th old value.
1448  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1449  *          is to delete using decrRef() as it is no more needed.
1450  *  \throw If \a this is not allocated.
1451  */
1452 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1453 {
1454   checkAllocated();
1455   int nbTuples=getNumberOfTuples();
1456   int nbOfCompo=getNumberOfComponents();
1457   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1458   ret->alloc(nbTuples,nbOfCompo);
1459   ret->copyStringInfoFrom(*this);
1460   const double *iptr=getConstPointer();
1461   double *optr=ret->getPointer();
1462   for(int i=0;i<nbTuples;i++)
1463     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1464   ret->copyStringInfoFrom(*this);
1465   return ret.retn();
1466 }
1467
1468 /*!
1469  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1470  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1471  * tuples in the result array remains the same as in \this one.
1472  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1473  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1474  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1475  *     giving a previous position of i-th new value.
1476  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1477  *          is to delete using decrRef() as it is no more needed.
1478  */
1479 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1480 {
1481   checkAllocated();
1482   int nbTuples=getNumberOfTuples();
1483   int nbOfCompo=getNumberOfComponents();
1484   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1485   ret->alloc(nbTuples,nbOfCompo);
1486   ret->copyStringInfoFrom(*this);
1487   const double *iptr=getConstPointer();
1488   double *optr=ret->getPointer();
1489   for(int i=0;i<nbTuples;i++)
1490     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1491   ret->copyStringInfoFrom(*this);
1492   return ret.retn();
1493 }
1494
1495 /*!
1496  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1497  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1498  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1499  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1500  * \a old2New[ i ] is negative, is missing from the result array.
1501  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1502  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1503  *     giving a new position for i-th old tuple and giving negative position for
1504  *     for i-th old tuple that should be omitted.
1505  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1506  *          is to delete using decrRef() as it is no more needed.
1507  */
1508 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1509 {
1510   checkAllocated();
1511   int nbTuples=getNumberOfTuples();
1512   int nbOfCompo=getNumberOfComponents();
1513   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1514   ret->alloc(newNbOfTuple,nbOfCompo);
1515   const double *iptr=getConstPointer();
1516   double *optr=ret->getPointer();
1517   for(int i=0;i<nbTuples;i++)
1518     {
1519       int w=old2New[i];
1520       if(w>=0)
1521         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1522     }
1523   ret->copyStringInfoFrom(*this);
1524   return ret.retn();
1525 }
1526
1527 /*!
1528  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1529  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1530  * \a new2OldBg array.
1531  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1532  * This method is equivalent to renumberAndReduce() except that convention in input is
1533  * \c new2old and \b not \c old2new.
1534  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1535  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1536  *              tuple index in \a this array to fill the i-th tuple in the new array.
1537  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1538  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1539  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1540  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1541  *          is to delete using decrRef() as it is no more needed.
1542  */
1543 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1544 {
1545   checkAllocated();
1546   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1547   int nbComp=getNumberOfComponents();
1548   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1549   ret->copyStringInfoFrom(*this);
1550   double *pt=ret->getPointer();
1551   const double *srcPt=getConstPointer();
1552   int i=0;
1553   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1554     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1555   ret->copyStringInfoFrom(*this);
1556   return ret.retn();
1557 }
1558
1559 /*!
1560  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1561  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1562  * \a new2OldBg array.
1563  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1564  * This method is equivalent to renumberAndReduce() except that convention in input is
1565  * \c new2old and \b not \c old2new.
1566  * This method is equivalent to selectByTupleId() except that it prevents coping data
1567  * from behind the end of \a this array.
1568  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1569  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1570  *              tuple index in \a this array to fill the i-th tuple in the new array.
1571  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1572  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1573  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1574  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1575  *          is to delete using decrRef() as it is no more needed.
1576  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1577  */
1578 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1579 {
1580   checkAllocated();
1581   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1582   int nbComp=getNumberOfComponents();
1583   int oldNbOfTuples=getNumberOfTuples();
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     if(*w>=0 && *w<oldNbOfTuples)
1591       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1592     else
1593       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1594   ret->copyStringInfoFrom(*this);
1595   return ret.retn();
1596 }
1597
1598 /*!
1599  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1600  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1601  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1602  * command \c range( \a bg, \a end2, \a step ).
1603  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1604  * not constructed explicitly.
1605  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1606  *  \param [in] bg - index of the first tuple to copy from \a this array.
1607  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1608  *  \param [in] step - index increment to get index of the next tuple to copy.
1609  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1610  *          is to delete using decrRef() as it is no more needed.
1611  *  \sa DataArrayDouble::substr.
1612  */
1613 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1614 {
1615   checkAllocated();
1616   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1617   int nbComp=getNumberOfComponents();
1618   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1619   ret->alloc(newNbOfTuples,nbComp);
1620   double *pt=ret->getPointer();
1621   const double *srcPt=getConstPointer()+bg*nbComp;
1622   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1623     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1624   ret->copyStringInfoFrom(*this);
1625   return ret.retn();
1626 }
1627
1628 /*!
1629  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1630  * of tuples specified by \a ranges parameter.
1631  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1632  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1633  *              of tuples in [\c begin,\c end) format.
1634  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1635  *          is to delete using decrRef() as it is no more needed.
1636  *  \throw If \a end < \a begin.
1637  *  \throw If \a end > \a this->getNumberOfTuples().
1638  *  \throw If \a this is not allocated.
1639  */
1640 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1641 {
1642   checkAllocated();
1643   int nbOfComp=getNumberOfComponents();
1644   int nbOfTuplesThis=getNumberOfTuples();
1645   if(ranges.empty())
1646     {
1647       DataArrayDouble *ret=DataArrayDouble::New();
1648       ret->alloc(0,nbOfComp);
1649       ret->copyStringInfoFrom(*this);
1650       return ret;
1651     }
1652   int ref=ranges.front().first;
1653   int nbOfTuples=0;
1654   bool isIncreasing=true;
1655   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1656     {
1657       if((*it).first<=(*it).second)
1658         {
1659           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1660             {
1661               nbOfTuples+=(*it).second-(*it).first;
1662               if(isIncreasing)
1663                 isIncreasing=ref<=(*it).first;
1664               ref=(*it).second;
1665             }
1666           else
1667             {
1668               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1669               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1670               throw INTERP_KERNEL::Exception(oss.str().c_str());
1671             }
1672         }
1673       else
1674         {
1675           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1676           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1677           throw INTERP_KERNEL::Exception(oss.str().c_str());
1678         }
1679     }
1680   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1681     return deepCpy();
1682   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1683   ret->alloc(nbOfTuples,nbOfComp);
1684   ret->copyStringInfoFrom(*this);
1685   const double *src=getConstPointer();
1686   double *work=ret->getPointer();
1687   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1688     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1689   return ret.retn();
1690 }
1691
1692 /*!
1693  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1694  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1695  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1696  * This method is a specialization of selectByTupleId2().
1697  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1698  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1699  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1700  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1701  *          is to delete using decrRef() as it is no more needed.
1702  *  \throw If \a tupleIdBg < 0.
1703  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1704     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1705  *  \sa DataArrayDouble::selectByTupleId2
1706  */
1707 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1708 {
1709   checkAllocated();
1710   int nbt=getNumberOfTuples();
1711   if(tupleIdBg<0)
1712     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1713   if(tupleIdBg>nbt)
1714     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1715   int trueEnd=tupleIdEnd;
1716   if(tupleIdEnd!=-1)
1717     {
1718       if(tupleIdEnd>nbt)
1719         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1720     }
1721   else
1722     trueEnd=nbt;
1723   int nbComp=getNumberOfComponents();
1724   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1725   ret->alloc(trueEnd-tupleIdBg,nbComp);
1726   ret->copyStringInfoFrom(*this);
1727   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1728   return ret.retn();
1729 }
1730
1731 /*!
1732  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1733  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1734  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1735  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1736  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1737  * components.  
1738  *  \param [in] newNbOfComp - number of components for the new array to have.
1739  *  \param [in] dftValue - value assigned to new values added to the new array.
1740  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1741  *          is to delete using decrRef() as it is no more needed.
1742  *  \throw If \a this is not allocated.
1743  */
1744 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1745 {
1746   checkAllocated();
1747   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1748   ret->alloc(getNumberOfTuples(),newNbOfComp);
1749   const double *oldc=getConstPointer();
1750   double *nc=ret->getPointer();
1751   int nbOfTuples=getNumberOfTuples();
1752   int oldNbOfComp=getNumberOfComponents();
1753   int dim=std::min(oldNbOfComp,newNbOfComp);
1754   for(int i=0;i<nbOfTuples;i++)
1755     {
1756       int j=0;
1757       for(;j<dim;j++)
1758         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1759       for(;j<newNbOfComp;j++)
1760         nc[newNbOfComp*i+j]=dftValue;
1761     }
1762   ret->setName(getName().c_str());
1763   for(int i=0;i<dim;i++)
1764     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1765   ret->setName(getName().c_str());
1766   return ret.retn();
1767 }
1768
1769 /*!
1770  * Changes the number of components within \a this array so that its raw data **does
1771  * not** change, instead splitting this data into tuples changes.
1772  *  \warning This method erases all (name and unit) component info set before!
1773  *  \param [in] newNbOfComp - number of components for \a this array to have.
1774  *  \throw If \a this is not allocated
1775  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1776  *  \throw If \a newNbOfCompo is lower than 1.
1777  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1778  *  \warning This method erases all (name and unit) component info set before!
1779  */
1780 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1781 {
1782   checkAllocated();
1783   if(newNbOfCompo<1)
1784     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1785   std::size_t nbOfElems=getNbOfElems();
1786   if(nbOfElems%newNbOfCompo!=0)
1787     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1788   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1789     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1790   _info_on_compo.clear();
1791   _info_on_compo.resize(newNbOfCompo);
1792   declareAsNew();
1793 }
1794
1795 /*!
1796  * Changes the number of components within \a this array to be equal to its number
1797  * of tuples, and inversely its number of tuples to become equal to its number of 
1798  * components. So that its raw data **does not** change, instead splitting this
1799  * data into tuples changes.
1800  *  \warning This method erases all (name and unit) component info set before!
1801  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1802  *  \throw If \a this is not allocated.
1803  *  \sa rearrange()
1804  */
1805 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1806 {
1807   checkAllocated();
1808   int nbOfTuples=getNumberOfTuples();
1809   rearrange(nbOfTuples);
1810 }
1811
1812 /*!
1813  * Returns a copy of \a this array composed of selected components.
1814  * The new DataArrayDouble has the same number of tuples but includes components
1815  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1816  * can be either less, same or more than \a this->getNbOfElems().
1817  *  \param [in] compoIds - sequence of zero based indices of components to include
1818  *              into the new array.
1819  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1820  *          is to delete using decrRef() as it is no more needed.
1821  *  \throw If \a this is not allocated.
1822  *  \throw If a component index (\a i) is not valid: 
1823  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1824  *
1825  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1826  */
1827 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1828 {
1829   checkAllocated();
1830   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1831   std::size_t newNbOfCompo=compoIds.size();
1832   int oldNbOfCompo=getNumberOfComponents();
1833   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1834     if((*it)<0 || (*it)>=oldNbOfCompo)
1835       {
1836         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1837         throw INTERP_KERNEL::Exception(oss.str().c_str());
1838       }
1839   int nbOfTuples=getNumberOfTuples();
1840   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1841   ret->copyPartOfStringInfoFrom(*this,compoIds);
1842   const double *oldc=getConstPointer();
1843   double *nc=ret->getPointer();
1844   for(int i=0;i<nbOfTuples;i++)
1845     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1846       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1847   return ret.retn();
1848 }
1849
1850 /*!
1851  * Appends components of another array to components of \a this one, tuple by tuple.
1852  * So that the number of tuples of \a this array remains the same and the number of 
1853  * components increases.
1854  *  \param [in] other - the DataArrayDouble to append to \a this one.
1855  *  \throw If \a this is not allocated.
1856  *  \throw If \a this and \a other arrays have different number of tuples.
1857  *
1858  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1859  *
1860  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1861  */
1862 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1863 {
1864   checkAllocated();
1865   other->checkAllocated();
1866   int nbOfTuples=getNumberOfTuples();
1867   if(nbOfTuples!=other->getNumberOfTuples())
1868     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1869   int nbOfComp1=getNumberOfComponents();
1870   int nbOfComp2=other->getNumberOfComponents();
1871   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1872   double *w=newArr;
1873   const double *inp1=getConstPointer();
1874   const double *inp2=other->getConstPointer();
1875   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1876     {
1877       w=std::copy(inp1,inp1+nbOfComp1,w);
1878       w=std::copy(inp2,inp2+nbOfComp2,w);
1879     }
1880   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1881   std::vector<int> compIds(nbOfComp2);
1882   for(int i=0;i<nbOfComp2;i++)
1883     compIds[i]=nbOfComp1+i;
1884   copyPartOfStringInfoFrom2(compIds,*other);
1885 }
1886
1887 /*!
1888  * This method checks that all tuples in \a other are in \a this.
1889  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1890  * 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.
1891  *
1892  * \param [in] other - the array having the same number of components than \a this.
1893  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1894  * \sa DataArrayDouble::findCommonTuples
1895  */
1896 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1897 {
1898   if(!other)
1899     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1900   checkAllocated(); other->checkAllocated();
1901   if(getNumberOfComponents()!=other->getNumberOfComponents())
1902     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1903   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1904   DataArrayInt *c=0,*ci=0;
1905   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1906   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1907   int newNbOfTuples=-1;
1908   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1909   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1910   tupleIds=ret1.retn();
1911   return newNbOfTuples==getNumberOfTuples();
1912 }
1913
1914 /*!
1915  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1916  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1917  * distance separating two points is computed with the infinite norm.
1918  *
1919  * Indices of coincident tuples are stored in output arrays.
1920  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1921  *
1922  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1923  * MEDCouplingUMesh::mergeNodes().
1924  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1925  *              considered not coincident.
1926  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1927  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1928  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1929  *               \a comm->getNumberOfComponents() == 1. 
1930  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1931  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1932  *               groups of (indices of) coincident tuples. Its every value is a tuple
1933  *               index where a next group of tuples begins. For example the second
1934  *               group of tuples in \a comm is described by following range of indices:
1935  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1936  *               gives the number of groups of coincident tuples.
1937  *  \throw If \a this is not allocated.
1938  *  \throw If the number of components is not in [1,2,3].
1939  *
1940  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1941  *
1942  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1943  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1944  */
1945 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1946 {
1947   checkAllocated();
1948   int nbOfCompo=getNumberOfComponents();
1949   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1950     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1951   
1952   int nbOfTuples=getNumberOfTuples();
1953   //
1954   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1955   switch(nbOfCompo)
1956     {
1957     case 3:
1958       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1959       break;
1960     case 2:
1961       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1962       break;
1963     case 1:
1964       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1965       break;
1966     default:
1967       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1968     }
1969   comm=c.retn();
1970   commIndex=cI.retn();
1971 }
1972
1973 /*!
1974  * 
1975  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1976  *             \a nbTimes  should be at least equal to 1.
1977  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1978  * \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.
1979  */
1980 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1981 {
1982   checkAllocated();
1983   if(getNumberOfComponents()!=1)
1984     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1985   if(nbTimes<1)
1986     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1987   int nbTuples=getNumberOfTuples();
1988   const double *inPtr=getConstPointer();
1989   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1990   double *retPtr=ret->getPointer();
1991   for(int i=0;i<nbTuples;i++,inPtr++)
1992     {
1993       double val=*inPtr;
1994       for(int j=0;j<nbTimes;j++,retPtr++)
1995         *retPtr=val;
1996     }
1997   ret->copyStringInfoFrom(*this);
1998   return ret.retn();
1999 }
2000
2001 /*!
2002  * This methods returns the minimal distance between the two set of points \a this and \a other.
2003  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2004  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2005  *
2006  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2007  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2008  * \return the minimal distance between the two set of points \a this and \a other.
2009  * \sa DataArrayDouble::findClosestTupleId
2010  */
2011 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
2012 {
2013   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2014   int nbOfCompo(getNumberOfComponents());
2015   int otherNbTuples(other->getNumberOfTuples());
2016   const double *thisPt(begin()),*otherPt(other->begin());
2017   const int *part1Pt(part1->begin());
2018   double ret=std::numeric_limits<double>::max();
2019   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2020     {
2021       double tmp(0.);
2022       for(int j=0;j<nbOfCompo;j++)
2023         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2024       if(tmp<ret)
2025         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2026     }
2027   return sqrt(ret);
2028 }
2029
2030 /*!
2031  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2032  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2033  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2034  *
2035  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2036  * \sa DataArrayDouble::minimalDistanceTo
2037  */
2038 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
2039 {
2040   if(!other)
2041     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2042   checkAllocated(); other->checkAllocated();
2043   int nbOfCompo=getNumberOfComponents();
2044   if(nbOfCompo!=other->getNumberOfComponents())
2045     {
2046       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2047       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2048       throw INTERP_KERNEL::Exception(oss.str().c_str());
2049     }
2050   int nbOfTuples=other->getNumberOfTuples();
2051   int thisNbOfTuples=getNumberOfTuples();
2052   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2053   double bounds[6];
2054   getMinMaxPerComponent(bounds);
2055   switch(nbOfCompo)
2056     {
2057     case 3:
2058       {
2059         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2060         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2061         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2062         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2063         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2064         break;
2065       }
2066     case 2:
2067       {
2068         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2069         double delta=std::max(xDelta,yDelta);
2070         double characSize=sqrt(delta/(double)thisNbOfTuples);
2071         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2072         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2073         break;
2074       }
2075     case 1:
2076       {
2077         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2078         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2079         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2080         break;
2081       }
2082     default:
2083       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2084     }
2085   return ret.retn();
2086 }
2087
2088 /*!
2089  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2090  * 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
2091  * how many bounding boxes in \a otherBBoxFrmt.
2092  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2093  *
2094  * \param [in] otherBBoxFrmt - It is an array .
2095  * \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.
2096  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2097  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2098  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2099  */
2100 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception)
2101 {
2102   if(!otherBBoxFrmt)
2103     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2104   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2105     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2106   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2107   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2108     {
2109       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2110       throw INTERP_KERNEL::Exception(oss.str().c_str());
2111     }
2112   if(nbOfComp%2!=0)
2113     {
2114       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2115       throw INTERP_KERNEL::Exception(oss.str().c_str());
2116     }
2117   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2118   const double *thisBBPtr(begin());
2119   int *retPtr(ret->getPointer());
2120   switch(nbOfComp/2)
2121     {
2122     case 3:
2123       {
2124         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2125         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2126           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2127         break;
2128       }
2129     case 2:
2130       {
2131         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2132         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2133           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2134         break;
2135       }
2136     case 1:
2137       {
2138         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2139         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2140           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2141         break;
2142       }
2143     defaut:
2144       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2145     }
2146   
2147   return ret.retn();
2148 }
2149
2150 /*!
2151  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2152  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2153  * space. The distance between tuples is computed using norm2. If several tuples are
2154  * not far each from other than \a prec, only one of them remains in the result
2155  * array. The order of tuples in the result array is same as in \a this one except
2156  * that coincident tuples are excluded.
2157  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2158  *              considered not coincident.
2159  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2160  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2161  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2162  *          is to delete using decrRef() as it is no more needed.
2163  *  \throw If \a this is not allocated.
2164  *  \throw If the number of components is not in [1,2,3].
2165  *
2166  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2167  */
2168 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2169 {
2170   checkAllocated();
2171   DataArrayInt *c0=0,*cI0=0;
2172   findCommonTuples(prec,limitTupleId,c0,cI0);
2173   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2174   int newNbOfTuples=-1;
2175   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2176   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2177 }
2178
2179 /*!
2180  * Copy all components in a specified order from another DataArrayDouble.
2181  * Both numerical and textual data is copied. The number of tuples in \a this and
2182  * the other array can be different.
2183  *  \param [in] a - the array to copy data from.
2184  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2185  *              to be copied.
2186  *  \throw If \a a is NULL.
2187  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2188  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2189  *
2190  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2191  */
2192 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2193 {
2194   if(!a)
2195     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2196   checkAllocated();
2197   copyPartOfStringInfoFrom2(compoIds,*a);
2198   std::size_t partOfCompoSz=compoIds.size();
2199   int nbOfCompo=getNumberOfComponents();
2200   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2201   const double *ac=a->getConstPointer();
2202   double *nc=getPointer();
2203   for(int i=0;i<nbOfTuples;i++)
2204     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2205       nc[nbOfCompo*i+compoIds[j]]=*ac;
2206 }
2207
2208 /*!
2209  * Copy all values from another DataArrayDouble into specified tuples and components
2210  * of \a this array. Textual data is not copied.
2211  * The tree parameters defining set of indices of tuples and components are similar to
2212  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2213  *  \param [in] a - the array to copy values from.
2214  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2215  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2216  *              are located.
2217  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2218  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2219  *  \param [in] endComp - index of the component before which the components to assign
2220  *              to are located.
2221  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2222  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2223  *              must be equal to the number of columns to assign to, else an
2224  *              exception is thrown; if \a false, then it is only required that \a
2225  *              a->getNbOfElems() equals to number of values to assign to (this condition
2226  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2227  *              values to assign to is given by following Python expression:
2228  *              \a nbTargetValues = 
2229  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2230  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2231  *  \throw If \a a is NULL.
2232  *  \throw If \a a is not allocated.
2233  *  \throw If \a this is not allocated.
2234  *  \throw If parameters specifying tuples and components to assign to do not give a
2235  *            non-empty range of increasing indices.
2236  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2237  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2238  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2239  *
2240  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2241  */
2242 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2243 {
2244   if(!a)
2245     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2246   const char msg[]="DataArrayDouble::setPartOfValues1";
2247   checkAllocated();
2248   a->checkAllocated();
2249   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2250   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2251   int nbComp=getNumberOfComponents();
2252   int nbOfTuples=getNumberOfTuples();
2253   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2254   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2255   bool assignTech=true;
2256   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2257     {
2258       if(strictCompoCompare)
2259         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2260     }
2261   else
2262     {
2263       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2264       assignTech=false;
2265     }
2266   const double *srcPt=a->getConstPointer();
2267   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2268   if(assignTech)
2269     {
2270       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2271         for(int j=0;j<newNbOfComp;j++,srcPt++)
2272           pt[j*stepComp]=*srcPt;
2273     }
2274   else
2275     {
2276       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2277         {
2278           const double *srcPt2=srcPt;
2279           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2280             pt[j*stepComp]=*srcPt2;
2281         }
2282     }
2283 }
2284
2285 /*!
2286  * Assign a given value to values at specified tuples and components of \a this array.
2287  * The tree parameters defining set of indices of tuples and components are similar to
2288  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2289  *  \param [in] a - the value to assign.
2290  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2291  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2292  *              are located.
2293  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2294  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2295  *  \param [in] endComp - index of the component before which the components to assign
2296  *              to are located.
2297  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2298  *  \throw If \a this is not allocated.
2299  *  \throw If parameters specifying tuples and components to assign to, do not give a
2300  *            non-empty range of increasing indices or indices are out of a valid range
2301  *            for \this array.
2302  *
2303  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2304  */
2305 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2306 {
2307   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2308   checkAllocated();
2309   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2310   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2311   int nbComp=getNumberOfComponents();
2312   int nbOfTuples=getNumberOfTuples();
2313   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2314   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2315   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2316   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2317     for(int j=0;j<newNbOfComp;j++)
2318       pt[j*stepComp]=a;
2319 }
2320
2321 /*!
2322  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2323  * components of \a this array. Textual data is not copied.
2324  * The tuples and components to assign to are defined by C arrays of indices.
2325  * There are two *modes of usage*:
2326  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2327  *   of \a a is assigned to its own location within \a this array. 
2328  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2329  *   components of every specified tuple of \a this array. In this mode it is required
2330  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2331  *
2332  *  \param [in] a - the array to copy values from.
2333  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2334  *              assign values of \a a to.
2335  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2336  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2337  *              \a bgTuples <= \a pi < \a endTuples.
2338  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2339  *              assign values of \a a to.
2340  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2341  *              pointer to a component index <em>(pi)</em> varies as this: 
2342  *              \a bgComp <= \a pi < \a endComp.
2343  *  \param [in] strictCompoCompare - this parameter is checked only if the
2344  *               *mode of usage* is the first; if it is \a true (default), 
2345  *               then \a a->getNumberOfComponents() must be equal 
2346  *               to the number of specified columns, else this is not required.
2347  *  \throw If \a a is NULL.
2348  *  \throw If \a a is not allocated.
2349  *  \throw If \a this is not allocated.
2350  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2351  *         out of a valid range for \a this array.
2352  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2353  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2354  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2355  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2356  *
2357  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2358  */
2359 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2360 {
2361   if(!a)
2362     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2363   const char msg[]="DataArrayDouble::setPartOfValues2";
2364   checkAllocated();
2365   a->checkAllocated();
2366   int nbComp=getNumberOfComponents();
2367   int nbOfTuples=getNumberOfTuples();
2368   for(const int *z=bgComp;z!=endComp;z++)
2369     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2370   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2371   int newNbOfComp=(int)std::distance(bgComp,endComp);
2372   bool assignTech=true;
2373   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2374     {
2375       if(strictCompoCompare)
2376         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2377     }
2378   else
2379     {
2380       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2381       assignTech=false;
2382     }
2383   double *pt=getPointer();
2384   const double *srcPt=a->getConstPointer();
2385   if(assignTech)
2386     {    
2387       for(const int *w=bgTuples;w!=endTuples;w++)
2388         {
2389           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2390           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2391             {    
2392               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2393             }
2394         }
2395     }
2396   else
2397     {
2398       for(const int *w=bgTuples;w!=endTuples;w++)
2399         {
2400           const double *srcPt2=srcPt;
2401           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2402           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2403             {    
2404               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2405             }
2406         }
2407     }
2408 }
2409
2410 /*!
2411  * Assign a given value to values at specified tuples and components of \a this array.
2412  * The tuples and components to assign to are defined by C arrays of indices.
2413  *  \param [in] a - the value to assign.
2414  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2415  *              assign \a a to.
2416  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2417  *              pointer to a tuple index (\a pi) varies as this: 
2418  *              \a bgTuples <= \a pi < \a endTuples.
2419  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2420  *              assign \a a to.
2421  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2422  *              pointer to a component index (\a pi) varies as this: 
2423  *              \a bgComp <= \a pi < \a endComp.
2424  *  \throw If \a this is not allocated.
2425  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2426  *         out of a valid range for \a this array.
2427  *
2428  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2429  */
2430 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2431 {
2432   checkAllocated();
2433   int nbComp=getNumberOfComponents();
2434   int nbOfTuples=getNumberOfTuples();
2435   for(const int *z=bgComp;z!=endComp;z++)
2436     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2437   double *pt=getPointer();
2438   for(const int *w=bgTuples;w!=endTuples;w++)
2439     for(const int *z=bgComp;z!=endComp;z++)
2440       {
2441         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2442         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2443       }
2444 }
2445
2446 /*!
2447  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2448  * components of \a this array. Textual data is not copied.
2449  * The tuples to assign to are defined by a C array of indices.
2450  * The components to assign to are defined by three values similar to parameters of
2451  * the Python function \c range(\c start,\c stop,\c step).
2452  * There are two *modes of usage*:
2453  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2454  *   of \a a is assigned to its own location within \a this array. 
2455  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2456  *   components of every specified tuple of \a this array. In this mode it is required
2457  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2458  *
2459  *  \param [in] a - the array to copy values from.
2460  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2461  *              assign values of \a a to.
2462  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2463  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2464  *              \a bgTuples <= \a pi < \a endTuples.
2465  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2466  *  \param [in] endComp - index of the component before which the components to assign
2467  *              to are located.
2468  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2469  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2470  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2471  *               then \a a->getNumberOfComponents() must be equal 
2472  *               to the number of specified columns, else this is not required.
2473  *  \throw If \a a is NULL.
2474  *  \throw If \a a is not allocated.
2475  *  \throw If \a this is not allocated.
2476  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2477  *         \a this array.
2478  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2479  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2480  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2481  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2482  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2483  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2484  *  \throw If parameters specifying components to assign to, do not give a
2485  *            non-empty range of increasing indices or indices are out of a valid range
2486  *            for \this array.
2487  *
2488  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2489  */
2490 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2491 {
2492   if(!a)
2493     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2494   const char msg[]="DataArrayDouble::setPartOfValues3";
2495   checkAllocated();
2496   a->checkAllocated();
2497   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2498   int nbComp=getNumberOfComponents();
2499   int nbOfTuples=getNumberOfTuples();
2500   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2501   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2502   bool assignTech=true;
2503   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2504     {
2505       if(strictCompoCompare)
2506         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2507     }
2508   else
2509     {
2510       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2511       assignTech=false;
2512     }
2513   double *pt=getPointer()+bgComp;
2514   const double *srcPt=a->getConstPointer();
2515   if(assignTech)
2516     {
2517       for(const int *w=bgTuples;w!=endTuples;w++)
2518         for(int j=0;j<newNbOfComp;j++,srcPt++)
2519           {
2520             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2521             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2522           }
2523     }
2524   else
2525     {
2526       for(const int *w=bgTuples;w!=endTuples;w++)
2527         {
2528           const double *srcPt2=srcPt;
2529           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2530             {
2531               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2532               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2533             }
2534         }
2535     }
2536 }
2537
2538 /*!
2539  * Assign a given value to values at specified tuples and components of \a this array.
2540  * The tuples to assign to are defined by a C array of indices.
2541  * The components to assign to are defined by three values similar to parameters of
2542  * the Python function \c range(\c start,\c stop,\c step).
2543  *  \param [in] a - the value to assign.
2544  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2545  *              assign \a a to.
2546  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2547  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2548  *              \a bgTuples <= \a pi < \a endTuples.
2549  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2550  *  \param [in] endComp - index of the component before which the components to assign
2551  *              to are located.
2552  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2553  *  \throw If \a this is not allocated.
2554  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2555  *         \a this array.
2556  *  \throw If parameters specifying components to assign to, do not give a
2557  *            non-empty range of increasing indices or indices are out of a valid range
2558  *            for \this array.
2559  *
2560  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2561  */
2562 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2563 {
2564   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2565   checkAllocated();
2566   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2567   int nbComp=getNumberOfComponents();
2568   int nbOfTuples=getNumberOfTuples();
2569   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2570   double *pt=getPointer()+bgComp;
2571   for(const int *w=bgTuples;w!=endTuples;w++)
2572     for(int j=0;j<newNbOfComp;j++)
2573       {
2574         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2575         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2576       }
2577 }
2578
2579 /*!
2580  * Copy all values from another DataArrayDouble into specified tuples and components
2581  * of \a this array. Textual data is not copied.
2582  * The tree parameters defining set of indices of tuples and components are similar to
2583  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2584  *  \param [in] a - the array to copy values from.
2585  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2586  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2587  *              are located.
2588  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2589  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2590  *              assign \a a to.
2591  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2592  *              pointer to a component index (\a pi) varies as this: 
2593  *              \a bgComp <= \a pi < \a endComp.
2594  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2595  *              must be equal to the number of columns to assign to, else an
2596  *              exception is thrown; if \a false, then it is only required that \a
2597  *              a->getNbOfElems() equals to number of values to assign to (this condition
2598  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2599  *              values to assign to is given by following Python expression:
2600  *              \a nbTargetValues = 
2601  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2602  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2603  *  \throw If \a a is NULL.
2604  *  \throw If \a a is not allocated.
2605  *  \throw If \a this is not allocated.
2606  *  \throw If parameters specifying tuples and components to assign to do not give a
2607  *            non-empty range of increasing indices.
2608  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2609  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2610  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2611  *
2612  */
2613 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2614 {
2615   if(!a)
2616     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2617   const char msg[]="DataArrayDouble::setPartOfValues4";
2618   checkAllocated();
2619   a->checkAllocated();
2620   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2621   int newNbOfComp=(int)std::distance(bgComp,endComp);
2622   int nbComp=getNumberOfComponents();
2623   for(const int *z=bgComp;z!=endComp;z++)
2624     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2625   int nbOfTuples=getNumberOfTuples();
2626   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2627   bool assignTech=true;
2628   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2629     {
2630       if(strictCompoCompare)
2631         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2632     }
2633   else
2634     {
2635       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2636       assignTech=false;
2637     }
2638   const double *srcPt=a->getConstPointer();
2639   double *pt=getPointer()+bgTuples*nbComp;
2640   if(assignTech)
2641     {
2642       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2643         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2644           pt[*z]=*srcPt;
2645     }
2646   else
2647     {
2648       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2649         {
2650           const double *srcPt2=srcPt;
2651           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2652             pt[*z]=*srcPt2;
2653         }
2654     }
2655 }
2656
2657 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2658 {
2659   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2660   checkAllocated();
2661   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2662   int nbComp=getNumberOfComponents();
2663   for(const int *z=bgComp;z!=endComp;z++)
2664     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2665   int nbOfTuples=getNumberOfTuples();
2666   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2667   double *pt=getPointer()+bgTuples*nbComp;
2668   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2669     for(const int *z=bgComp;z!=endComp;z++)
2670       pt[*z]=a;
2671 }
2672
2673 /*!
2674  * Copy some tuples from another DataArrayDouble into specified tuples
2675  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2676  * components.
2677  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2678  * All components of selected tuples are copied.
2679  *  \param [in] a - the array to copy values from.
2680  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2681  *              target tuples of \a this. \a tuplesSelec has two components, and the
2682  *              first component specifies index of the source tuple and the second
2683  *              one specifies index of the target tuple.
2684  *  \throw If \a this is not allocated.
2685  *  \throw If \a a is NULL.
2686  *  \throw If \a a is not allocated.
2687  *  \throw If \a tuplesSelec is NULL.
2688  *  \throw If \a tuplesSelec is not allocated.
2689  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2690  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2691  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2692  *         the corresponding (\a this or \a a) array.
2693  */
2694 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2695 {
2696   if(!a || !tuplesSelec)
2697     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2698   checkAllocated();
2699   a->checkAllocated();
2700   tuplesSelec->checkAllocated();
2701   int nbOfComp=getNumberOfComponents();
2702   if(nbOfComp!=a->getNumberOfComponents())
2703     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2704   if(tuplesSelec->getNumberOfComponents()!=2)
2705     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2706   int thisNt=getNumberOfTuples();
2707   int aNt=a->getNumberOfTuples();
2708   double *valsToSet=getPointer();
2709   const double *valsSrc=a->getConstPointer();
2710   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2711     {
2712       if(tuple[1]>=0 && tuple[1]<aNt)
2713         {
2714           if(tuple[0]>=0 && tuple[0]<thisNt)
2715             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2716           else
2717             {
2718               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2719               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2720               throw INTERP_KERNEL::Exception(oss.str().c_str());
2721             }
2722         }
2723       else
2724         {
2725           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2726           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2727           throw INTERP_KERNEL::Exception(oss.str().c_str());
2728         }
2729     }
2730 }
2731
2732 /*!
2733  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2734  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2735  * components.
2736  * The tuples to assign to are defined by index of the first tuple, and
2737  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2738  * The tuples to copy are defined by values of a DataArrayInt.
2739  * All components of selected tuples are copied.
2740  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2741  *              values to.
2742  *  \param [in] aBase - the array to copy values from.
2743  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2744  *  \throw If \a this is not allocated.
2745  *  \throw If \a aBase is NULL.
2746  *  \throw If \a aBase is not allocated.
2747  *  \throw If \a tuplesSelec is NULL.
2748  *  \throw If \a tuplesSelec is not allocated.
2749  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2750  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2751  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2752  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2753  *         \a aBase array.
2754  */
2755 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2756 {
2757   if(!aBase || !tuplesSelec)
2758     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2759   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2760   if(!a)
2761     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2762   checkAllocated();
2763   a->checkAllocated();
2764   tuplesSelec->checkAllocated();
2765   int nbOfComp=getNumberOfComponents();
2766   if(nbOfComp!=a->getNumberOfComponents())
2767     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2768   if(tuplesSelec->getNumberOfComponents()!=1)
2769     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2770   int thisNt=getNumberOfTuples();
2771   int aNt=a->getNumberOfTuples();
2772   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2773   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2774   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2775     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2776   const double *valsSrc=a->getConstPointer();
2777   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2778     {
2779       if(*tuple>=0 && *tuple<aNt)
2780         {
2781           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2782         }
2783       else
2784         {
2785           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2786           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2787           throw INTERP_KERNEL::Exception(oss.str().c_str());
2788         }
2789     }
2790 }
2791
2792 /*!
2793  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2794  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2795  * components.
2796  * The tuples to copy are defined by three values similar to parameters of
2797  * the Python function \c range(\c start,\c stop,\c step).
2798  * The tuples to assign to are defined by index of the first tuple, and
2799  * their number is defined by number of tuples to copy.
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] bg - index of the first tuple to copy of the array \a aBase.
2805  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2806  *              are located.
2807  *  \param [in] step - index increment to get index of the next tuple to copy.
2808  *  \throw If \a this is not allocated.
2809  *  \throw If \a aBase is NULL.
2810  *  \throw If \a aBase is not allocated.
2811  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2812  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2813  *  \throw If parameters specifying tuples to copy, do not give a
2814  *            non-empty range of increasing indices or indices are out of a valid range
2815  *            for the array \a aBase.
2816  */
2817 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2818 {
2819   if(!aBase)
2820     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2821   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2822   if(!a)
2823     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2824   checkAllocated();
2825   a->checkAllocated();
2826   int nbOfComp=getNumberOfComponents();
2827   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2828   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2829   if(nbOfComp!=a->getNumberOfComponents())
2830     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2831   int thisNt=getNumberOfTuples();
2832   int aNt=a->getNumberOfTuples();
2833   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2834   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2835     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2836   if(end2>aNt)
2837     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2838   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2839   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2840     {
2841       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2842     }
2843 }
2844
2845 /*!
2846  * Returns a value located at specified tuple and component.
2847  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2848  * parameters is checked. So this method is safe but expensive if used to go through
2849  * all values of \a this.
2850  *  \param [in] tupleId - index of tuple of interest.
2851  *  \param [in] compoId - index of component of interest.
2852  *  \return double - value located by \a tupleId and \a compoId.
2853  *  \throw If \a this is not allocated.
2854  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2855  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2856  */
2857 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2858 {
2859   checkAllocated();
2860   if(tupleId<0 || tupleId>=getNumberOfTuples())
2861     {
2862       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2863       throw INTERP_KERNEL::Exception(oss.str().c_str());
2864     }
2865   if(compoId<0 || compoId>=getNumberOfComponents())
2866     {
2867       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2868       throw INTERP_KERNEL::Exception(oss.str().c_str());
2869     }
2870   return _mem[tupleId*_info_on_compo.size()+compoId];
2871 }
2872
2873 /*!
2874  * Returns the first value of \a this. 
2875  *  \return double - the last value of \a this array.
2876  *  \throw If \a this is not allocated.
2877  *  \throw If \a this->getNumberOfComponents() != 1.
2878  *  \throw If \a this->getNumberOfTuples() < 1.
2879  */
2880 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2881 {
2882   checkAllocated();
2883   if(getNumberOfComponents()!=1)
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2885   int nbOfTuples=getNumberOfTuples();
2886   if(nbOfTuples<1)
2887     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2888   return *(getConstPointer());
2889 }
2890
2891 /*!
2892  * Returns the last value of \a this. 
2893  *  \return double - the last value of \a this array.
2894  *  \throw If \a this is not allocated.
2895  *  \throw If \a this->getNumberOfComponents() != 1.
2896  *  \throw If \a this->getNumberOfTuples() < 1.
2897  */
2898 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2899 {
2900   checkAllocated();
2901   if(getNumberOfComponents()!=1)
2902     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2903   int nbOfTuples=getNumberOfTuples();
2904   if(nbOfTuples<1)
2905     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2906   return *(getConstPointer()+nbOfTuples-1);
2907 }
2908
2909 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2910 {
2911   if(newArray!=arrayToSet)
2912     {
2913       if(arrayToSet)
2914         arrayToSet->decrRef();
2915       arrayToSet=newArray;
2916       if(arrayToSet)
2917         arrayToSet->incrRef();
2918     }
2919 }
2920
2921 /*!
2922  * Sets a C array to be used as raw data of \a this. The previously set info
2923  *  of components is retained and re-sized. 
2924  * For more info see \ref MEDCouplingArraySteps1.
2925  *  \param [in] array - the C array to be used as raw data of \a this.
2926  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2927  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2928  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2929  *                     \c free(\c array ) will be called.
2930  *  \param [in] nbOfTuple - new number of tuples in \a this.
2931  *  \param [in] nbOfCompo - new number of components in \a this.
2932  */
2933 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2934 {
2935   _info_on_compo.resize(nbOfCompo);
2936   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2937   declareAsNew();
2938 }
2939
2940 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2941 {
2942   _info_on_compo.resize(nbOfCompo);
2943   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2944   declareAsNew();
2945 }
2946
2947 /*!
2948  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2949  * is thrown.
2950  * \throw If zero is found in \a this array.
2951  */
2952 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2953 {
2954   const double *tmp=getConstPointer();
2955   std::size_t nbOfElems=getNbOfElems();
2956   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2957   if(where!=tmp+nbOfElems)
2958     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2959 }
2960
2961 /*!
2962  * Computes minimal and maximal value in each component. An output array is filled
2963  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2964  * enough memory before calling this method.
2965  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2966  *               It is filled as follows:<br>
2967  *               \a bounds[0] = \c min_of_component_0 <br>
2968  *               \a bounds[1] = \c max_of_component_0 <br>
2969  *               \a bounds[2] = \c min_of_component_1 <br>
2970  *               \a bounds[3] = \c max_of_component_1 <br>
2971  *               ...
2972  */
2973 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2974 {
2975   checkAllocated();
2976   int dim=getNumberOfComponents();
2977   for (int idim=0; idim<dim; idim++)
2978     {
2979       bounds[idim*2]=std::numeric_limits<double>::max();
2980       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2981     } 
2982   const double *ptr=getConstPointer();
2983   int nbOfTuples=getNumberOfTuples();
2984   for(int i=0;i<nbOfTuples;i++)
2985     {
2986       for(int idim=0;idim<dim;idim++)
2987         {
2988           if(bounds[idim*2]>ptr[i*dim+idim])
2989             {
2990               bounds[idim*2]=ptr[i*dim+idim];
2991             }
2992           if(bounds[idim*2+1]<ptr[i*dim+idim])
2993             {
2994               bounds[idim*2+1]=ptr[i*dim+idim];
2995             }
2996         }
2997     }
2998 }
2999
3000 /*!
3001  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3002  * to store both the min and max per component of each tuples. 
3003  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3004  *
3005  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3006  *
3007  * \throw If \a this is not allocated yet.
3008  */
3009 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
3010 {
3011   checkAllocated();
3012   const double *dataPtr=getConstPointer();
3013   int nbOfCompo=getNumberOfComponents();
3014   int nbTuples=getNumberOfTuples();
3015   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3016   bbox->alloc(nbTuples,2*nbOfCompo);
3017   double *bboxPtr=bbox->getPointer();
3018   for(int i=0;i<nbTuples;i++)
3019     {
3020       for(int j=0;j<nbOfCompo;j++)
3021         {
3022           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3023           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3024         }
3025     }
3026   return bbox.retn();
3027 }
3028
3029 /*!
3030  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3031  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3032  * 
3033  * \param [in] other a DataArrayDouble having same number of components than \a this.
3034  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3035  * \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.
3036  *             \a cI allows to extract information in \a c.
3037  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3038  *
3039  * \throw In case of:
3040  *  - \a this is not allocated
3041  *  - \a other is not allocated or null
3042  *  - \a this and \a other do not have the same number of components
3043  *  - if number of components of \a this is not in [1,2,3]
3044  *
3045  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3046  */
3047 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
3048 {
3049   if(!other)
3050     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3051   checkAllocated();
3052   other->checkAllocated();
3053   int nbOfCompo=getNumberOfComponents();
3054   int otherNbOfCompo=other->getNumberOfComponents();
3055   if(nbOfCompo!=otherNbOfCompo)
3056     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3057   int nbOfTuplesOther=other->getNumberOfTuples();
3058   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3059   switch(nbOfCompo)
3060     {
3061     case 3:
3062       {
3063         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3064         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3065         break;
3066       }
3067     case 2:
3068       {
3069         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3070         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3071         break;
3072       }
3073     case 1:
3074       {
3075         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3076         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3077         break;
3078       }
3079     default:
3080       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3081     }
3082   c=cArr.retn(); cI=cIArr.retn();
3083 }
3084
3085 /*!
3086  * 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
3087  * around origin of 'radius' 1.
3088  * 
3089  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3090  */
3091 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
3092 {
3093   checkAllocated();
3094   int dim=getNumberOfComponents();
3095   std::vector<double> bounds(2*dim);
3096   getMinMaxPerComponent(&bounds[0]);
3097   for(int i=0;i<dim;i++)
3098     {
3099       double delta=bounds[2*i+1]-bounds[2*i];
3100       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3101       if(delta>eps)
3102         applyLin(1./delta,-offset/delta,i);
3103       else
3104         applyLin(1.,-offset,i);
3105     }
3106 }
3107
3108 /*!
3109  * Returns the maximal value and its location within \a this one-dimensional array.
3110  *  \param [out] tupleId - index of the tuple holding the maximal value.
3111  *  \return double - the maximal value among all values of \a this array.
3112  *  \throw If \a this->getNumberOfComponents() != 1
3113  *  \throw If \a this->getNumberOfTuples() < 1
3114  */
3115 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3116 {
3117   checkAllocated();
3118   if(getNumberOfComponents()!=1)
3119     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 !");
3120   int nbOfTuples=getNumberOfTuples();
3121   if(nbOfTuples<=0)
3122     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3123   const double *vals=getConstPointer();
3124   const double *loc=std::max_element(vals,vals+nbOfTuples);
3125   tupleId=(int)std::distance(vals,loc);
3126   return *loc;
3127 }
3128
3129 /*!
3130  * Returns the maximal value within \a this array that is allowed to have more than
3131  *  one component.
3132  *  \return double - the maximal value among all values of \a this array.
3133  *  \throw If \a this is not allocated.
3134  */
3135 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
3136 {
3137   checkAllocated();
3138   const double *loc=std::max_element(begin(),end());
3139   return *loc;
3140 }
3141
3142 /*!
3143  * Returns the maximal value and all its locations within \a this one-dimensional array.
3144  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3145  *               tuples holding the maximal value. The caller is to delete it using
3146  *               decrRef() as it is no more needed.
3147  *  \return double - the maximal value among all values of \a this array.
3148  *  \throw If \a this->getNumberOfComponents() != 1
3149  *  \throw If \a this->getNumberOfTuples() < 1
3150  */
3151 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3152 {
3153   int tmp;
3154   tupleIds=0;
3155   double ret=getMaxValue(tmp);
3156   tupleIds=getIdsInRange(ret,ret);
3157   return ret;
3158 }
3159
3160 /*!
3161  * Returns the minimal value and its location within \a this one-dimensional array.
3162  *  \param [out] tupleId - index of the tuple holding the minimal value.
3163  *  \return double - the minimal value among all values of \a this array.
3164  *  \throw If \a this->getNumberOfComponents() != 1
3165  *  \throw If \a this->getNumberOfTuples() < 1
3166  */
3167 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3168 {
3169   checkAllocated();
3170   if(getNumberOfComponents()!=1)
3171     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3172   int nbOfTuples=getNumberOfTuples();
3173   if(nbOfTuples<=0)
3174     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3175   const double *vals=getConstPointer();
3176   const double *loc=std::min_element(vals,vals+nbOfTuples);
3177   tupleId=(int)std::distance(vals,loc);
3178   return *loc;
3179 }
3180
3181 /*!
3182  * Returns the minimal value within \a this array that is allowed to have more than
3183  *  one component.
3184  *  \return double - the minimal value among all values of \a this array.
3185  *  \throw If \a this is not allocated.
3186  */
3187 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3188 {
3189   checkAllocated();
3190   const double *loc=std::min_element(begin(),end());
3191   return *loc;
3192 }
3193
3194 /*!
3195  * Returns the minimal value and all its locations within \a this one-dimensional array.
3196  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3197  *               tuples holding the minimal value. The caller is to delete it using
3198  *               decrRef() as it is no more needed.
3199  *  \return double - the minimal value among all values of \a this array.
3200  *  \throw If \a this->getNumberOfComponents() != 1
3201  *  \throw If \a this->getNumberOfTuples() < 1
3202  */
3203 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3204 {
3205   int tmp;
3206   tupleIds=0;
3207   double ret=getMinValue(tmp);
3208   tupleIds=getIdsInRange(ret,ret);
3209   return ret;
3210 }
3211
3212 /*!
3213  * 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.
3214  * This method only works for single component array.
3215  *
3216  * \return a value in [ 0, \c this->getNumberOfTuples() )
3217  *
3218  * \throw If \a this is not allocated
3219  *
3220  */
3221 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3222 {
3223   int ret=0;
3224   checkAllocated();
3225   if(getNumberOfComponents()!=1)
3226     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3227   const double *vals=begin();
3228   int nbOfTuples=getNumberOfTuples();
3229   for(int i=0;i<nbOfTuples;i++,vals++)
3230     if(fabs(*vals-value)<=eps)
3231       ret++;
3232   return ret;
3233 }
3234
3235 /*!
3236  * Returns the average value of \a this one-dimensional array.
3237  *  \return double - the average value over all values of \a this array.
3238  *  \throw If \a this->getNumberOfComponents() != 1
3239  *  \throw If \a this->getNumberOfTuples() < 1
3240  */
3241 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3242 {
3243   if(getNumberOfComponents()!=1)
3244     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3245   int nbOfTuples=getNumberOfTuples();
3246   if(nbOfTuples<=0)
3247     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3248   const double *vals=getConstPointer();
3249   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3250   return ret/nbOfTuples;
3251 }
3252
3253 /*!
3254  * Returns the Euclidean norm of the vector defined by \a this array.
3255  *  \return double - the value of the Euclidean norm, i.e.
3256  *          the square root of the inner product of vector.
3257  *  \throw If \a this is not allocated.
3258  */
3259 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3260 {
3261   checkAllocated();
3262   double ret=0.;
3263   std::size_t nbOfElems=getNbOfElems();
3264   const double *pt=getConstPointer();
3265   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3266     ret+=(*pt)*(*pt);
3267   return sqrt(ret);
3268 }
3269
3270 /*!
3271  * Returns the maximum norm of the vector defined by \a this array.
3272  *  \return double - the value of the maximum norm, i.e.
3273  *          the maximal absolute value among values of \a this array.
3274  *  \throw If \a this is not allocated.
3275  */
3276 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3277 {
3278   checkAllocated();
3279   double ret=-1.;
3280   std::size_t nbOfElems=getNbOfElems();
3281   const double *pt=getConstPointer();
3282   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3283     {
3284       double val=std::abs(*pt);
3285       if(val>ret)
3286         ret=val;
3287     }
3288   return ret;
3289 }
3290
3291 /*!
3292  * Accumulates values of each component of \a this array.
3293  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3294  *         by the caller, that is filled by this method with sum value for each
3295  *         component.
3296  *  \throw If \a this is not allocated.
3297  */
3298 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3299 {
3300   checkAllocated();
3301   const double *ptr=getConstPointer();
3302   int nbTuple=getNumberOfTuples();
3303   int nbComps=getNumberOfComponents();
3304   std::fill(res,res+nbComps,0.);
3305   for(int i=0;i<nbTuple;i++)
3306     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3307 }
3308
3309 /*!
3310  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3311  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3312  *
3313  *
3314  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3315  * \a tupleEnd. If not an exception will be thrown.
3316  *
3317  * \param [in] tupleBg start pointer (included) of input external tuple
3318  * \param [in] tupleEnd end pointer (not included) of input external tuple
3319  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3320  * \return the min distance.
3321  * \sa MEDCouplingUMesh::distanceToPoint
3322  */
3323 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3324 {
3325   checkAllocated();
3326   int nbTuple=getNumberOfTuples();
3327   int nbComps=getNumberOfComponents();
3328   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3329     { 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()); }
3330   if(nbTuple==0)
3331     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3332   double ret0=std::numeric_limits<double>::max();
3333   tupleId=-1;
3334   const double *work=getConstPointer();
3335   for(int i=0;i<nbTuple;i++)
3336     {
3337       double val=0.;
3338       for(int j=0;j<nbComps;j++,work++) 
3339         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3340       if(val>=ret0)
3341         continue;
3342       else
3343         { ret0=val; tupleId=i; }
3344     }
3345   return sqrt(ret0);
3346 }
3347
3348 /*!
3349  * Accumulate values of the given component of \a this array.
3350  *  \param [in] compId - the index of the component of interest.
3351  *  \return double - a sum value of \a compId-th component.
3352  *  \throw If \a this is not allocated.
3353  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3354  *         not respected.
3355  */
3356 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3357 {
3358   checkAllocated();
3359   const double *ptr=getConstPointer();
3360   int nbTuple=getNumberOfTuples();
3361   int nbComps=getNumberOfComponents();
3362   if(compId<0 || compId>=nbComps)
3363     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3364   double ret=0.;
3365   for(int i=0;i<nbTuple;i++)
3366     ret+=ptr[i*nbComps+compId];
3367   return ret;
3368 }
3369
3370 /*!
3371  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3372  * The returned array will have same number of components than \a this and number of tuples equal to
3373  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3374  *
3375  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3376  * 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.
3377  *
3378  * \param [in] bgOfIndex - begin (included) of the input index array.
3379  * \param [in] endOfIndex - end (excluded) of the input index array.
3380  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3381  * 
3382  * \throw If bgOfIndex or end is NULL.
3383  * \throw If input index array is not ascendingly sorted.
3384  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3385  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3386  */
3387 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3388 {
3389   if(!bgOfIndex || !endOfIndex)
3390     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3391   checkAllocated();
3392   int nbCompo=getNumberOfComponents();
3393   int nbOfTuples=getNumberOfTuples();
3394   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3395   if(sz<1)
3396     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3397   sz--;
3398   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3399   const int *w=bgOfIndex;
3400   if(*w<0 || *w>=nbOfTuples)
3401     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3402   const double *srcPt=begin()+(*w)*nbCompo;
3403   double *tmp=ret->getPointer();
3404   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3405     {
3406       std::fill(tmp,tmp+nbCompo,0.);
3407       if(w[1]>=w[0])
3408         {
3409           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3410             {
3411               if(j>=0 && j<nbOfTuples)
3412                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3413               else
3414                 {
3415                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3416                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3417                 }
3418             }
3419         }
3420       else
3421         {
3422           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3423           throw INTERP_KERNEL::Exception(oss.str().c_str());
3424         }
3425     }
3426   ret->copyStringInfoFrom(*this);
3427   return ret.retn();
3428 }
3429
3430 /*!
3431  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3432  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3433  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3434  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3435  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3436  *          is to delete this array using decrRef() as it is no more needed. The array
3437  *          does not contain any textual info on components.
3438  *  \throw If \a this->getNumberOfComponents() != 2.
3439  */
3440 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3441 {
3442   checkAllocated();
3443   int nbOfComp=getNumberOfComponents();
3444   if(nbOfComp!=2)
3445     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3446   int nbOfTuple=getNumberOfTuples();
3447   DataArrayDouble *ret=DataArrayDouble::New();
3448   ret->alloc(nbOfTuple,2);
3449   double *w=ret->getPointer();
3450   const double *wIn=getConstPointer();
3451   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3452     {
3453       w[0]=wIn[0]*cos(wIn[1]);
3454       w[1]=wIn[0]*sin(wIn[1]);
3455     }
3456   return ret;
3457 }
3458
3459 /*!
3460  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3461  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3462  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3463  * the Cylindrical CS.
3464  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3465  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3466  *          on the third component is copied from \a this array. The caller
3467  *          is to delete this array using decrRef() as it is no more needed. 
3468  *  \throw If \a this->getNumberOfComponents() != 3.
3469  */
3470 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3471 {
3472   checkAllocated();
3473   int nbOfComp=getNumberOfComponents();
3474   if(nbOfComp!=3)
3475     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3476   int nbOfTuple=getNumberOfTuples();
3477   DataArrayDouble *ret=DataArrayDouble::New();
3478   ret->alloc(getNumberOfTuples(),3);
3479   double *w=ret->getPointer();
3480   const double *wIn=getConstPointer();
3481   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3482     {
3483       w[0]=wIn[0]*cos(wIn[1]);
3484       w[1]=wIn[0]*sin(wIn[1]);
3485       w[2]=wIn[2];
3486     }
3487   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3488   return ret;
3489 }
3490
3491 /*!
3492  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3493  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3494  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3495  * point in the Cylindrical CS.
3496  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3497  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3498  *          on the third component is copied from \a this array. The caller
3499  *          is to delete this array using decrRef() as it is no more needed.
3500  *  \throw If \a this->getNumberOfComponents() != 3.
3501  */
3502 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3503 {
3504   checkAllocated();
3505   int nbOfComp=getNumberOfComponents();
3506   if(nbOfComp!=3)
3507     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3508   int nbOfTuple=getNumberOfTuples();
3509   DataArrayDouble *ret=DataArrayDouble::New();
3510   ret->alloc(getNumberOfTuples(),3);
3511   double *w=ret->getPointer();
3512   const double *wIn=getConstPointer();
3513   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3514     {
3515       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3516       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3517       w[2]=wIn[0]*cos(wIn[1]);
3518     }
3519   return ret;
3520 }
3521
3522 /*!
3523  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3524  * array contating 6 components.
3525  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3526  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3527  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3528  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3529  *  \throw If \a this->getNumberOfComponents() != 6.
3530  */
3531 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3532 {
3533   checkAllocated();
3534   int nbOfComp=getNumberOfComponents();
3535   if(nbOfComp!=6)
3536     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3537   DataArrayDouble *ret=DataArrayDouble::New();
3538   int nbOfTuple=getNumberOfTuples();
3539   ret->alloc(nbOfTuple,1);
3540   const double *src=getConstPointer();
3541   double *dest=ret->getPointer();
3542   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3543     *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];
3544   return ret;
3545 }
3546
3547 /*!
3548  * Computes the determinant of every square matrix defined by the tuple of \a this
3549  * array, which contains either 4, 6 or 9 components. The case of 6 components
3550  * corresponds to that of the upper triangular matrix.
3551  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3552  *          is the determinant of matrix of the corresponding tuple of \a this array.
3553  *          The caller is to delete this result array using decrRef() as it is no more
3554  *          needed. 
3555  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3556  */
3557 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3558 {
3559   checkAllocated();
3560   DataArrayDouble *ret=DataArrayDouble::New();
3561   int nbOfTuple=getNumberOfTuples();
3562   ret->alloc(nbOfTuple,1);
3563   const double *src=getConstPointer();
3564   double *dest=ret->getPointer();
3565   switch(getNumberOfComponents())
3566     {
3567     case 6:
3568       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3569         *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];
3570       return ret;
3571     case 4:
3572       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3573         *dest=src[0]*src[3]-src[1]*src[2];
3574       return ret;
3575     case 9:
3576       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3577         *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];
3578       return ret;
3579     default:
3580       ret->decrRef();
3581       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3582     }
3583 }
3584
3585 /*!
3586  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3587  * \a this array, which contains 6 components.
3588  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3589  *          components, whose each tuple contains the eigenvalues of the matrix of
3590  *          corresponding tuple of \a this array. 
3591  *          The caller is to delete this result array using decrRef() as it is no more
3592  *          needed. 
3593  *  \throw If \a this->getNumberOfComponents() != 6.
3594  */
3595 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3596 {
3597   checkAllocated();
3598   int nbOfComp=getNumberOfComponents();
3599   if(nbOfComp!=6)
3600     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3601   DataArrayDouble *ret=DataArrayDouble::New();
3602   int nbOfTuple=getNumberOfTuples();
3603   ret->alloc(nbOfTuple,3);
3604   const double *src=getConstPointer();
3605   double *dest=ret->getPointer();
3606   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3607     INTERP_KERNEL::computeEigenValues6(src,dest);
3608   return ret;
3609 }
3610
3611 /*!
3612  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3613  * \a this array, which contains 6 components.
3614  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3615  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3616  *          corresponding tuple of \a this array.
3617  *          The caller is to delete this result array using decrRef() as it is no more
3618  *          needed.
3619  *  \throw If \a this->getNumberOfComponents() != 6.
3620  */
3621 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3622 {
3623   checkAllocated();
3624   int nbOfComp=getNumberOfComponents();
3625   if(nbOfComp!=6)
3626     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3627   DataArrayDouble *ret=DataArrayDouble::New();
3628   int nbOfTuple=getNumberOfTuples();
3629   ret->alloc(nbOfTuple,9);
3630   const double *src=getConstPointer();
3631   double *dest=ret->getPointer();
3632   for(int i=0;i<nbOfTuple;i++,src+=6)
3633     {
3634       double tmp[3];
3635       INTERP_KERNEL::computeEigenValues6(src,tmp);
3636       for(int j=0;j<3;j++,dest+=3)
3637         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3638     }
3639   return ret;
3640 }
3641
3642 /*!
3643  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3644  * array, which contains either 4, 6 or 9 components. The case of 6 components
3645  * corresponds to that of the upper triangular matrix.
3646  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3647  *          same number of components as \a this one, whose each tuple is the inverse
3648  *          matrix of the matrix of corresponding tuple of \a this array. 
3649  *          The caller is to delete this result array using decrRef() as it is no more
3650  *          needed. 
3651  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3652  */
3653 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3654 {
3655   checkAllocated();
3656   int nbOfComp=getNumberOfComponents();
3657   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3658     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3659   DataArrayDouble *ret=DataArrayDouble::New();
3660   int nbOfTuple=getNumberOfTuples();
3661   ret->alloc(nbOfTuple,nbOfComp);
3662   const double *src=getConstPointer();
3663   double *dest=ret->getPointer();
3664 if(nbOfComp==6)
3665     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3666       {
3667         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];
3668         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3669         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3670         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3671         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3672         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3673         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3674       }
3675   else if(nbOfComp==4)
3676     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3677       {
3678         double det=src[0]*src[3]-src[1]*src[2];
3679         dest[0]=src[3]/det;
3680         dest[1]=-src[1]/det;
3681         dest[2]=-src[2]/det;
3682         dest[3]=src[0]/det;
3683       }
3684   else
3685     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3686       {
3687         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];
3688         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3689         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3690         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3691         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3692         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3693         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3694         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3695         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3696         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3697       }
3698   return ret;
3699 }
3700
3701 /*!
3702  * Computes the trace of every matrix defined by the tuple of \a this
3703  * array, which contains either 4, 6 or 9 components. The case of 6 components
3704  * corresponds to that of the upper triangular matrix.
3705  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3706  *          1 component, whose each tuple is the trace of
3707  *          the matrix of corresponding tuple of \a this array. 
3708  *          The caller is to delete this result array using decrRef() as it is no more
3709  *          needed. 
3710  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3711  */
3712 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3713 {
3714   checkAllocated();
3715   int nbOfComp=getNumberOfComponents();
3716   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3717     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3718   DataArrayDouble *ret=DataArrayDouble::New();
3719   int nbOfTuple=getNumberOfTuples();
3720   ret->alloc(nbOfTuple,1);
3721   const double *src=getConstPointer();
3722   double *dest=ret->getPointer();
3723   if(nbOfComp==6)
3724     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3725       *dest=src[0]+src[1]+src[2];
3726   else if(nbOfComp==4)
3727     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3728       *dest=src[0]+src[3];
3729   else
3730     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3731       *dest=src[0]+src[4]+src[8];
3732   return ret;
3733 }
3734
3735 /*!
3736  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3737  * \a this array, which contains 6 components.
3738  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3739  *          same number of components and tuples as \a this array.
3740  *          The caller is to delete this result array using decrRef() as it is no more
3741  *          needed.
3742  *  \throw If \a this->getNumberOfComponents() != 6.
3743  */
3744 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3745 {
3746   checkAllocated();
3747   int nbOfComp=getNumberOfComponents();
3748   if(nbOfComp!=6)
3749     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3750   DataArrayDouble *ret=DataArrayDouble::New();
3751   int nbOfTuple=getNumberOfTuples();
3752   ret->alloc(nbOfTuple,6);
3753   const double *src=getConstPointer();
3754   double *dest=ret->getPointer();
3755   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3756     {
3757       double tr=(src[0]+src[1]+src[2])/3.;
3758       dest[0]=src[0]-tr;
3759       dest[1]=src[1]-tr;
3760       dest[2]=src[2]-tr;
3761       dest[3]=src[3];
3762       dest[4]=src[4];
3763       dest[5]=src[5];
3764     }
3765   return ret;
3766 }
3767
3768 /*!
3769  * Computes the magnitude of every vector defined by the tuple of
3770  * \a this array.
3771  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3772  *          same number of tuples as \a this array and one component.
3773  *          The caller is to delete this result array using decrRef() as it is no more
3774  *          needed.
3775  *  \throw If \a this is not allocated.
3776  */
3777 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3778 {
3779   checkAllocated();
3780   int nbOfComp=getNumberOfComponents();
3781   DataArrayDouble *ret=DataArrayDouble::New();
3782   int nbOfTuple=getNumberOfTuples();
3783   ret->alloc(nbOfTuple,1);
3784   const double *src=getConstPointer();
3785   double *dest=ret->getPointer();
3786   for(int i=0;i<nbOfTuple;i++,dest++)
3787     {
3788       double sum=0.;
3789       for(int j=0;j<nbOfComp;j++,src++)
3790         sum+=(*src)*(*src);
3791       *dest=sqrt(sum);
3792     }
3793   return ret;
3794 }
3795
3796 /*!
3797  * Computes the maximal value within every tuple of \a this array.
3798  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3799  *          same number of tuples as \a this array and one component.
3800  *          The caller is to delete this result array using decrRef() as it is no more
3801  *          needed.
3802  *  \throw If \a this is not allocated.
3803  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3804  */
3805 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3806 {
3807   checkAllocated();
3808   int nbOfComp=getNumberOfComponents();
3809   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3810   int nbOfTuple=getNumberOfTuples();
3811   ret->alloc(nbOfTuple,1);
3812   const double *src=getConstPointer();
3813   double *dest=ret->getPointer();
3814   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3815     *dest=*std::max_element(src,src+nbOfComp);
3816   return ret.retn();
3817 }
3818
3819 /*!
3820  * Computes the maximal value within every tuple of \a this array and it returns the first component
3821  * id for each tuple that corresponds to the maximal value within the tuple.
3822  * 
3823  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3824  *          same number of tuples and only one component.
3825  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3826  *          same number of tuples as \a this array and one component.
3827  *          The caller is to delete this result array using decrRef() as it is no more
3828  *          needed.
3829  *  \throw If \a this is not allocated.
3830  *  \sa DataArrayDouble::maxPerTuple
3831  */
3832 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3833 {
3834   checkAllocated();
3835   int nbOfComp=getNumberOfComponents();
3836   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3837   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3838   int nbOfTuple=getNumberOfTuples();
3839   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3840   const double *src=getConstPointer();
3841   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3842   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3843     {
3844       const double *loc=std::max_element(src,src+nbOfComp);
3845       *dest=*loc;
3846       *dest1=(int)std::distance(src,loc);
3847     }
3848   compoIdOfMaxPerTuple=ret1.retn();
3849   return ret0.retn();
3850 }
3851
3852 /*!
3853  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3854  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3855  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3856  * \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)
3857  *
3858  * \warning use this method with care because it can leads to big amount of consumed memory !
3859  * 
3860  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3861  *
3862  * \throw If \a this is not allocated.
3863  *
3864  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3865  */
3866 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3867 {
3868   checkAllocated();
3869   int nbOfComp=getNumberOfComponents();
3870   int nbOfTuples=getNumberOfTuples();
3871   const double *inData=getConstPointer();
3872   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3873   ret->alloc(nbOfTuples*nbOfTuples,1);
3874   double *outData=ret->getPointer();
3875   for(int i=0;i<nbOfTuples;i++)
3876     {
3877       outData[i*nbOfTuples+i]=0.;
3878       for(int j=i+1;j<nbOfTuples;j++)
3879         {
3880           double dist=0.;
3881           for(int k=0;k<nbOfComp;k++)
3882             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3883           dist=sqrt(dist);
3884           outData[i*nbOfTuples+j]=dist;
3885           outData[j*nbOfTuples+i]=dist;
3886         }
3887     }
3888   return ret.retn();
3889 }
3890
3891 /*!
3892  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3893  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3894  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3895  * \n Output rectangular matrix is sorted along rows.
3896  * \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)
3897  *
3898  * \warning use this method with care because it can leads to big amount of consumed memory !
3899  * 
3900  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3901  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3902  *
3903  * \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.
3904  *
3905  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3906  */
3907 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3908 {
3909   if(!other)
3910     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3911   checkAllocated();
3912   other->checkAllocated();
3913   int nbOfComp=getNumberOfComponents();
3914   int otherNbOfComp=other->getNumberOfComponents();
3915   if(nbOfComp!=otherNbOfComp)
3916     {
3917       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3918       throw INTERP_KERNEL::Exception(oss.str().c_str());
3919     }
3920   int nbOfTuples=getNumberOfTuples();
3921   int otherNbOfTuples=other->getNumberOfTuples();
3922   const double *inData=getConstPointer();
3923   const double *inDataOther=other->getConstPointer();
3924   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3925   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3926   double *outData=ret->getPointer();
3927   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3928     {
3929       for(int j=0;j<nbOfTuples;j++)
3930         {
3931           double dist=0.;
3932           for(int k=0;k<nbOfComp;k++)
3933             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3934           dist=sqrt(dist);
3935           outData[i*nbOfTuples+j]=dist;
3936         }
3937     }
3938   return ret.retn();
3939 }
3940
3941 /*!
3942  * Sorts value within every tuple of \a this array.
3943  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3944  *              in descending order.
3945  *  \throw If \a this is not allocated.
3946  */
3947 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3948 {
3949   checkAllocated();
3950   double *pt=getPointer();
3951   int nbOfTuple=getNumberOfTuples();
3952   int nbOfComp=getNumberOfComponents();
3953   if(asc)
3954     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3955       std::sort(pt,pt+nbOfComp);
3956   else
3957     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3958       std::sort(pt,pt+nbOfComp,std::greater<double>());
3959   declareAsNew();
3960 }
3961
3962 /*!
3963  * Converts every value of \a this array to its absolute value.
3964  *  \throw If \a this is not allocated.
3965  */
3966 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3967 {
3968   checkAllocated();
3969   double *ptr=getPointer();
3970   std::size_t nbOfElems=getNbOfElems();
3971   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3972   declareAsNew();
3973 }
3974
3975 /*!
3976  * Apply a liner function to a given component of \a this array, so that
3977  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3978  *  \param [in] a - the first coefficient of the function.
3979  *  \param [in] b - the second coefficient of the function.
3980  *  \param [in] compoId - the index of component to modify.
3981  *  \throw If \a this is not allocated.
3982  */
3983 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3984 {
3985   checkAllocated();
3986   double *ptr=getPointer()+compoId;
3987   int nbOfComp=getNumberOfComponents();
3988   int nbOfTuple=getNumberOfTuples();
3989   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3990     *ptr=a*(*ptr)+b;
3991   declareAsNew();
3992 }
3993
3994 /*!
3995  * Apply a liner function to all elements of \a this array, so that
3996  * an element _x_ becomes \f$ a * x + b \f$.
3997  *  \param [in] a - the first coefficient of the function.
3998  *  \param [in] b - the second coefficient of the function.
3999  *  \throw If \a this is not allocated.
4000  */
4001 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
4002 {
4003   checkAllocated();
4004   double *ptr=getPointer();
4005   std::size_t nbOfElems=getNbOfElems();
4006   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4007     *ptr=a*(*ptr)+b;
4008   declareAsNew();
4009 }
4010
4011 /*!
4012  * Modify all elements of \a this array, so that
4013  * an element _x_ becomes \f$ numerator / x \f$.
4014  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4015  *           array, all elements processed before detection of the zero element remain
4016  *           modified.
4017  *  \param [in] numerator - the numerator used to modify array elements.
4018  *  \throw If \a this is not allocated.
4019  *  \throw If there is an element equal to 0.0 in \a this array.
4020  */
4021 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
4022 {
4023   checkAllocated();
4024   double *ptr=getPointer();
4025   std::size_t nbOfElems=getNbOfElems();
4026   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4027     {
4028       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4029         {
4030           *ptr=numerator/(*ptr);
4031         }
4032       else
4033         {
4034           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4035           oss << " !";
4036           throw INTERP_KERNEL::Exception(oss.str().c_str());
4037         }
4038     }
4039   declareAsNew();
4040 }
4041
4042 /*!
4043  * Returns a full copy of \a this array except that sign of all elements is reversed.
4044  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4045  *          same number of tuples and component as \a this array.
4046  *          The caller is to delete this result array using decrRef() as it is no more
4047  *          needed.
4048  *  \throw If \a this is not allocated.
4049  */
4050 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
4051 {
4052   checkAllocated();
4053   DataArrayDouble *newArr=DataArrayDouble::New();
4054   int nbOfTuples=getNumberOfTuples();
4055   int nbOfComp=getNumberOfComponents();
4056   newArr->alloc(nbOfTuples,nbOfComp);
4057   const double *cptr=getConstPointer();
4058   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4059   newArr->copyStringInfoFrom(*this);
4060   return newArr;
4061 }
4062
4063 /*!
4064  * Modify all elements of \a this array, so that
4065  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4066  * all values in \a this have to be >= 0 if val is \b not integer.
4067  *  \param [in] val - the value used to apply pow on all array elements.
4068  *  \throw If \a this is not allocated.
4069  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4070  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4071  *           modified.
4072  */
4073 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
4074 {
4075   checkAllocated();
4076   double *ptr=getPointer();
4077   std::size_t nbOfElems=getNbOfElems();
4078   int val2=(int)val;
4079   bool isInt=((double)val2)==val;
4080   if(!isInt)
4081     {
4082       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4083         {
4084           if(*ptr>=0)
4085             *ptr=pow(*ptr,val);
4086           else
4087             {
4088               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4089               throw INTERP_KERNEL::Exception(oss.str().c_str());
4090             }
4091         }
4092     }
4093   else
4094     {
4095       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4096         *ptr=pow(*ptr,val2);
4097     }
4098   declareAsNew();
4099 }
4100
4101 /*!
4102  * Modify all elements of \a this array, so that
4103  * an element _x_ becomes \f$ val ^ x \f$.
4104  *  \param [in] val - the value used to apply pow on all array elements.
4105  *  \throw If \a this is not allocated.
4106  *  \throw If \a val < 0.
4107  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4108  *           array, all elements processed before detection of the zero element remain
4109  *           modified.
4110  */
4111 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
4112 {
4113   checkAllocated();
4114   if(val<0.)
4115     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4116   double *ptr=getPointer();
4117   std::size_t nbOfElems=getNbOfElems();
4118   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4119     *ptr=pow(val,*ptr);
4120   declareAsNew();
4121 }
4122
4123 /*!
4124  * Returns a new DataArrayDouble created from \a this one by applying \a
4125  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4126  * For more info see \ref MEDCouplingArrayApplyFunc
4127  *  \param [in] nbOfComp - number of components in the result array.
4128  *  \param [in] func - the \a FunctionToEvaluate declared as 
4129  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4130  *              where \a pos points to the first component of a tuple of \a this array
4131  *              and \a res points to the first component of a tuple of the result array.
4132  *              Note that length (number of components) of \a pos can differ from
4133  *              that of \a res.
4134  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4135  *          same number of tuples as \a this array.
4136  *          The caller is to delete this result array using decrRef() as it is no more
4137  *          needed.
4138  *  \throw If \a this is not allocated.
4139  *  \throw If \a func returns \a false.
4140  */
4141 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
4142 {
4143   checkAllocated();
4144   DataArrayDouble *newArr=DataArrayDouble::New();
4145   int nbOfTuples=getNumberOfTuples();
4146   int oldNbOfComp=getNumberOfComponents();
4147   newArr->alloc(nbOfTuples,nbOfComp);
4148   const double *ptr=getConstPointer();
4149   double *ptrToFill=newArr->getPointer();
4150   for(int i=0;i<nbOfTuples;i++)
4151     {
4152       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4153         {
4154           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4155           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4156           oss << ") : Evaluation of function failed !";
4157           newArr->decrRef();
4158           throw INTERP_KERNEL::Exception(oss.str().c_str());
4159         }
4160     }
4161   return newArr;
4162 }
4163
4164 /*!
4165  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4166  * tuple of \a this array. Textual data is not copied.
4167  * For more info see \ref MEDCouplingArrayApplyFunc1.
4168  *  \param [in] nbOfComp - number of components in the result array.
4169  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4170  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4171  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4172  *          same number of tuples as \a this array and \a nbOfComp components.
4173  *          The caller is to delete this result array using decrRef() as it is no more
4174  *          needed.
4175  *  \throw If \a this is not allocated.
4176  *  \throw If computing \a func fails.
4177  */
4178 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4179 {
4180   checkAllocated();
4181   INTERP_KERNEL::ExprParser expr(func);
4182   expr.parse();
4183   std::set<std::string> vars;
4184   expr.getTrueSetOfVars(vars);
4185   int oldNbOfComp=getNumberOfComponents();
4186   if((int)vars.size()>oldNbOfComp)
4187     {
4188       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4189       oss << vars.size() << " variables : ";
4190       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4191       throw INTERP_KERNEL::Exception(oss.str().c_str());
4192     }
4193   std::vector<std::string> varsV(vars.begin(),vars.end());
4194   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4195   //
4196   DataArrayDouble *newArr=DataArrayDouble::New();
4197   int nbOfTuples=getNumberOfTuples();
4198   newArr->alloc(nbOfTuples,nbOfComp);
4199   const double *ptr=getConstPointer();
4200   double *ptrToFill=newArr->getPointer();
4201   for(int i=0;i<nbOfTuples;i++)
4202     {
4203       try
4204         {
4205           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4206         }
4207       catch(INTERP_KERNEL::Exception& e)
4208         {
4209           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4210           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4211           oss << ") : Evaluation of function failed !" << e.what();
4212           newArr->decrRef();
4213           throw INTERP_KERNEL::Exception(oss.str().c_str());
4214         }
4215     }
4216   return newArr;
4217 }
4218
4219 /*!
4220  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4221  * tuple of \a this array. Textual data is not copied.
4222  * For more info see \ref MEDCouplingArrayApplyFunc0.
4223  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4224  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4225  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4226  *          same number of tuples and components as \a this array.
4227  *          The caller is to delete this result array using decrRef() as it is no more
4228  *          needed.
4229  *  \throw If \a this is not allocated.
4230  *  \throw If computing \a func fails.
4231  */
4232 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4233 {
4234   checkAllocated();
4235   INTERP_KERNEL::ExprParser expr(func);
4236   expr.parse();
4237   expr.prepareExprEvaluationVec();
4238   //
4239   DataArrayDouble *newArr=DataArrayDouble::New();
4240   int nbOfTuples=getNumberOfTuples();
4241   int nbOfComp=getNumberOfComponents();
4242   newArr->alloc(nbOfTuples,nbOfComp);
4243   const double *ptr=getConstPointer();
4244   double *ptrToFill=newArr->getPointer();
4245   for(int i=0;i<nbOfTuples;i++)
4246     {
4247       try
4248         {
4249           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4250         }
4251       catch(INTERP_KERNEL::Exception& e)
4252         {
4253           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4254           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4255           oss << ") : Evaluation of function failed ! " << e.what();
4256           newArr->decrRef();
4257           throw INTERP_KERNEL::Exception(oss.str().c_str());
4258         }
4259     }
4260   return newArr;
4261 }
4262
4263 /*!
4264  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4265  * tuple of \a this array. Textual data is not copied.
4266  * For more info see \ref MEDCouplingArrayApplyFunc2.
4267  *  \param [in] nbOfComp - number of components in the result array.
4268  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4269  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4270  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4271  *          same number of tuples as \a this array.
4272  *          The caller is to delete this result array using decrRef() as it is no more
4273  *          needed.
4274  *  \throw If \a this is not allocated.
4275  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4276  *  \throw If computing \a func fails.
4277  */
4278 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4279 {
4280   checkAllocated();
4281   INTERP_KERNEL::ExprParser expr(func);
4282   expr.parse();
4283   std::set<std::string> vars;
4284   expr.getTrueSetOfVars(vars);
4285   int oldNbOfComp=getNumberOfComponents();
4286   if((int)vars.size()>oldNbOfComp)
4287     {
4288       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4289       oss << vars.size() << " variables : ";
4290       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4291       throw INTERP_KERNEL::Exception(oss.str().c_str());
4292     }
4293   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4294   //
4295   DataArrayDouble *newArr=DataArrayDouble::New();
4296   int nbOfTuples=getNumberOfTuples();
4297   newArr->alloc(nbOfTuples,nbOfComp);
4298   const double *ptr=getConstPointer();
4299   double *ptrToFill=newArr->getPointer();
4300   for(int i=0;i<nbOfTuples;i++)
4301     {
4302       try
4303         {
4304           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4305         }
4306       catch(INTERP_KERNEL::Exception& e)
4307         {
4308           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4309           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4310           oss << ") : Evaluation of function failed !" << e.what();
4311           newArr->decrRef();
4312           throw INTERP_KERNEL::Exception(oss.str().c_str());
4313         }
4314     }
4315   return newArr;
4316 }
4317
4318 /*!
4319  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4320  * tuple of \a this array. Textual data is not copied.
4321  * For more info see \ref MEDCouplingArrayApplyFunc3.
4322  *  \param [in] nbOfComp - number of components in the result array.
4323  *  \param [in] varsOrder - sequence of vars defining their order.
4324  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4325  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4326  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4327  *          same number of tuples as \a this array.
4328  *          The caller is to delete this result array using decrRef() as it is no more
4329  *          needed.
4330  *  \throw If \a this is not allocated.
4331  *  \throw If \a func contains vars not in \a varsOrder.
4332  *  \throw If computing \a func fails.
4333  */
4334 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4335 {
4336   checkAllocated();
4337   INTERP_KERNEL::ExprParser expr(func);
4338   expr.parse();
4339   std::set<std::string> vars;
4340   expr.getTrueSetOfVars(vars);
4341   int oldNbOfComp=getNumberOfComponents();
4342   if((int)vars.size()>oldNbOfComp)
4343     {
4344       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4345       oss << vars.size() << " variables : ";
4346       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4347       throw INTERP_KERNEL::Exception(oss.str().c_str());
4348     }
4349   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4350   //
4351   DataArrayDouble *newArr=DataArrayDouble::New();
4352   int nbOfTuples=getNumberOfTuples();
4353   newArr->alloc(nbOfTuples,nbOfComp);
4354   const double *ptr=getConstPointer();
4355   double *ptrToFill=newArr->getPointer();
4356   for(int i=0;i<nbOfTuples;i++)
4357     {
4358       try
4359         {
4360           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4361         }
4362       catch(INTERP_KERNEL::Exception& e)
4363         {
4364           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4365           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4366           oss << ") : Evaluation of function failed !" << e.what();
4367           newArr->decrRef();
4368           throw INTERP_KERNEL::Exception(oss.str().c_str());
4369         }
4370     }
4371   return newArr;
4372 }
4373
4374 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4375 {
4376   checkAllocated();
4377   INTERP_KERNEL::ExprParser expr(func);
4378   expr.parse();
4379   char *funcStr=expr.compileX86();
4380   MYFUNCPTR funcPtr;
4381   *((void **)&funcPtr)=funcStr;//he he...
4382   //
4383   double *ptr=getPointer();
4384   int nbOfComp=getNumberOfComponents();
4385   int nbOfTuples=getNumberOfTuples();
4386   int nbOfElems=nbOfTuples*nbOfComp;
4387   for(int i=0;i<nbOfElems;i++,ptr++)
4388     *ptr=funcPtr(*ptr);
4389   declareAsNew();
4390 }
4391
4392 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4393 {
4394   checkAllocated();
4395   INTERP_KERNEL::ExprParser expr(func);
4396   expr.parse();
4397   char *funcStr=expr.compileX86_64();
4398   MYFUNCPTR funcPtr;
4399   *((void **)&funcPtr)=funcStr;//he he...
4400   //
4401   double *ptr=getPointer();
4402   int nbOfComp=getNumberOfComponents();
4403   int nbOfTuples=getNumberOfTuples();
4404   int nbOfElems=nbOfTuples*nbOfComp;
4405   for(int i=0;i<nbOfElems;i++,ptr++)
4406     *ptr=funcPtr(*ptr);
4407   declareAsNew();
4408 }
4409
4410 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4411 {
4412   return new DataArrayDoubleIterator(this);
4413 }
4414
4415 /*!
4416  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4417  * array whose values are within a given range. Textual data is not copied.
4418  *  \param [in] vmin - a lowest acceptable value (included).
4419  *  \param [in] vmax - a greatest acceptable value (included).
4420  *  \return DataArrayInt * - the new instance of DataArrayInt.
4421  *          The caller is to delete this result array using decrRef() as it is no more
4422  *          needed.
4423  *  \throw If \a this->getNumberOfComponents() != 1.
4424  *
4425  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4426  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4427  */
4428 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4429 {
4430   checkAllocated();
4431   if(getNumberOfComponents()!=1)
4432     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4433   const double *cptr=getConstPointer();
4434   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4435   int nbOfTuples=getNumberOfTuples();
4436   for(int i=0;i<nbOfTuples;i++,cptr++)
4437     if(*cptr>=vmin && *cptr<=vmax)
4438       ret->pushBackSilent(i);
4439   return ret.retn();
4440 }
4441
4442 /*!
4443  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4444  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4445  * the number of component in the result array is same as that of each of given arrays.
4446  * Info on components is copied from the first of the given arrays. Number of components
4447  * in the given arrays must be  the same.
4448  *  \param [in] a1 - an array to include in the result array.
4449  *  \param [in] a2 - another array to include in the result array.
4450  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4451  *          The caller is to delete this result array using decrRef() as it is no more
4452  *          needed.
4453  *  \throw If both \a a1 and \a a2 are NULL.
4454  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4455  */
4456 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4457 {
4458   std::vector<const DataArrayDouble *> tmp(2);
4459   tmp[0]=a1; tmp[1]=a2;
4460   return Aggregate(tmp);
4461 }
4462
4463 /*!
4464  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4465  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4466  * the number of component in the result array is same as that of each of given arrays.
4467  * Info on components is copied from the first of the given arrays. Number of components
4468  * in the given arrays must be  the same.
4469  *  \param [in] arr - a sequence of arrays to include in the result array.
4470  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4471  *          The caller is to delete this result array using decrRef() as it is no more
4472  *          needed.
4473  *  \throw If all arrays within \a arr are NULL.
4474  *  \throw If getNumberOfComponents() of arrays within \a arr.
4475  */
4476 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4477 {
4478   std::vector<const DataArrayDouble *> a;
4479   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4480     if(*it4)
4481       a.push_back(*it4);
4482   if(a.empty())
4483     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4484   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4485   int nbOfComp=(*it)->getNumberOfComponents();
4486   int nbt=(*it++)->getNumberOfTuples();
4487   for(int i=1;it!=a.end();it++,i++)
4488     {
4489       if((*it)->getNumberOfComponents()!=nbOfComp)
4490         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4491       nbt+=(*it)->getNumberOfTuples();
4492     }
4493   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4494   ret->alloc(nbt,nbOfComp);
4495   double *pt=ret->getPointer();
4496   for(it=a.begin();it!=a.end();it++)
4497     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4498   ret->copyStringInfoFrom(*(a[0]));
4499   return ret.retn();
4500 }
4501
4502 /*!
4503  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4504  * of components in the result array is a sum of the number of components of given arrays
4505  * and (2) the number of tuples in the result array is same as that of each of given
4506  * arrays. In other words the i-th tuple of result array includes all components of
4507  * i-th tuples of all given arrays.
4508  * Number of tuples in the given arrays must be  the same.
4509  *  \param [in] a1 - an array to include in the result array.
4510  *  \param [in] a2 - another array to include in the result array.
4511  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4512  *          The caller is to delete this result array using decrRef() as it is no more
4513  *          needed.
4514  *  \throw If both \a a1 and \a a2 are NULL.
4515  *  \throw If any given array is not allocated.
4516  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4517  */
4518 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4519 {
4520   std::vector<const DataArrayDouble *> arr(2);
4521   arr[0]=a1; arr[1]=a2;
4522   return Meld(arr);
4523 }
4524
4525 /*!
4526  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4527  * of components in the result array is a sum of the number of components of given arrays
4528  * and (2) the number of tuples in the result array is same as that of each of given
4529  * arrays. In other words the i-th tuple of result array includes all components of
4530  * i-th tuples of all given arrays.
4531  * Number of tuples in the given arrays must be  the same.
4532  *  \param [in] arr - a sequence of arrays to include in the result array.
4533  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4534  *          The caller is to delete this result array using decrRef() as it is no more
4535  *          needed.
4536  *  \throw If all arrays within \a arr are NULL.
4537  *  \throw If any given array is not allocated.
4538  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4539  */
4540 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4541 {
4542   std::vector<const DataArrayDouble *> a;
4543   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4544     if(*it4)
4545       a.push_back(*it4);
4546   if(a.empty())
4547     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4548   std::vector<const DataArrayDouble *>::const_iterator it;
4549   for(it=a.begin();it!=a.end();it++)
4550     (*it)->checkAllocated();
4551   it=a.begin();
4552   int nbOfTuples=(*it)->getNumberOfTuples();
4553   std::vector<int> nbc(a.size());
4554   std::vector<const double *> pts(a.size());
4555   nbc[0]=(*it)->getNumberOfComponents();
4556   pts[0]=(*it++)->getConstPointer();
4557   for(int i=1;it!=a.end();it++,i++)
4558     {
4559       if(nbOfTuples!=(*it)->getNumberOfTuples())
4560         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4561       nbc[i]=(*it)->getNumberOfComponents();
4562       pts[i]=(*it)->getConstPointer();
4563     }
4564   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4565   DataArrayDouble *ret=DataArrayDouble::New();
4566   ret->alloc(nbOfTuples,totalNbOfComp);
4567   double *retPtr=ret->getPointer();
4568   for(int i=0;i<nbOfTuples;i++)
4569     for(int j=0;j<(int)a.size();j++)
4570       {
4571         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4572         pts[j]+=nbc[j];
4573       }
4574   int k=0;
4575   for(int i=0;i<(int)a.size();i++)
4576     for(int j=0;j<nbc[i];j++,k++)
4577       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4578   return ret;
4579 }
4580
4581 /*!
4582  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4583  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4584  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4585  * Info on components and name is copied from the first of the given arrays.
4586  * Number of tuples and components in the given arrays must be the same.
4587  *  \param [in] a1 - a given array.
4588  *  \param [in] a2 - another given array.
4589  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4590  *          The caller is to delete this result array using decrRef() as it is no more
4591  *          needed.
4592  *  \throw If either \a a1 or \a a2 is NULL.
4593  *  \throw If any given array is not allocated.
4594  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4595  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4596  */
4597 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4598 {
4599   if(!a1 || !a2)
4600     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4601   a1->checkAllocated();
4602   a2->checkAllocated();
4603   int nbOfComp=a1->getNumberOfComponents();
4604   if(nbOfComp!=a2->getNumberOfComponents())
4605     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4606   int nbOfTuple=a1->getNumberOfTuples();
4607   if(nbOfTuple!=a2->getNumberOfTuples())
4608     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4609   DataArrayDouble *ret=DataArrayDouble::New();
4610   ret->alloc(nbOfTuple,1);
4611   double *retPtr=ret->getPointer();
4612   const double *a1Ptr=a1->getConstPointer();
4613   const double *a2Ptr=a2->getConstPointer();
4614   for(int i=0;i<nbOfTuple;i++)
4615     {
4616       double sum=0.;
4617       for(int j=0;j<nbOfComp;j++)
4618         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4619       retPtr[i]=sum;
4620     }
4621   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4622   ret->setName(a1->getName().c_str());
4623   return ret;
4624 }
4625
4626 /*!
4627  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4628  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4629  * product of two vectors defined by the i-th tuples of given arrays.
4630  * Info on components is copied from the first of the given arrays.
4631  * Number of tuples in the given arrays must be the same.
4632  * Number of components in the given arrays must be 3.
4633  *  \param [in] a1 - a given array.
4634  *  \param [in] a2 - another given array.
4635  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4636  *          The caller is to delete this result array using decrRef() as it is no more
4637  *          needed.
4638  *  \throw If either \a a1 or \a a2 is NULL.
4639  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4640  *  \throw If \a a1->getNumberOfComponents() != 3
4641  *  \throw If \a a2->getNumberOfComponents() != 3
4642  */
4643 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4644 {
4645   if(!a1 || !a2)
4646     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4647   int nbOfComp=a1->getNumberOfComponents();
4648   if(nbOfComp!=a2->getNumberOfComponents())
4649     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4650   if(nbOfComp!=3)
4651     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4652   int nbOfTuple=a1->getNumberOfTuples();
4653   if(nbOfTuple!=a2->getNumberOfTuples())
4654     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4655   DataArrayDouble *ret=DataArrayDouble::New();
4656   ret->alloc(nbOfTuple,3);
4657   double *retPtr=ret->getPointer();
4658   const double *a1Ptr=a1->getConstPointer();
4659   const double *a2Ptr=a2->getConstPointer();
4660   for(int i=0;i<nbOfTuple;i++)
4661     {
4662       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4663       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4664       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4665     }
4666   ret->copyStringInfoFrom(*a1);
4667   return ret;
4668 }
4669
4670 /*!
4671  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4672  * Info on components is copied from the first of the given arrays.
4673  * Number of tuples and components in the given arrays must be the same.
4674  *  \param [in] a1 - an array to compare values with another one.
4675  *  \param [in] a2 - another array to compare values with the first one.
4676  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4677  *          The caller is to delete this result array using decrRef() as it is no more
4678  *          needed.
4679  *  \throw If either \a a1 or \a a2 is NULL.
4680  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4681  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4682  */
4683 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4684 {
4685   if(!a1 || !a2)
4686     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4687   int nbOfComp=a1->getNumberOfComponents();
4688   if(nbOfComp!=a2->getNumberOfComponents())
4689     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4690   int nbOfTuple=a1->getNumberOfTuples();
4691   if(nbOfTuple!=a2->getNumberOfTuples())
4692     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4693   DataArrayDouble *ret=DataArrayDouble::New();
4694   ret->alloc(nbOfTuple,nbOfComp);
4695   double *retPtr=ret->getPointer();
4696   const double *a1Ptr=a1->getConstPointer();
4697   const double *a2Ptr=a2->getConstPointer();
4698   int nbElem=nbOfTuple*nbOfComp;
4699   for(int i=0;i<nbElem;i++)
4700     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4701   ret->copyStringInfoFrom(*a1);
4702   return ret;
4703 }
4704
4705 /*!
4706  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4707  * Info on components is copied from the first of the given arrays.
4708  * Number of tuples and components in the given arrays must be the same.
4709  *  \param [in] a1 - an array to compare values with another one.
4710  *  \param [in] a2 - another array to compare values with the first one.
4711  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4712  *          The caller is to delete this result array using decrRef() as it is no more
4713  *          needed.
4714  *  \throw If either \a a1 or \a a2 is NULL.
4715  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4716  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4717  */
4718 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4719 {
4720   if(!a1 || !a2)
4721     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4722   int nbOfComp=a1->getNumberOfComponents();
4723   if(nbOfComp!=a2->getNumberOfComponents())
4724     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4725   int nbOfTuple=a1->getNumberOfTuples();
4726   if(nbOfTuple!=a2->getNumberOfTuples())
4727     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4728   DataArrayDouble *ret=DataArrayDouble::New();
4729   ret->alloc(nbOfTuple,nbOfComp);
4730   double *retPtr=ret->getPointer();
4731   const double *a1Ptr=a1->getConstPointer();
4732   const double *a2Ptr=a2->getConstPointer();
4733   int nbElem=nbOfTuple*nbOfComp;
4734   for(int i=0;i<nbElem;i++)
4735     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4736   ret->copyStringInfoFrom(*a1);
4737   return ret;
4738 }
4739
4740 /*!
4741  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4742  * valid cases.
4743  * 1.  The arrays have same number of tuples and components. Then each value of
4744  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4745  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4746  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4747  *   component. Then
4748  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4749  * 3.  The arrays have same number of components and one array, say _a2_, has one
4750  *   tuple. Then
4751  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4752  *
4753  * Info on components is copied either from the first array (in the first case) or from
4754  * the array with maximal number of elements (getNbOfElems()).
4755  *  \param [in] a1 - an array to sum up.
4756  *  \param [in] a2 - another array to sum up.
4757  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4758  *          The caller is to delete this result array using decrRef() as it is no more
4759  *          needed.
4760  *  \throw If either \a a1 or \a a2 is NULL.
4761  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4762  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4763  *         none of them has number of tuples or components equal to 1.
4764  */
4765 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4766 {
4767   if(!a1 || !a2)
4768     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4769   int nbOfTuple=a1->getNumberOfTuples();
4770   int nbOfTuple2=a2->getNumberOfTuples();
4771   int nbOfComp=a1->getNumberOfComponents();
4772   int nbOfComp2=a2->getNumberOfComponents();
4773   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4774   if(nbOfTuple==nbOfTuple2)
4775     {
4776       if(nbOfComp==nbOfComp2)
4777         {
4778           ret=DataArrayDouble::New();
4779           ret->alloc(nbOfTuple,nbOfComp);
4780           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4781           ret->copyStringInfoFrom(*a1);
4782         }
4783       else
4784         {
4785           int nbOfCompMin,nbOfCompMax;
4786           const DataArrayDouble *aMin, *aMax;
4787           if(nbOfComp>nbOfComp2)
4788             {
4789               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4790               aMin=a2; aMax=a1;
4791             }
4792           else
4793             {
4794               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4795               aMin=a1; aMax=a2;
4796             }
4797           if(nbOfCompMin==1)
4798             {
4799               ret=DataArrayDouble::New();
4800               ret->alloc(nbOfTuple,nbOfCompMax);
4801               const double *aMinPtr=aMin->getConstPointer();
4802               const double *aMaxPtr=aMax->getConstPointer();
4803               double *res=ret->getPointer();
4804               for(int i=0;i<nbOfTuple;i++)
4805                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4806               ret->copyStringInfoFrom(*aMax);
4807             }
4808           else
4809             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4810         }
4811     }
4812   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4813     {
4814       if(nbOfComp==nbOfComp2)
4815         {
4816           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4817           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4818           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4819           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4820           ret=DataArrayDouble::New();
4821           ret->alloc(nbOfTupleMax,nbOfComp);
4822           double *res=ret->getPointer();
4823           for(int i=0;i<nbOfTupleMax;i++)
4824             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4825           ret->copyStringInfoFrom(*aMax);
4826         }
4827       else
4828         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4829     }
4830   else
4831     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4832   return ret.retn();
4833 }
4834
4835 /*!
4836  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4837  * valid cases.
4838  * 1.  The arrays have same number of tuples and components. Then each value of
4839  *   \a other array is added to the corresponding value of \a this array, i.e.:
4840  *   _a_ [ i, j ] += _other_ [ i, j ].
4841  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4842  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4843  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4844  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4845  *
4846  *  \param [in] other - an array to add to \a this one.
4847  *  \throw If \a other is NULL.
4848  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4849  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4850  *         \a other has number of both tuples and components not equal to 1.
4851  */
4852 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4853 {
4854   if(!other)
4855     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4856   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4857   checkAllocated();
4858   other->checkAllocated();
4859   int nbOfTuple=getNumberOfTuples();
4860   int nbOfTuple2=other->getNumberOfTuples();
4861   int nbOfComp=getNumberOfComponents();
4862   int nbOfComp2=other->getNumberOfComponents();
4863   if(nbOfTuple==nbOfTuple2)
4864     {
4865       if(nbOfComp==nbOfComp2)
4866         {
4867           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4868         }
4869       else if(nbOfComp2==1)
4870         {
4871           double *ptr=getPointer();
4872           const double *ptrc=other->getConstPointer();
4873           for(int i=0;i<nbOfTuple;i++)
4874             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4875         }
4876       else
4877         throw INTERP_KERNEL::Exception(msg);
4878     }
4879   else if(nbOfTuple2==1)
4880     {
4881       if(nbOfComp2==nbOfComp)
4882         {
4883           double *ptr=getPointer();
4884           const double *ptrc=other->getConstPointer();
4885           for(int i=0;i<nbOfTuple;i++)
4886             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4887         }
4888       else
4889         throw INTERP_KERNEL::Exception(msg);
4890     }
4891   else
4892     throw INTERP_KERNEL::Exception(msg);
4893   declareAsNew();
4894 }
4895
4896 /*!
4897  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4898  * valid cases.
4899  * 1.  The arrays have same number of tuples and components. Then each value of
4900  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4901  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4902  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4903  *   component. Then
4904  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4905  * 3.  The arrays have same number of components and one array, say _a2_, has one
4906  *   tuple. Then
4907  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4908  *
4909  * Info on components is copied either from the first array (in the first case) or from
4910  * the array with maximal number of elements (getNbOfElems()).
4911  *  \param [in] a1 - an array to subtract from.
4912  *  \param [in] a2 - an array to subtract.
4913  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4914  *          The caller is to delete this result array using decrRef() as it is no more
4915  *          needed.
4916  *  \throw If either \a a1 or \a a2 is NULL.
4917  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4918  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4919  *         none of them has number of tuples or components equal to 1.
4920  */
4921 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4922 {
4923   if(!a1 || !a2)
4924     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4925   int nbOfTuple1=a1->getNumberOfTuples();
4926   int nbOfTuple2=a2->getNumberOfTuples();
4927   int nbOfComp1=a1->getNumberOfComponents();
4928   int nbOfComp2=a2->getNumberOfComponents();
4929   if(nbOfTuple2==nbOfTuple1)
4930     {
4931       if(nbOfComp1==nbOfComp2)
4932         {
4933           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4934           ret->alloc(nbOfTuple2,nbOfComp1);
4935           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4936           ret->copyStringInfoFrom(*a1);
4937           return ret.retn();
4938         }
4939       else if(nbOfComp2==1)
4940         {
4941           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4942           ret->alloc(nbOfTuple1,nbOfComp1);
4943           const double *a2Ptr=a2->getConstPointer();
4944           const double *a1Ptr=a1->getConstPointer();
4945           double *res=ret->getPointer();
4946           for(int i=0;i<nbOfTuple1;i++)
4947             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4948           ret->copyStringInfoFrom(*a1);
4949           return ret.retn();
4950         }
4951       else
4952         {
4953           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4954           return 0;
4955         }
4956     }
4957   else if(nbOfTuple2==1)
4958     {
4959       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4960       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4961       ret->alloc(nbOfTuple1,nbOfComp1);
4962       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4963       double *pt=ret->getPointer();
4964       for(int i=0;i<nbOfTuple1;i++)
4965         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4966       ret->copyStringInfoFrom(*a1);
4967       return ret.retn();
4968     }
4969   else
4970     {
4971       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4972       return 0;
4973     }
4974 }
4975
4976 /*!
4977  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4978  * valid cases.
4979  * 1.  The arrays have same number of tuples and components. Then each value of
4980  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4981  *   _a_ [ i, j ] -= _other_ [ i, j ].
4982  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4983  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4984  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4985  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4986  *
4987  *  \param [in] other - an array to subtract from \a this one.
4988  *  \throw If \a other is NULL.
4989  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4990  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4991  *         \a other has number of both tuples and components not equal to 1.
4992  */
4993 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4994 {
4995   if(!other)
4996     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4997   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4998   checkAllocated();
4999   other->checkAllocated();
5000   int nbOfTuple=getNumberOfTuples();
5001   int nbOfTuple2=other->getNumberOfTuples();
5002   int nbOfComp=getNumberOfComponents();
5003   int nbOfComp2=other->getNumberOfComponents();
5004   if(nbOfTuple==nbOfTuple2)
5005     {
5006       if(nbOfComp==nbOfComp2)
5007         {
5008           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5009         }
5010       else if(nbOfComp2==1)
5011         {
5012           double *ptr=getPointer();
5013           const double *ptrc=other->getConstPointer();
5014           for(int i=0;i<nbOfTuple;i++)
5015             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5016         }
5017       else
5018         throw INTERP_KERNEL::Exception(msg);
5019     }
5020   else if(nbOfTuple2==1)
5021     {
5022       if(nbOfComp2==nbOfComp)
5023         {
5024           double *ptr=getPointer();
5025           const double *ptrc=other->getConstPointer();
5026           for(int i=0;i<nbOfTuple;i++)
5027             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5028         }
5029       else
5030         throw INTERP_KERNEL::Exception(msg);
5031     }
5032   else
5033     throw INTERP_KERNEL::Exception(msg);
5034   declareAsNew();
5035 }
5036
5037 /*!
5038  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5039  * valid cases.
5040  * 1.  The arrays have same number of tuples and components. Then each value of
5041  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5042  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5043  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5044  *   component. Then
5045  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5046  * 3.  The arrays have same number of components and one array, say _a2_, has one
5047  *   tuple. Then
5048  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5049  *
5050  * Info on components is copied either from the first array (in the first case) or from
5051  * the array with maximal number of elements (getNbOfElems()).
5052  *  \param [in] a1 - a factor array.
5053  *  \param [in] a2 - another factor array.
5054  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5055  *          The caller is to delete this result array using decrRef() as it is no more
5056  *          needed.
5057  *  \throw If either \a a1 or \a a2 is NULL.
5058  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5059  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5060  *         none of them has number of tuples or components equal to 1.
5061  */
5062 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5063 {
5064   if(!a1 || !a2)
5065     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5066   int nbOfTuple=a1->getNumberOfTuples();
5067   int nbOfTuple2=a2->getNumberOfTuples();
5068   int nbOfComp=a1->getNumberOfComponents();
5069   int nbOfComp2=a2->getNumberOfComponents();
5070   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5071   if(nbOfTuple==nbOfTuple2)
5072     {
5073       if(nbOfComp==nbOfComp2)
5074         {
5075           ret=DataArrayDouble::New();
5076           ret->alloc(nbOfTuple,nbOfComp);
5077           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5078           ret->copyStringInfoFrom(*a1);
5079         }
5080       else
5081         {
5082           int nbOfCompMin,nbOfCompMax;
5083           const DataArrayDouble *aMin, *aMax;
5084           if(nbOfComp>nbOfComp2)
5085             {
5086               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5087               aMin=a2; aMax=a1;
5088             }
5089           else
5090             {
5091               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5092               aMin=a1; aMax=a2;
5093             }
5094           if(nbOfCompMin==1)
5095             {
5096               ret=DataArrayDouble::New();
5097               ret->alloc(nbOfTuple,nbOfCompMax);
5098               const double *aMinPtr=aMin->getConstPointer();
5099               const double *aMaxPtr=aMax->getConstPointer();
5100               double *res=ret->getPointer();
5101               for(int i=0;i<nbOfTuple;i++)
5102                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5103               ret->copyStringInfoFrom(*aMax);
5104             }
5105           else
5106             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5107         }
5108     }
5109   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5110     {
5111       if(nbOfComp==nbOfComp2)
5112         {
5113           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5114           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5115           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5116           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5117           ret=DataArrayDouble::New();
5118           ret->alloc(nbOfTupleMax,nbOfComp);
5119           double *res=ret->getPointer();
5120           for(int i=0;i<nbOfTupleMax;i++)
5121             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5122           ret->copyStringInfoFrom(*aMax);
5123         }
5124       else
5125         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5126     }
5127   else
5128     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5129   return ret.retn();
5130 }
5131
5132 /*!
5133  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5134  * valid cases.
5135  * 1.  The arrays have same number of tuples and components. Then each value of
5136  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5137  *   _this_ [ i, j ] *= _other_ [ i, j ].
5138  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5139  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5140  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5141  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5142  *
5143  *  \param [in] other - an array to multiply to \a this one.
5144  *  \throw If \a other is NULL.
5145  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5146  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5147  *         \a other has number of both tuples and components not equal to 1.
5148  */
5149 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5150 {
5151   if(!other)
5152     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5153   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5154   checkAllocated();
5155   other->checkAllocated();
5156   int nbOfTuple=getNumberOfTuples();
5157   int nbOfTuple2=other->getNumberOfTuples();
5158   int nbOfComp=getNumberOfComponents();
5159   int nbOfComp2=other->getNumberOfComponents();
5160   if(nbOfTuple==nbOfTuple2)
5161     {
5162       if(nbOfComp==nbOfComp2)
5163         {
5164           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5165         }
5166       else if(nbOfComp2==1)
5167         {
5168           double *ptr=getPointer();
5169           const double *ptrc=other->getConstPointer();
5170           for(int i=0;i<nbOfTuple;i++)
5171             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5172         }
5173       else
5174         throw INTERP_KERNEL::Exception(msg);
5175     }
5176   else if(nbOfTuple2==1)
5177     {
5178       if(nbOfComp2==nbOfComp)
5179         {
5180           double *ptr=getPointer();
5181           const double *ptrc=other->getConstPointer();
5182           for(int i=0;i<nbOfTuple;i++)
5183             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5184         }
5185       else
5186         throw INTERP_KERNEL::Exception(msg);
5187     }
5188   else
5189     throw INTERP_KERNEL::Exception(msg);
5190   declareAsNew();
5191 }
5192
5193 /*!
5194  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5195  * valid cases.
5196  * 1.  The arrays have same number of tuples and components. Then each value of
5197  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5198  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5199  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5200  *   component. Then
5201  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5202  * 3.  The arrays have same number of components and one array, say _a2_, has one
5203  *   tuple. Then
5204  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5205  *
5206  * Info on components is copied either from the first array (in the first case) or from
5207  * the array with maximal number of elements (getNbOfElems()).
5208  *  \warning No check of division by zero is performed!
5209  *  \param [in] a1 - a numerator array.
5210  *  \param [in] a2 - a denominator array.
5211  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5212  *          The caller is to delete this result array using decrRef() as it is no more
5213  *          needed.
5214  *  \throw If either \a a1 or \a a2 is NULL.
5215  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5216  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5217  *         none of them has number of tuples or components equal to 1.
5218  */
5219 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5220 {
5221   if(!a1 || !a2)
5222     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5223   int nbOfTuple1=a1->getNumberOfTuples();
5224   int nbOfTuple2=a2->getNumberOfTuples();
5225   int nbOfComp1=a1->getNumberOfComponents();
5226   int nbOfComp2=a2->getNumberOfComponents();
5227   if(nbOfTuple2==nbOfTuple1)
5228     {
5229       if(nbOfComp1==nbOfComp2)
5230         {
5231           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5232           ret->alloc(nbOfTuple2,nbOfComp1);
5233           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5234           ret->copyStringInfoFrom(*a1);
5235           return ret.retn();
5236         }
5237       else if(nbOfComp2==1)
5238         {
5239           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5240           ret->alloc(nbOfTuple1,nbOfComp1);
5241           const double *a2Ptr=a2->getConstPointer();
5242           const double *a1Ptr=a1->getConstPointer();
5243           double *res=ret->getPointer();
5244           for(int i=0;i<nbOfTuple1;i++)
5245             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5246           ret->copyStringInfoFrom(*a1);
5247           return ret.retn();
5248         }
5249       else
5250         {
5251           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5252           return 0;
5253         }
5254     }
5255   else if(nbOfTuple2==1)
5256     {
5257       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5258       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5259       ret->alloc(nbOfTuple1,nbOfComp1);
5260       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5261       double *pt=ret->getPointer();
5262       for(int i=0;i<nbOfTuple1;i++)
5263         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5264       ret->copyStringInfoFrom(*a1);
5265       return ret.retn();
5266     }
5267   else
5268     {
5269       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5270       return 0;
5271     }
5272 }
5273
5274 /*!
5275  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5276  * valid cases.
5277  * 1.  The arrays have same number of tuples and components. Then each value of
5278  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5279  *   _a_ [ i, j ] /= _other_ [ i, j ].
5280  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5281  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5282  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5283  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5284  *
5285  *  \warning No check of division by zero is performed!
5286  *  \param [in] other - an array to divide \a this one by.
5287  *  \throw If \a other is NULL.
5288  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5289  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5290  *         \a other has number of both tuples and components not equal to 1.
5291  */
5292 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5293 {
5294   if(!other)
5295     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5296   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5297   checkAllocated();
5298   other->checkAllocated();
5299   int nbOfTuple=getNumberOfTuples();
5300   int nbOfTuple2=other->getNumberOfTuples();
5301   int nbOfComp=getNumberOfComponents();
5302   int nbOfComp2=other->getNumberOfComponents();
5303   if(nbOfTuple==nbOfTuple2)
5304     {
5305       if(nbOfComp==nbOfComp2)
5306         {
5307           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5308         }
5309       else if(nbOfComp2==1)
5310         {
5311           double *ptr=getPointer();
5312           const double *ptrc=other->getConstPointer();
5313           for(int i=0;i<nbOfTuple;i++)
5314             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5315         }
5316       else
5317         throw INTERP_KERNEL::Exception(msg);
5318     }
5319   else if(nbOfTuple2==1)
5320     {
5321       if(nbOfComp2==nbOfComp)
5322         {
5323           double *ptr=getPointer();
5324           const double *ptrc=other->getConstPointer();
5325           for(int i=0;i<nbOfTuple;i++)
5326             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5327         }
5328       else
5329         throw INTERP_KERNEL::Exception(msg);
5330     }
5331   else
5332     throw INTERP_KERNEL::Exception(msg);
5333   declareAsNew();
5334 }
5335
5336 /*!
5337  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5338  * valid cases.
5339  *
5340  *  \param [in] a1 - an array to pow up.
5341  *  \param [in] a2 - another array to sum up.
5342  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5343  *          The caller is to delete this result array using decrRef() as it is no more
5344  *          needed.
5345  *  \throw If either \a a1 or \a a2 is NULL.
5346  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5347  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5348  *  \throw If there is a negative value in \a a1.
5349  */
5350 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5351 {
5352   if(!a1 || !a2)
5353     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5354   int nbOfTuple=a1->getNumberOfTuples();
5355   int nbOfTuple2=a2->getNumberOfTuples();
5356   int nbOfComp=a1->getNumberOfComponents();
5357   int nbOfComp2=a2->getNumberOfComponents();
5358   if(nbOfTuple!=nbOfTuple2)
5359     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5360   if(nbOfComp!=1 || nbOfComp2!=1)
5361     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5362   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5363   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5364   double *ptr=ret->getPointer();
5365   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5366     {
5367       if(*ptr1>=0)
5368         {
5369           *ptr=pow(*ptr1,*ptr2);
5370         }
5371       else
5372         {
5373           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5374           throw INTERP_KERNEL::Exception(oss.str().c_str());
5375         }
5376     }
5377   return ret.retn();
5378 }
5379
5380 /*!
5381  * Apply pow on values of another DataArrayDouble to values of \a this one.
5382  *
5383  *  \param [in] other - an array to pow to \a this one.
5384  *  \throw If \a other is NULL.
5385  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5386  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5387  *  \throw If there is a negative value in \a this.
5388  */
5389 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5390 {
5391   if(!other)
5392     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5393   int nbOfTuple=getNumberOfTuples();
5394   int nbOfTuple2=other->getNumberOfTuples();
5395   int nbOfComp=getNumberOfComponents();
5396   int nbOfComp2=other->getNumberOfComponents();
5397   if(nbOfTuple!=nbOfTuple2)
5398     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5399   if(nbOfComp!=1 || nbOfComp2!=1)
5400     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5401   double *ptr=getPointer();
5402   const double *ptrc=other->begin();
5403   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5404     {
5405       if(*ptr>=0)
5406         *ptr=pow(*ptr,*ptrc);
5407       else
5408         {
5409           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5410           throw INTERP_KERNEL::Exception(oss.str().c_str());
5411         }
5412     }
5413   declareAsNew();
5414 }
5415
5416 /*!
5417  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5418  * Server side.
5419  */
5420 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5421 {
5422   tinyInfo.resize(2);
5423   if(isAllocated())
5424     {
5425       tinyInfo[0]=getNumberOfTuples();
5426       tinyInfo[1]=getNumberOfComponents();
5427     }
5428   else
5429     {
5430       tinyInfo[0]=-1;
5431       tinyInfo[1]=-1;
5432     }
5433 }
5434
5435 /*!
5436  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5437  * Server side.
5438  */
5439 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5440 {
5441   if(isAllocated())
5442     {
5443       int nbOfCompo=getNumberOfComponents();
5444       tinyInfo.resize(nbOfCompo+1);
5445       tinyInfo[0]=getName();
5446       for(int i=0;i<nbOfCompo;i++)
5447         tinyInfo[i+1]=getInfoOnComponent(i);
5448     }
5449   else
5450     {
5451       tinyInfo.resize(1);
5452       tinyInfo[0]=getName();
5453     }
5454 }
5455
5456 /*!
5457  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5458  * This method returns if a feeding is needed.
5459  */
5460 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5461 {
5462   int nbOfTuple=tinyInfoI[0];
5463   int nbOfComp=tinyInfoI[1];
5464   if(nbOfTuple!=-1 || nbOfComp!=-1)
5465     {
5466       alloc(nbOfTuple,nbOfComp);
5467       return true;
5468     }
5469   return false;
5470 }
5471
5472 /*!
5473  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5474  */
5475 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5476 {
5477   setName(tinyInfoS[0].c_str());
5478   if(isAllocated())
5479     {
5480       int nbOfCompo=getNumberOfComponents();
5481       for(int i=0;i<nbOfCompo;i++)
5482         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5483     }
5484 }
5485
5486 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5487 {
5488   if(_da)
5489     {
5490       _da->incrRef();
5491       if(_da->isAllocated())
5492         {
5493           _nb_comp=da->getNumberOfComponents();
5494           _nb_tuple=da->getNumberOfTuples();
5495           _pt=da->getPointer();
5496         }
5497     }
5498 }
5499
5500 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5501 {
5502   if(_da)
5503     _da->decrRef();
5504 }
5505
5506 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5507 {
5508   if(_tuple_id<_nb_tuple)
5509     {
5510       _tuple_id++;
5511       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5512       _pt+=_nb_comp;
5513       return ret;
5514     }
5515   else
5516     return 0;
5517 }
5518
5519 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5520 {
5521 }
5522
5523
5524 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5525 {
5526   std::ostringstream oss; oss.precision(17); oss << "(";
5527   for(int i=0;i<_nb_of_compo-1;i++)
5528     oss << _pt[i] << ", ";
5529   oss << _pt[_nb_of_compo-1] << ")";
5530   return oss.str();
5531 }
5532
5533 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5534 {
5535   if(_nb_of_compo==1)
5536     return *_pt;
5537   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5538 }
5539
5540 /*!
5541  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5542  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5543  * 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
5544  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5545  */
5546 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5547 {
5548   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5549     {
5550       DataArrayDouble *ret=DataArrayDouble::New();
5551       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5552       return ret;
5553     }
5554   else
5555     {
5556       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5557       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5558       throw INTERP_KERNEL::Exception(oss.str().c_str());
5559     }
5560 }
5561
5562 /*!
5563  * Returns a new instance of DataArrayInt. The caller is to delete this array
5564  * using decrRef() as it is no more needed. 
5565  */
5566 DataArrayInt *DataArrayInt::New()
5567 {
5568   return new DataArrayInt;
5569 }
5570
5571 /*!
5572  * Checks if raw data is allocated. Read more on the raw data
5573  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5574  *  \return bool - \a true if the raw data is allocated, \a false else.
5575  */
5576 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5577 {
5578   return getConstPointer()!=0;
5579 }
5580
5581 /*!
5582  * Checks if raw data is allocated and throws an exception if it is not the case.
5583  *  \throw If the raw data is not allocated.
5584  */
5585 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5586 {
5587   if(!isAllocated())
5588     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5589 }
5590
5591 /*!
5592  * This method desallocated \a this without modification of informations relative to the components.
5593  * After call of this method, DataArrayInt::isAllocated will return false.
5594  * If \a this is already not allocated, \a this is let unchanged.
5595  */
5596 void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
5597 {
5598   _mem.destroy();
5599 }
5600
5601 std::size_t DataArrayInt::getHeapMemorySize() const
5602 {
5603   std::size_t sz=_mem.getNbOfElemAllocated();
5604   sz*=sizeof(int);
5605   return DataArray::getHeapMemorySize()+sz;
5606 }
5607
5608 /*!
5609  * Returns the only one value in \a this, if and only if number of elements
5610  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5611  *  \return double - the sole value stored in \a this array.
5612  *  \throw If at least one of conditions stated above is not fulfilled.
5613  */
5614 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5615 {
5616   if(isAllocated())
5617     {
5618       if(getNbOfElems()==1)
5619         {
5620           return *getConstPointer();
5621         }
5622       else
5623         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5624     }
5625   else
5626     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5627 }
5628
5629 /*!
5630  * Returns an integer value characterizing \a this array, which is useful for a quick
5631  * comparison of many instances of DataArrayInt.
5632  *  \return int - the hash value.
5633  *  \throw If \a this is not allocated.
5634  */
5635 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5636 {
5637   checkAllocated();
5638   std::size_t nbOfElems=getNbOfElems();
5639   int ret=nbOfElems*65536;
5640   int delta=3;
5641   if(nbOfElems>48)
5642     delta=nbOfElems/8;
5643   int ret0=0;
5644   const int *pt=begin();
5645   for(std::size_t i=0;i<nbOfElems;i+=delta)
5646     ret0+=pt[i] & 0x1FFF;
5647   return ret+ret0;
5648 }
5649
5650 /*!
5651  * Checks the number of tuples.
5652  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5653  *  \throw If \a this is not allocated.
5654  */
5655 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5656 {
5657   checkAllocated();
5658   return getNumberOfTuples()==0;
5659 }
5660
5661 /*!
5662  * Returns a full copy of \a this. For more info on copying data arrays see
5663  * \ref MEDCouplingArrayBasicsCopyDeep.
5664  *  \return DataArrayInt * - a new instance of DataArrayInt.
5665  */
5666 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5667 {
5668   return new DataArrayInt(*this);
5669 }
5670
5671 /*!
5672  * Returns either a \a deep or \a shallow copy of this array. For more info see
5673  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5674  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5675  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5676  *          == \a true) or \a this instance (if \a dCpy == \a false).
5677  */
5678 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5679 {
5680   if(dCpy)
5681     return deepCpy();
5682   else
5683     {
5684       incrRef();
5685       return const_cast<DataArrayInt *>(this);
5686     }
5687 }
5688
5689 /*!
5690  * Copies all the data from another DataArrayInt. For more info see
5691  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5692  *  \param [in] other - another instance of DataArrayInt to copy data from.
5693  *  \throw If the \a other is not allocated.
5694  */
5695 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5696 {
5697   other.checkAllocated();
5698   int nbOfTuples=other.getNumberOfTuples();
5699   int nbOfComp=other.getNumberOfComponents();
5700   allocIfNecessary(nbOfTuples,nbOfComp);
5701   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5702   int *pt=getPointer();
5703   const int *ptI=other.getConstPointer();
5704   for(std::size_t i=0;i<nbOfElems;i++)
5705     pt[i]=ptI[i];
5706   copyStringInfoFrom(other);
5707 }
5708
5709 /*!
5710  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5711  * 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.
5712  * If \a this has not already been allocated, number of components is set to one.
5713  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5714  * 
5715  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5716  */
5717 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5718 {
5719   int nbCompo=getNumberOfComponents();
5720   if(nbCompo==1)
5721     {
5722       _mem.reserve(nbOfElems);
5723     }
5724   else if(nbCompo==0)
5725     {
5726       _mem.reserve(nbOfElems);
5727       _info_on_compo.resize(1);
5728     }
5729   else
5730     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5731 }
5732
5733 /*!
5734  * 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
5735  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5736  *
5737  * \param [in] val the value to be added in \a this
5738  * \throw If \a this has already been allocated with number of components different from one.
5739  * \sa DataArrayInt::pushBackValsSilent
5740  */
5741 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5742 {
5743   int nbCompo=getNumberOfComponents();
5744   if(nbCompo==1)
5745     _mem.pushBack(val);
5746   else if(nbCompo==0)
5747     {
5748       _info_on_compo.resize(1);
5749       _mem.pushBack(val);
5750     }
5751   else
5752     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5753 }
5754
5755 /*!
5756  * 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
5757  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5758  *
5759  *  \param [in] valsBg - an array of values to push at the end of \this.
5760  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5761  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5762  * \throw If \a this has already been allocated with number of components different from one.
5763  * \sa DataArrayInt::pushBackSilent
5764  */
5765 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5766 {
5767   int nbCompo=getNumberOfComponents();
5768   if(nbCompo==1)
5769     _mem.insertAtTheEnd(valsBg,valsEnd);
5770   else if(nbCompo==0)
5771     {
5772       _info_on_compo.resize(1);
5773       _mem.insertAtTheEnd(valsBg,valsEnd);
5774     }
5775   else
5776     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5777 }
5778
5779 /*!
5780  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5781  * \throw If \a this is already empty.
5782  * \throw If \a this has number of components different from one.
5783  */
5784 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5785 {
5786   if(getNumberOfComponents()==1)
5787     return _mem.popBack();
5788   else
5789     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5790 }
5791
5792 /*!
5793  * 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.
5794  *
5795  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5796  */
5797 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5798 {
5799   _mem.pack();
5800 }
5801
5802 /*!
5803  * Allocates the raw data in memory. If exactly as same memory as needed already
5804  * allocated, it is not re-allocated.
5805  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5806  *  \param [in] nbOfCompo - number of components of data to allocate.
5807  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5808  */
5809 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5810 {
5811   if(isAllocated())
5812     {
5813       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5814         alloc(nbOfTuple,nbOfCompo);
5815     }
5816   else
5817     alloc(nbOfTuple,nbOfCompo);
5818 }
5819
5820 /*!
5821  * Allocates the raw data in memory. If the memory was already allocated, then it is
5822  * freed and re-allocated. See an example of this method use
5823  * \ref MEDCouplingArraySteps1WC "here".
5824  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5825  *  \param [in] nbOfCompo - number of components of data to allocate.
5826  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5827  */
5828 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5829 {
5830   if(nbOfTuple<0 || nbOfCompo<0)
5831     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5832   _info_on_compo.resize(nbOfCompo);
5833   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5834   declareAsNew();
5835 }
5836
5837 /*!
5838  * Assign zero to all values in \a this array. To know more on filling arrays see
5839  * \ref MEDCouplingArrayFill.
5840  * \throw If \a this is not allocated.
5841  */
5842 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5843 {
5844   checkAllocated();
5845   _mem.fillWithValue(0);
5846   declareAsNew();
5847 }
5848
5849 /*!
5850  * Assign \a val to all values in \a this array. To know more on filling arrays see
5851  * \ref MEDCouplingArrayFill.
5852  *  \param [in] val - the value to fill with.
5853  *  \throw If \a this is not allocated.
5854  */
5855 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5856 {
5857   checkAllocated();
5858   _mem.fillWithValue(val);
5859   declareAsNew();
5860 }
5861
5862 /*!
5863  * Set all values in \a this array so that the i-th element equals to \a init + i
5864  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5865  *  \param [in] init - value to assign to the first element of array.
5866  *  \throw If \a this->getNumberOfComponents() != 1
5867  *  \throw If \a this is not allocated.
5868  */
5869 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5870 {
5871   checkAllocated();
5872   if(getNumberOfComponents()!=1)
5873     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5874   int *ptr=getPointer();
5875   int ntuples=getNumberOfTuples();
5876   for(int i=0;i<ntuples;i++)
5877     ptr[i]=init+i;
5878   declareAsNew();
5879 }
5880
5881 /*!
5882  * Returns a textual and human readable representation of \a this instance of
5883  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5884  *  \return std::string - text describing \a this DataArrayInt.
5885  */
5886 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5887 {
5888   std::ostringstream ret;
5889   reprStream(ret);
5890   return ret.str();
5891 }
5892
5893 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5894 {
5895   std::ostringstream ret;
5896   reprZipStream(ret);
5897   return ret.str();
5898 }
5899
5900 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5901 {
5902   checkAllocated();
5903   std::string idt(indent,' ');
5904   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5905   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5906   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5907   ofs << std::endl << idt << "</DataArray>\n";
5908 }
5909
5910 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5911 {
5912   stream << "Name of int array : \"" << _name << "\"\n";
5913   reprWithoutNameStream(stream);
5914 }
5915
5916 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5917 {
5918   stream << "Name of int array : \"" << _name << "\"\n";
5919   reprZipWithoutNameStream(stream);
5920 }
5921
5922 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5923 {
5924   DataArray::reprWithoutNameStream(stream);
5925   _mem.repr(getNumberOfComponents(),stream);
5926 }
5927
5928 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5929 {
5930   DataArray::reprWithoutNameStream(stream);
5931   _mem.reprZip(getNumberOfComponents(),stream);
5932 }
5933
5934 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5935 {
5936   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5937   const int *data=getConstPointer();
5938   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5939   if(nbTuples*nbComp>=1)
5940     {
5941       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5942       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5943       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5944       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5945     }
5946   else
5947     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5948   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5949 }
5950
5951 /*!
5952  * Method that gives a quick overvien of \a this for python.
5953  */
5954 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5955 {
5956   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5957   stream << "DataArrayInt C++ instance at " << this << ". ";
5958   if(isAllocated())
5959     {
5960       int nbOfCompo=(int)_info_on_compo.size();
5961       if(nbOfCompo>=1)
5962         {
5963           int nbOfTuples=getNumberOfTuples();
5964           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5965           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5966         }
5967       else
5968         stream << "Number of components : 0.";
5969     }
5970   else
5971     stream << "*** No data allocated ****";
5972 }
5973
5974 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5975 {
5976   const int *data=begin();
5977   int nbOfTuples=getNumberOfTuples();
5978   int nbOfCompo=(int)_info_on_compo.size();
5979   std::ostringstream oss2; oss2 << "[";
5980   std::string oss2Str(oss2.str());
5981   bool isFinished=true;
5982   for(int i=0;i<nbOfTuples && isFinished;i++)
5983     {
5984       if(nbOfCompo>1)
5985         {
5986           oss2 << "(";
5987           for(int j=0;j<nbOfCompo;j++,data++)
5988             {
5989               oss2 << *data;
5990               if(j!=nbOfCompo-1) oss2 << ", ";
5991             }
5992           oss2 << ")";
5993         }
5994       else
5995         oss2 << *data++;
5996       if(i!=nbOfTuples-1) oss2 << ", ";
5997       std::string oss3Str(oss2.str());
5998       if(oss3Str.length()<maxNbOfByteInRepr)
5999         oss2Str=oss3Str;
6000       else
6001         isFinished=false;
6002     }
6003   stream << oss2Str;
6004   if(!isFinished)
6005     stream << "... ";
6006   stream << "]";
6007 }
6008
6009 /*!
6010  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6011  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6012  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6013  *         to \a this array.
6014  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6015  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6016  *  \throw If \a this->getNumberOfComponents() != 1
6017  *  \throw If any value of \a this can't be used as a valid index for 
6018  *         [\a indArrBg, \a indArrEnd).
6019  */
6020 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
6021 {
6022   checkAllocated();
6023   if(getNumberOfComponents()!=1)
6024     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6025   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6026   int nbOfTuples=getNumberOfTuples();
6027   int *pt=getPointer();
6028   for(int i=0;i<nbOfTuples;i++,pt++)
6029     {
6030       if(*pt>=0 && *pt<nbElemsIn)
6031         *pt=indArrBg[*pt];
6032       else
6033         {
6034           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6035           throw INTERP_KERNEL::Exception(oss.str().c_str());
6036         }
6037     }
6038   declareAsNew();
6039 }
6040
6041 /*!
6042  * Computes distribution of values of \a this one-dimensional array between given value
6043  * ranges (casts). This method is typically useful for entity number spliting by types,
6044  * for example. 
6045  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6046  *           check of this is be done. If not, the result is not warranted. 
6047  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6048  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6049  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6050  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6051  *         should be more than every value in \a this array.
6052  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6053  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6054  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6055  *         (same number of tuples and components), the caller is to delete 
6056  *         using decrRef() as it is no more needed.
6057  *         This array contains indices of ranges for every value of \a this array. I.e.
6058  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6059  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6060  *         this in which cast it holds.
6061  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6062  *         array, the caller is to delete using decrRef() as it is no more needed.
6063  *         This array contains ranks of values of \a this array within ranges
6064  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6065  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6066  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6067  *         for each tuple its rank inside its cast. The rank is computed as difference
6068  *         between the value and the lowest value of range.
6069  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6070  *         ranges (casts) to which at least one value of \a this array belongs.
6071  *         Or, in other words, this param contains the casts that \a this contains.
6072  *         The caller is to delete this array using decrRef() as it is no more needed.
6073  *
6074  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6075  *            the output of this method will be : 
6076  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6077  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6078  * - \a castsPresent  : [0,1]
6079  *
6080  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6081  * range #1 and its rank within this range is 2; etc.
6082  *
6083  *  \throw If \a this->getNumberOfComponents() != 1.
6084  *  \throw If \a arrEnd - arrBg < 2.
6085  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6086  */
6087 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6088                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6089 {
6090   checkAllocated();
6091   if(getNumberOfComponents()!=1)
6092     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6093   int nbOfTuples=getNumberOfTuples();
6094   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6095   if(nbOfCast<2)
6096     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6097   nbOfCast--;
6098   const int *work=getConstPointer();
6099   typedef std::reverse_iterator<const int *> rintstart;
6100   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6101   rintstart end2(arrBg);
6102   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6103   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6104   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6105   ret1->alloc(nbOfTuples,1);
6106   ret2->alloc(nbOfTuples,1);
6107   int *ret1Ptr=ret1->getPointer();
6108   int *ret2Ptr=ret2->getPointer();
6109   std::set<std::size_t> castsDetected;
6110   for(int i=0;i<nbOfTuples;i++)
6111     {
6112       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6113       std::size_t pos=std::distance(bg,res);
6114       std::size_t pos2=nbOfCast-pos;
6115       if(pos2<nbOfCast)
6116         {
6117           ret1Ptr[i]=(int)pos2;
6118           ret2Ptr[i]=work[i]-arrBg[pos2];
6119           castsDetected.insert(pos2);
6120         }
6121       else
6122         {
6123           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6124           throw INTERP_KERNEL::Exception(oss.str().c_str());
6125         }
6126     }
6127   ret3->alloc((int)castsDetected.size(),1);
6128   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6129   castArr=ret1.retn();
6130   rankInsideCast=ret2.retn();
6131   castsPresent=ret3.retn();
6132 }
6133
6134 /*!
6135  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6136  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6137  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6138  * new value in place \a indArr[ \a v ] is i.
6139  *  \param [in] indArrBg - the array holding indices within the result array to assign
6140  *         indices of values of \a this array pointing to values of \a indArrBg.
6141  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6142  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6143  *  \return DataArrayInt * - the new instance of DataArrayInt.
6144  *          The caller is to delete this result array using decrRef() as it is no more
6145  *          needed.
6146  *  \throw If \a this->getNumberOfComponents() != 1.
6147  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6148  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6149  */
6150 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
6151 {
6152   checkAllocated();
6153   if(getNumberOfComponents()!=1)
6154     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6155   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6156   int nbOfTuples=getNumberOfTuples();
6157   const int *pt=getConstPointer();
6158   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6159   ret->alloc(nbOfTuples,1);
6160   ret->fillWithValue(-1);
6161   int *tmp=ret->getPointer();
6162   for(int i=0;i<nbOfTuples;i++,pt++)
6163     {
6164       if(*pt>=0 && *pt<nbElemsIn)
6165         {
6166           int pos=indArrBg[*pt];
6167           if(pos>=0 && pos<nbOfTuples)
6168             tmp[pos]=i;
6169           else
6170             {
6171               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6172               throw INTERP_KERNEL::Exception(oss.str().c_str());
6173             }
6174         }
6175       else
6176         {
6177           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6178           throw INTERP_KERNEL::Exception(oss.str().c_str());
6179         }
6180     }
6181   return ret.retn();
6182 }
6183
6184 /*!
6185  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6186  * from values of \a this array, which is supposed to contain a renumbering map in 
6187  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6188  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6189  *  \param [in] newNbOfElem - the number of tuples in the result array.
6190  *  \return DataArrayInt * - the new instance of DataArrayInt.
6191  *          The caller is to delete this result array using decrRef() as it is no more
6192  *          needed.
6193  * 
6194  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6195  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6196  */
6197 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6198 {
6199   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6200   ret->alloc(newNbOfElem,1);
6201   int nbOfOldNodes=getNumberOfTuples();
6202   const int *old2New=getConstPointer();
6203   int *pt=ret->getPointer();
6204   for(int i=0;i!=nbOfOldNodes;i++)
6205     if(old2New[i]!=-1)
6206       pt[old2New[i]]=i;
6207   return ret.retn();
6208 }
6209
6210 /*!
6211  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6212  * 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]
6213  */
6214 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6215 {
6216   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6217   ret->alloc(newNbOfElem,1);
6218   int nbOfOldNodes=getNumberOfTuples();
6219   const int *old2New=getConstPointer();
6220   int *pt=ret->getPointer();
6221   for(int i=nbOfOldNodes-1;i>=0;i--)
6222     if(old2New[i]!=-1)
6223       pt[old2New[i]]=i;
6224   return ret.retn();
6225 }
6226
6227 /*!
6228  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6229  * from values of \a this array, which is supposed to contain a renumbering map in 
6230  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6231  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6232  *  \param [in] newNbOfElem - the number of tuples in the result array.
6233  *  \return DataArrayInt * - the new instance of DataArrayInt.
6234  *          The caller is to delete this result array using decrRef() as it is no more
6235  *          needed.
6236  * 
6237  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6238  *
6239  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6240  */
6241 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6242 {
6243   checkAllocated();
6244   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6245   ret->alloc(oldNbOfElem,1);
6246   const int *new2Old=getConstPointer();
6247   int *pt=ret->getPointer();
6248   std::fill(pt,pt+oldNbOfElem,-1);
6249   int nbOfNewElems=getNumberOfTuples();
6250   for(int i=0;i<nbOfNewElems;i++)
6251     {
6252       int v(new2Old[i]);
6253       if(v>=0 && v<oldNbOfElem)
6254          pt[v]=i;
6255       else
6256         {
6257           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6258           throw INTERP_KERNEL::Exception(oss.str().c_str());
6259         }
6260     }
6261   return ret.retn();
6262 }
6263
6264 /*!
6265  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6266  * mismatch is given.
6267  * 
6268  * \param [in] other the instance to be compared with \a this
6269  * \param [out] reason In case of inequality returns the reason.
6270  * \sa DataArrayInt::isEqual
6271  */
6272 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6273 {
6274   if(!areInfoEqualsIfNotWhy(other,reason))
6275     return false;
6276   return _mem.isEqual(other._mem,0,reason);
6277 }
6278
6279 /*!
6280  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6281  * \ref MEDCouplingArrayBasicsCompare.
6282  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6283  *  \return bool - \a true if the two arrays are equal, \a false else.
6284  */
6285 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6286 {
6287   std::string tmp;
6288   return isEqualIfNotWhy(other,tmp);
6289 }
6290
6291 /*!
6292  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6293  * \ref MEDCouplingArrayBasicsCompare.
6294  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6295  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6296  */
6297 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6298 {
6299   std::string tmp;
6300   return _mem.isEqual(other._mem,0,tmp);
6301 }
6302
6303 /*!
6304  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6305  * performed on sorted value sequences.
6306  * For more info see\ref MEDCouplingArrayBasicsCompare.
6307  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6308  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6309  */
6310 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6311 {
6312   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6313   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6314   a->sort();
6315   b->sort();
6316   return a->isEqualWithoutConsideringStr(*b);
6317 }
6318
6319 /*!
6320  * This method compares content of input vector \a v and \a this.
6321  * 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.
6322  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6323  *
6324  * \param [in] v - the vector of 'flags' to be compared with \a this.
6325  *
6326  * \throw If \a this is not sorted ascendingly.
6327  * \throw If \a this has not exactly one component.
6328  * \throw If \a this is not allocated.
6329  */
6330 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception)
6331 {
6332   checkAllocated();
6333   if(getNumberOfComponents()!=1)
6334     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6335   int nbOfTuples(getNumberOfTuples());
6336   const int *w(begin()),*end2(end());
6337   int refVal=-std::numeric_limits<int>::max();
6338   int i=0;
6339   std::vector<bool>::const_iterator it(v.begin());
6340   for(;it!=v.end();it++,i++)
6341     {
6342       if(*it)
6343         {
6344           if(w!=end2)
6345             {
6346               if(*w++==i)
6347                 {
6348                   if(i>refVal)
6349                     refVal=i;
6350                   else
6351                     {
6352                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6353                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6354                     }
6355                 }
6356               else
6357                 return false;
6358             }
6359           else
6360             return false;
6361         }
6362     }
6363   return w==end2;
6364 }
6365
6366 /*!
6367  * Sorts values of the array.
6368  *  \param [in] asc - \a true means ascending order, \a false, descending.
6369  *  \throw If \a this is not allocated.
6370  *  \throw If \a this->getNumberOfComponents() != 1.
6371  */
6372 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6373 {
6374   checkAllocated();
6375   if(getNumberOfComponents()!=1)
6376     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6377   _mem.sort(asc);
6378   declareAsNew();
6379 }
6380
6381 /*!
6382  * Reverse the array values.
6383  *  \throw If \a this->getNumberOfComponents() < 1.
6384  *  \throw If \a this is not allocated.
6385  */
6386 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6387 {
6388   checkAllocated();
6389   _mem.reverse(getNumberOfComponents());
6390   declareAsNew();
6391 }
6392
6393 /*!
6394  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6395  * If not an exception is thrown.
6396  *  \param [in] increasing - if \a true, the array values should be increasing.
6397  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6398  *         increasing arg.
6399  *  \throw If \a this->getNumberOfComponents() != 1.
6400  *  \throw If \a this is not allocated.
6401  */
6402 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6403 {
6404   if(!isMonotonic(increasing))
6405     {
6406       if (increasing)
6407         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6408       else
6409         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6410     }
6411 }
6412
6413 /*!
6414  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6415  *  \param [in] increasing - if \a true, array values should be increasing.
6416  *  \return bool - \a true if values change in accordance with \a increasing arg.
6417  *  \throw If \a this->getNumberOfComponents() != 1.
6418  *  \throw If \a this is not allocated.
6419  */
6420 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6421 {
6422   checkAllocated();
6423   if(getNumberOfComponents()!=1)
6424     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6425   int nbOfElements=getNumberOfTuples();
6426   const int *ptr=getConstPointer();
6427   if(nbOfElements==0)
6428     return true;
6429   int ref=ptr[0];
6430   if(increasing)
6431     {
6432       for(int i=1;i<nbOfElements;i++)
6433         {
6434           if(ptr[i]>=ref)
6435             ref=ptr[i];
6436           else
6437             return false;
6438         }
6439     }
6440   else
6441     {
6442       for(int i=1;i<nbOfElements;i++)
6443         {
6444           if(ptr[i]<=ref)
6445             ref=ptr[i];
6446           else
6447             return false;
6448         }
6449     }
6450   return true;
6451 }
6452
6453 /*!
6454  * This method check that array consistently INCREASING or DECREASING in value.
6455  */
6456 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6457 {
6458   checkAllocated();
6459   if(getNumberOfComponents()!=1)
6460     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6461   int nbOfElements=getNumberOfTuples();
6462   const int *ptr=getConstPointer();
6463   if(nbOfElements==0)
6464     return true;
6465   int ref=ptr[0];
6466   if(increasing)
6467     {
6468       for(int i=1;i<nbOfElements;i++)
6469         {
6470           if(ptr[i]>ref)
6471             ref=ptr[i];
6472           else
6473             return false;
6474         }
6475     }
6476   else
6477     {
6478       for(int i=1;i<nbOfElements;i++)
6479         {
6480           if(ptr[i]<ref)
6481             ref=ptr[i];
6482           else
6483             return false;
6484         }
6485     }
6486   return true;
6487 }
6488
6489 /*!
6490  * This method check that array consistently INCREASING or DECREASING in value.
6491  */
6492 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6493 {
6494   if(!isStrictlyMonotonic(increasing))
6495     {
6496       if (increasing)
6497         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6498       else
6499         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6500     }
6501 }
6502
6503 /*!
6504  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6505  * one-dimensional arrays that must be of the same length. The result array describes
6506  * correspondence between \a this and \a other arrays, so that 
6507  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6508  * not possible because some element in \a other is not in \a this, an exception is thrown.
6509  *  \param [in] other - an array to compute permutation to.
6510  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6511  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6512  * no more needed.
6513  *  \throw If \a this->getNumberOfComponents() != 1.
6514  *  \throw If \a other->getNumberOfComponents() != 1.
6515  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6516  *  \throw If \a other includes a value which is not in \a this array.
6517  * 
6518  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6519  *
6520  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6521  */
6522 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6523 {
6524   checkAllocated();
6525   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6526     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6527   int nbTuple=getNumberOfTuples();
6528   other.checkAllocated();
6529   if(nbTuple!=other.getNumberOfTuples())
6530     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6531   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6532   ret->alloc(nbTuple,1);
6533   ret->fillWithValue(-1);
6534   const int *pt=getConstPointer();
6535   std::map<int,int> mm;
6536   for(int i=0;i<nbTuple;i++)
6537     mm[pt[i]]=i;
6538   pt=other.getConstPointer();
6539   int *retToFill=ret->getPointer();
6540   for(int i=0;i<nbTuple;i++)
6541     {
6542       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6543       if(it==mm.end())
6544         {
6545           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6546           throw INTERP_KERNEL::Exception(oss.str().c_str());
6547         }
6548       retToFill[i]=(*it).second;
6549     }
6550   return ret.retn();
6551 }
6552
6553 /*!
6554  * Sets a C array to be used as raw data of \a this. The previously set info
6555  *  of components is retained and re-sized. 
6556  * For more info see \ref MEDCouplingArraySteps1.
6557  *  \param [in] array - the C array to be used as raw data of \a this.
6558  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6559  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6560  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6561  *                     \c free(\c array ) will be called.
6562  *  \param [in] nbOfTuple - new number of tuples in \a this.
6563  *  \param [in] nbOfCompo - new number of components in \a this.
6564  */
6565 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6566 {
6567   _info_on_compo.resize(nbOfCompo);
6568   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6569   declareAsNew();
6570 }
6571
6572 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6573 {
6574   _info_on_compo.resize(nbOfCompo);
6575   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6576   declareAsNew();
6577 }
6578
6579 /*!
6580  * Returns a new DataArrayInt holding the same values as \a this array but differently
6581  * arranged in memory. If \a this array holds 2 components of 3 values:
6582  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6583  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6584  *  \warning Do not confuse this method with transpose()!
6585  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6586  *          is to delete using decrRef() as it is no more needed.
6587  *  \throw If \a this is not allocated.
6588  */
6589 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6590 {
6591   checkAllocated();
6592   if(_mem.isNull())
6593     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6594   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6595   DataArrayInt *ret=DataArrayInt::New();
6596   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6597   return ret;
6598 }
6599
6600 /*!
6601  * Returns a new DataArrayInt holding the same values as \a this array but differently
6602  * arranged in memory. If \a this array holds 2 components of 3 values:
6603  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6604  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6605  *  \warning Do not confuse this method with transpose()!
6606  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6607  *          is to delete using decrRef() as it is no more needed.
6608  *  \throw If \a this is not allocated.
6609  */
6610 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6611 {
6612   checkAllocated();
6613   if(_mem.isNull())
6614     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6615   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6616   DataArrayInt *ret=DataArrayInt::New();
6617   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6618   return ret;
6619 }
6620
6621 /*!
6622  * Permutes values of \a this array as required by \a old2New array. The values are
6623  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6624  * the same as in \this one.
6625  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6626  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6627  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6628  *     giving a new position for i-th old value.
6629  */
6630 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6631 {
6632   checkAllocated();
6633   int nbTuples=getNumberOfTuples();
6634   int nbOfCompo=getNumberOfComponents();
6635   int *tmp=new int[nbTuples*nbOfCompo];
6636   const int *iptr=getConstPointer();
6637   for(int i=0;i<nbTuples;i++)
6638     {
6639       int v=old2New[i];
6640       if(v>=0 && v<nbTuples)
6641         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6642       else
6643         {
6644           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6645           throw INTERP_KERNEL::Exception(oss.str().c_str());
6646         }
6647     }
6648   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6649   delete [] tmp;
6650   declareAsNew();
6651 }
6652
6653 /*!
6654  * Permutes values of \a this array as required by \a new2Old array. The values are
6655  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6656  * the same as in \this one.
6657  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6658  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6659  *     giving a previous position of i-th new value.
6660  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6661  *          is to delete using decrRef() as it is no more needed.
6662  */
6663 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6664 {
6665   checkAllocated();
6666   int nbTuples=getNumberOfTuples();
6667   int nbOfCompo=getNumberOfComponents();
6668   int *tmp=new int[nbTuples*nbOfCompo];
6669   const int *iptr=getConstPointer();
6670   for(int i=0;i<nbTuples;i++)
6671     {
6672       int v=new2Old[i];
6673       if(v>=0 && v<nbTuples)
6674         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6675       else
6676         {
6677           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6678           throw INTERP_KERNEL::Exception(oss.str().c_str());
6679         }
6680     }
6681   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6682   delete [] tmp;
6683   declareAsNew();
6684 }
6685
6686 /*!
6687  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6688  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6689  * Number of tuples in the result array remains the same as in \this one.
6690  * If a permutation reduction is needed, renumberAndReduce() should be used.
6691  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6692  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6693  *          giving a new position for i-th old value.
6694  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6695  *          is to delete using decrRef() as it is no more needed.
6696  *  \throw If \a this is not allocated.
6697  */
6698 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6699 {
6700   checkAllocated();
6701   int nbTuples=getNumberOfTuples();
6702   int nbOfCompo=getNumberOfComponents();
6703   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6704   ret->alloc(nbTuples,nbOfCompo);
6705   ret->copyStringInfoFrom(*this);
6706   const int *iptr=getConstPointer();
6707   int *optr=ret->getPointer();
6708   for(int i=0;i<nbTuples;i++)
6709     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6710   ret->copyStringInfoFrom(*this);
6711   return ret.retn();
6712 }
6713
6714 /*!
6715  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6716  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6717  * tuples in the result array remains the same as in \this one.
6718  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6719  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6720  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6721  *     giving a previous position of i-th new value.
6722  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6723  *          is to delete using decrRef() as it is no more needed.
6724  */
6725 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6726 {
6727   checkAllocated();
6728   int nbTuples=getNumberOfTuples();
6729   int nbOfCompo=getNumberOfComponents();
6730   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6731   ret->alloc(nbTuples,nbOfCompo);
6732   ret->copyStringInfoFrom(*this);
6733   const int *iptr=getConstPointer();
6734   int *optr=ret->getPointer();
6735   for(int i=0;i<nbTuples;i++)
6736     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6737   ret->copyStringInfoFrom(*this);
6738   return ret.retn();
6739 }
6740
6741 /*!
6742  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6743  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6744  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6745  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6746  * \a old2New[ i ] is negative, is missing from the result array.
6747  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6748  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6749  *     giving a new position for i-th old tuple and giving negative position for
6750  *     for i-th old tuple that should be omitted.
6751  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6752  *          is to delete using decrRef() as it is no more needed.
6753  */
6754 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6755 {
6756   checkAllocated();
6757   int nbTuples=getNumberOfTuples();
6758   int nbOfCompo=getNumberOfComponents();
6759   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6760   ret->alloc(newNbOfTuple,nbOfCompo);
6761   const int *iptr=getConstPointer();
6762   int *optr=ret->getPointer();
6763   for(int i=0;i<nbTuples;i++)
6764     {
6765       int w=old2New[i];
6766       if(w>=0)
6767         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6768     }
6769   ret->copyStringInfoFrom(*this);
6770   return ret.retn();
6771 }
6772
6773 /*!
6774  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6775  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6776  * \a new2OldBg array.
6777  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6778  * This method is equivalent to renumberAndReduce() except that convention in input is
6779  * \c new2old and \b not \c old2new.
6780  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6781  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6782  *              tuple index in \a this array to fill the i-th tuple in the new array.
6783  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6784  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6785  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6786  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6787  *          is to delete using decrRef() as it is no more needed.
6788  */
6789 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6790 {
6791   checkAllocated();
6792   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6793   int nbComp=getNumberOfComponents();
6794   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6795   ret->copyStringInfoFrom(*this);
6796   int *pt=ret->getPointer();
6797   const int *srcPt=getConstPointer();
6798   int i=0;
6799   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6800     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6801   ret->copyStringInfoFrom(*this);
6802   return ret.retn();
6803 }
6804
6805 /*!
6806  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6807  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6808  * \a new2OldBg array.
6809  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6810  * This method is equivalent to renumberAndReduce() except that convention in input is
6811  * \c new2old and \b not \c old2new.
6812  * This method is equivalent to selectByTupleId() except that it prevents coping data
6813  * from behind the end of \a this array.
6814  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6815  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6816  *              tuple index in \a this array to fill the i-th tuple in the new array.
6817  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6818  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6819  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6820  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6821  *          is to delete using decrRef() as it is no more needed.
6822  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6823  */
6824 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6825 {
6826   checkAllocated();
6827   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6828   int nbComp=getNumberOfComponents();
6829   int oldNbOfTuples=getNumberOfTuples();
6830   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6831   ret->copyStringInfoFrom(*this);
6832   int *pt=ret->getPointer();
6833   const int *srcPt=getConstPointer();
6834   int i=0;
6835   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6836     if(*w>=0 && *w<oldNbOfTuples)
6837       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6838     else
6839       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6840   ret->copyStringInfoFrom(*this);
6841   return ret.retn();
6842 }
6843
6844 /*!
6845  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6846  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6847  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6848  * command \c range( \a bg, \a end2, \a step ).
6849  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6850  * not constructed explicitly.
6851  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6852  *  \param [in] bg - index of the first tuple to copy from \a this array.
6853  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6854  *  \param [in] step - index increment to get index of the next tuple to copy.
6855  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6856  *          is to delete using decrRef() as it is no more needed.
6857  *  \sa DataArrayInt::substr.
6858  */
6859 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6860 {
6861   checkAllocated();
6862   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6863   int nbComp=getNumberOfComponents();
6864   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6865   ret->alloc(newNbOfTuples,nbComp);
6866   int *pt=ret->getPointer();
6867   const int *srcPt=getConstPointer()+bg*nbComp;
6868   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6869     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6870   ret->copyStringInfoFrom(*this);
6871   return ret.retn();
6872 }
6873
6874 /*!
6875  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6876  * of tuples specified by \a ranges parameter.
6877  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6878  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6879  *              of tuples in [\c begin,\c end) format.
6880  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6881  *          is to delete using decrRef() as it is no more needed.
6882  *  \throw If \a end < \a begin.
6883  *  \throw If \a end > \a this->getNumberOfTuples().
6884  *  \throw If \a this is not allocated.
6885  */
6886 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6887 {
6888   checkAllocated();
6889   int nbOfComp=getNumberOfComponents();
6890   int nbOfTuplesThis=getNumberOfTuples();
6891   if(ranges.empty())
6892     {
6893       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6894       ret->alloc(0,nbOfComp);
6895       ret->copyStringInfoFrom(*this);
6896       return ret.retn();
6897     }
6898   int ref=ranges.front().first;
6899   int nbOfTuples=0;
6900   bool isIncreasing=true;
6901   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6902     {
6903       if((*it).first<=(*it).second)
6904         {
6905           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6906             {
6907               nbOfTuples+=(*it).second-(*it).first;
6908               if(isIncreasing)
6909                 isIncreasing=ref<=(*it).first;
6910               ref=(*it).second;
6911             }
6912           else
6913             {
6914               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6915               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6916               throw INTERP_KERNEL::Exception(oss.str().c_str());
6917             }
6918         }
6919       else
6920         {
6921           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6922           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6923           throw INTERP_KERNEL::Exception(oss.str().c_str());
6924         }
6925     }
6926   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6927     return deepCpy();
6928   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6929   ret->alloc(nbOfTuples,nbOfComp);
6930   ret->copyStringInfoFrom(*this);
6931   const int *src=getConstPointer();
6932   int *work=ret->getPointer();
6933   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6934     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6935   return ret.retn();
6936 }
6937
6938 /*!
6939  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6940  * This map, if applied to \a this array, would make it sorted. For example, if
6941  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6942  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6943  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6944  * This method is useful for renumbering (in MED file for example). For more info
6945  * on renumbering see \ref MEDCouplingArrayRenumbering.
6946  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6947  *          array using decrRef() as it is no more needed.
6948  *  \throw If \a this is not allocated.
6949  *  \throw If \a this->getNumberOfComponents() != 1.
6950  *  \throw If there are equal values in \a this array.
6951  */
6952 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6953 {
6954   checkAllocated();
6955   if(getNumberOfComponents()!=1)
6956     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6957   int nbTuples=getNumberOfTuples();
6958   const int *pt=getConstPointer();
6959   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6960   DataArrayInt *ret=DataArrayInt::New();
6961   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6962   return ret;
6963 }
6964
6965 /*!
6966  * 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
6967  * input array \a ids2.
6968  * \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.
6969  * 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
6970  * inversely.
6971  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6972  *
6973  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6974  *          array using decrRef() as it is no more needed.
6975  * \throw If either ids1 or ids2 is null not allocated or not with one components.
6976  * 
6977  */
6978 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception)
6979 {
6980   if(!ids1 || !ids2)
6981     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
6982   if(!ids1->isAllocated() || !ids2->isAllocated())
6983     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
6984   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
6985     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
6986   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
6987     {
6988       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 !";
6989       throw INTERP_KERNEL::Exception(oss.str().c_str());
6990     }
6991   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
6992   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
6993   p1->sort(true); p2->sort(true);
6994   if(!p1->isEqualWithoutConsideringStr(*p2))
6995     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
6996   p1=ids1->checkAndPreparePermutation();
6997   p2=ids2->checkAndPreparePermutation();
6998   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
6999   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7000   return p2.retn();
7001 }
7002
7003 /*!
7004  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7005  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7006  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7007  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7008  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7009  * The first of out arrays returns indices of elements of \a this array, grouped by their
7010  * place in the set \a B. The second out array is the index of the first one; it shows how
7011  * many elements of \a A are mapped into each element of \a B. <br>
7012  * For more info on
7013  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7014  * \b Example:
7015  * - \a this: [0,3,2,3,2,2,1,2]
7016  * - \a targetNb: 4
7017  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7018  * - \a arrI: [0,1,2,6,8]
7019  *
7020  * This result means: <br>
7021  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7022  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7023  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7024  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7025  * \a arrI[ 2+1 ]]); <br> etc.
7026  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7027  *         than the maximal value of \a A.
7028  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7029  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7030  *         this array using decrRef() as it is no more needed.
7031  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7032  *         elements of \a this. The caller is to delete this array using decrRef() as it
7033  *         is no more needed.
7034  *  \throw If \a this is not allocated.
7035  *  \throw If \a this->getNumberOfComponents() != 1.
7036  *  \throw If any value in \a this is more or equal to \a targetNb.
7037  */
7038 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
7039 {
7040   checkAllocated();
7041   if(getNumberOfComponents()!=1)
7042     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7043   int nbOfTuples=getNumberOfTuples();
7044   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7045   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7046   retI->alloc(targetNb+1,1);
7047   const int *input=getConstPointer();
7048   std::vector< std::vector<int> > tmp(targetNb);
7049   for(int i=0;i<nbOfTuples;i++)
7050     {
7051       int tmp2=input[i];
7052       if(tmp2>=0 && tmp2<targetNb)
7053         tmp[tmp2].push_back(i);
7054       else
7055         {
7056           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7057           throw INTERP_KERNEL::Exception(oss.str().c_str());
7058         }
7059     }
7060   int *retIPtr=retI->getPointer();
7061   *retIPtr=0;
7062   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7063     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7064   if(nbOfTuples!=retI->getIJ(targetNb,0))
7065     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7066   ret->alloc(nbOfTuples,1);
7067   int *retPtr=ret->getPointer();
7068   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7069     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7070   arr=ret.retn();
7071   arrI=retI.retn();
7072 }
7073
7074
7075 /*!
7076  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7077  * from a zip representation of a surjective format (returned e.g. by
7078  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7079  * for example). The result array minimizes the permutation. <br>
7080  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7081  * \b Example: <br>
7082  * - \a nbOfOldTuples: 10 
7083  * - \a arr          : [0,3, 5,7,9]
7084  * - \a arrIBg       : [0,2,5]
7085  * - \a newNbOfTuples: 7
7086  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7087  *
7088  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7089  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7090  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7091  *         (indices of) equal values. Its every element (except the last one) points to
7092  *         the first element of a group of equal values.
7093  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7094  *          arrIBg is \a arrIEnd[ -1 ].
7095  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7096  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7097  *          array using decrRef() as it is no more needed.
7098  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7099  */
7100 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
7101 {
7102   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7103   ret->alloc(nbOfOldTuples,1);
7104   int *pt=ret->getPointer();
7105   std::fill(pt,pt+nbOfOldTuples,-1);
7106   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7107   const int *cIPtr=arrIBg;
7108   for(int i=0;i<nbOfGrps;i++)
7109     pt[arr[cIPtr[i]]]=-(i+2);
7110   int newNb=0;
7111   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7112     {
7113       if(pt[iNode]<0)
7114         {
7115           if(pt[iNode]==-1)
7116             pt[iNode]=newNb++;
7117           else
7118             {
7119               int grpId=-(pt[iNode]+2);
7120               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7121                 {
7122                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7123                     pt[arr[j]]=newNb;
7124                   else
7125                     {
7126                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7127                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7128                     }
7129                 }
7130               newNb++;
7131             }
7132         }
7133     }
7134   newNbOfTuples=newNb;
7135   return ret.retn();
7136 }
7137
7138 /*!
7139  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7140  * which if applied to \a this array would make it sorted ascendingly.
7141  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7142  * \b Example: <br>
7143  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7144  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7145  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7146  *
7147  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7148  *          array using decrRef() as it is no more needed.
7149  *  \throw If \a this is not allocated.
7150  *  \throw If \a this->getNumberOfComponents() != 1.
7151  */
7152 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
7153 {
7154   checkAllocated();
7155   if(getNumberOfComponents()!=1)
7156     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7157   int nbOfTuples=getNumberOfTuples();
7158   const int *pt=getConstPointer();
7159   std::map<int,int> m;
7160   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7161   ret->alloc(nbOfTuples,1);
7162   int *opt=ret->getPointer();
7163   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7164     {
7165       int val=*pt;
7166       std::map<int,int>::iterator it=m.find(val);
7167       if(it!=m.end())
7168         {
7169           *opt=(*it).second;
7170           (*it).second++;
7171         }
7172       else
7173         {
7174           *opt=0;
7175           m.insert(std::pair<int,int>(val,1));
7176         }
7177     }
7178   int sum=0;
7179   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7180     {
7181       int vt=(*it).second;
7182       (*it).second=sum;
7183       sum+=vt;
7184     }
7185   pt=getConstPointer();
7186   opt=ret->getPointer();
7187   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7188     *opt+=m[*pt];
7189   //
7190   return ret.retn();
7191 }
7192
7193 /*!
7194  * Checks if contents of \a this array are equal to that of an array filled with
7195  * iota(). This method is particularly useful for DataArrayInt instances that represent
7196  * a renumbering array to check the real need in renumbering. 
7197  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7198  *  \throw If \a this is not allocated.
7199  *  \throw If \a this->getNumberOfComponents() != 1.
7200  */
7201 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
7202 {
7203   checkAllocated();
7204   if(getNumberOfComponents()!=1)
7205     return false;
7206   int nbOfTuples=getNumberOfTuples();
7207   const int *pt=getConstPointer();
7208   for(int i=0;i<nbOfTuples;i++,pt++)
7209     if(*pt!=i)
7210       return false;
7211   return true;
7212 }
7213
7214 /*!
7215  * Checks if all values in \a this array are equal to \a val.
7216  *  \param [in] val - value to check equality of array values to.
7217  *  \return bool - \a true if all values are \a val.
7218  *  \throw If \a this is not allocated.
7219  *  \throw If \a this->getNumberOfComponents() != 1
7220  */
7221 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
7222 {
7223   checkAllocated();
7224   if(getNumberOfComponents()!=1)
7225     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7226   int nbOfTuples=getNumberOfTuples();
7227   const int *w=getConstPointer();
7228   const int *end2=w+nbOfTuples;
7229   for(;w!=end2;w++)
7230     if(*w!=val)
7231       return false;
7232   return true;
7233 }
7234
7235 /*!
7236  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7237  * array to the new one.
7238  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7239  */
7240 DataArrayDouble *DataArrayInt::convertToDblArr() const
7241 {
7242   checkAllocated();
7243   DataArrayDouble *ret=DataArrayDouble::New();
7244   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7245   std::size_t nbOfVals=getNbOfElems();
7246   const int *src=getConstPointer();
7247   double *dest=ret->getPointer();
7248   std::copy(src,src+nbOfVals,dest);
7249   ret->copyStringInfoFrom(*this);
7250   return ret;
7251 }
7252
7253 /*!
7254  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7255  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7256  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7257  * This method is a specialization of selectByTupleId2().
7258  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7259  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7260  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7261  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7262  *          is to delete using decrRef() as it is no more needed.
7263  *  \throw If \a tupleIdBg < 0.
7264  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7265     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7266  *  \sa DataArrayInt::selectByTupleId2
7267  */
7268 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7269 {
7270   checkAllocated();
7271   int nbt=getNumberOfTuples();
7272   if(tupleIdBg<0)
7273     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7274   if(tupleIdBg>nbt)
7275     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7276   int trueEnd=tupleIdEnd;
7277   if(tupleIdEnd!=-1)
7278     {
7279       if(tupleIdEnd>nbt)
7280         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7281     }
7282   else
7283     trueEnd=nbt;
7284   int nbComp=getNumberOfComponents();
7285   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7286   ret->alloc(trueEnd-tupleIdBg,nbComp);
7287   ret->copyStringInfoFrom(*this);
7288   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7289   return ret.retn();
7290 }
7291
7292 /*!
7293  * Changes the number of components within \a this array so that its raw data **does
7294  * not** change, instead splitting this data into tuples changes.
7295  *  \warning This method erases all (name and unit) component info set before!
7296  *  \param [in] newNbOfComp - number of components for \a this array to have.
7297  *  \throw If \a this is not allocated
7298  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7299  *  \throw If \a newNbOfCompo is lower than 1.
7300  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7301  *  \warning This method erases all (name and unit) component info set before!
7302  */
7303 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7304 {
7305   checkAllocated();
7306   if(newNbOfCompo<1)
7307     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7308   std::size_t nbOfElems=getNbOfElems();
7309   if(nbOfElems%newNbOfCompo!=0)
7310     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7311   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7312     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7313   _info_on_compo.clear();
7314   _info_on_compo.resize(newNbOfCompo);
7315   declareAsNew();
7316 }
7317
7318 /*!
7319  * Changes the number of components within \a this array to be equal to its number
7320  * of tuples, and inversely its number of tuples to become equal to its number of 
7321  * components. So that its raw data **does not** change, instead splitting this
7322  * data into tuples changes.
7323  *  \warning This method erases all (name and unit) component info set before!
7324  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7325  *  \throw If \a this is not allocated.
7326  *  \sa rearrange()
7327  */
7328 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7329 {
7330   checkAllocated();
7331   int nbOfTuples=getNumberOfTuples();
7332   rearrange(nbOfTuples);
7333 }
7334
7335 /*!
7336  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7337  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7338  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7339  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7340  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7341  * components.  
7342  *  \param [in] newNbOfComp - number of components for the new array to have.
7343  *  \param [in] dftValue - value assigned to new values added to the new array.
7344  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7345  *          is to delete using decrRef() as it is no more needed.
7346  *  \throw If \a this is not allocated.
7347  */
7348 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7349 {
7350   checkAllocated();
7351   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7352   ret->alloc(getNumberOfTuples(),newNbOfComp);
7353   const int *oldc=getConstPointer();
7354   int *nc=ret->getPointer();
7355   int nbOfTuples=getNumberOfTuples();
7356   int oldNbOfComp=getNumberOfComponents();
7357   int dim=std::min(oldNbOfComp,newNbOfComp);
7358   for(int i=0;i<nbOfTuples;i++)
7359     {
7360       int j=0;
7361       for(;j<dim;j++)
7362         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7363       for(;j<newNbOfComp;j++)
7364         nc[newNbOfComp*i+j]=dftValue;
7365     }
7366   ret->setName(getName().c_str());
7367   for(int i=0;i<dim;i++)
7368     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7369   ret->setName(getName().c_str());
7370   return ret.retn();
7371 }
7372
7373 /*!
7374  * Changes number of tuples in the array. If the new number of tuples is smaller
7375  * than the current number the array is truncated, otherwise the array is extended.
7376  *  \param [in] nbOfTuples - new number of tuples. 
7377  *  \throw If \a this is not allocated.
7378  *  \throw If \a nbOfTuples is negative.
7379  */
7380 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7381 {
7382   if(nbOfTuples<0)
7383     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7384   checkAllocated();
7385   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7386   declareAsNew();
7387 }
7388
7389
7390 /*!
7391  * Returns a copy of \a this array composed of selected components.
7392  * The new DataArrayInt has the same number of tuples but includes components
7393  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7394  * can be either less, same or more than \a this->getNbOfElems().
7395  *  \param [in] compoIds - sequence of zero based indices of components to include
7396  *              into the new array.
7397  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7398  *          is to delete using decrRef() as it is no more needed.
7399  *  \throw If \a this is not allocated.
7400  *  \throw If a component index (\a i) is not valid: 
7401  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7402  *
7403  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7404  */
7405 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7406 {
7407   checkAllocated();
7408   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7409   int newNbOfCompo=(int)compoIds.size();
7410   int oldNbOfCompo=getNumberOfComponents();
7411   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7412     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7413   int nbOfTuples=getNumberOfTuples();
7414   ret->alloc(nbOfTuples,newNbOfCompo);
7415   ret->copyPartOfStringInfoFrom(*this,compoIds);
7416   const int *oldc=getConstPointer();
7417   int *nc=ret->getPointer();
7418   for(int i=0;i<nbOfTuples;i++)
7419     for(int j=0;j<newNbOfCompo;j++,nc++)
7420       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7421   return ret.retn();
7422 }
7423
7424 /*!
7425  * Appends components of another array to components of \a this one, tuple by tuple.
7426  * So that the number of tuples of \a this array remains the same and the number of 
7427  * components increases.
7428  *  \param [in] other - the DataArrayInt to append to \a this one.
7429  *  \throw If \a this is not allocated.
7430  *  \throw If \a this and \a other arrays have different number of tuples.
7431  *
7432  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7433  *
7434  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7435  */
7436 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7437 {
7438   if(!other)
7439     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7440   checkAllocated();
7441   other->checkAllocated();
7442   int nbOfTuples=getNumberOfTuples();
7443   if(nbOfTuples!=other->getNumberOfTuples())
7444     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7445   int nbOfComp1=getNumberOfComponents();
7446   int nbOfComp2=other->getNumberOfComponents();
7447   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7448   int *w=newArr;
7449   const int *inp1=getConstPointer();
7450   const int *inp2=other->getConstPointer();
7451   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7452     {
7453       w=std::copy(inp1,inp1+nbOfComp1,w);
7454       w=std::copy(inp2,inp2+nbOfComp2,w);
7455     }
7456   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7457   std::vector<int> compIds(nbOfComp2);
7458   for(int i=0;i<nbOfComp2;i++)
7459     compIds[i]=nbOfComp1+i;
7460   copyPartOfStringInfoFrom2(compIds,*other);
7461 }
7462
7463 /*!
7464  * Copy all components in a specified order from another DataArrayInt.
7465  * The specified components become the first ones in \a this array.
7466  * Both numerical and textual data is copied. The number of tuples in \a this and
7467  * the other array can be different.
7468  *  \param [in] a - the array to copy data from.
7469  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7470  *              to be copied.
7471  *  \throw If \a a is NULL.
7472  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7473  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7474  *
7475  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7476  */
7477 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7478 {
7479   if(!a)
7480     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7481   checkAllocated();
7482   a->checkAllocated();
7483   copyPartOfStringInfoFrom2(compoIds,*a);
7484   std::size_t partOfCompoSz=compoIds.size();
7485   int nbOfCompo=getNumberOfComponents();
7486   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7487   const int *ac=a->getConstPointer();
7488   int *nc=getPointer();
7489   for(int i=0;i<nbOfTuples;i++)
7490     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7491       nc[nbOfCompo*i+compoIds[j]]=*ac;
7492 }
7493
7494 /*!
7495  * Copy all values from another DataArrayInt into specified tuples and components
7496  * of \a this array. Textual data is not copied.
7497  * The tree parameters defining set of indices of tuples and components are similar to
7498  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7499  *  \param [in] a - the array to copy values from.
7500  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7501  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7502  *              are located.
7503  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7504  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7505  *  \param [in] endComp - index of the component before which the components to assign
7506  *              to are located.
7507  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7508  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7509  *              must be equal to the number of columns to assign to, else an
7510  *              exception is thrown; if \a false, then it is only required that \a
7511  *              a->getNbOfElems() equals to number of values to assign to (this condition
7512  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7513  *              values to assign to is given by following Python expression:
7514  *              \a nbTargetValues = 
7515  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7516  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7517  *  \throw If \a a is NULL.
7518  *  \throw If \a a is not allocated.
7519  *  \throw If \a this is not allocated.
7520  *  \throw If parameters specifying tuples and components to assign to do not give a
7521  *            non-empty range of increasing indices.
7522  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7523  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7524  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7525  *
7526  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7527  */
7528 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7529 {
7530   if(!a)
7531     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7532   const char msg[]="DataArrayInt::setPartOfValues1";
7533   checkAllocated();
7534   a->checkAllocated();
7535   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7536   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7537   int nbComp=getNumberOfComponents();
7538   int nbOfTuples=getNumberOfTuples();
7539   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7540   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7541   bool assignTech=true;
7542   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7543     {
7544       if(strictCompoCompare)
7545         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7546     }
7547   else
7548     {
7549       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7550       assignTech=false;
7551     }
7552   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7553   const int *srcPt=a->getConstPointer();
7554   if(assignTech)
7555     {
7556       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7557         for(int j=0;j<newNbOfComp;j++,srcPt++)
7558           pt[j*stepComp]=*srcPt;
7559     }
7560   else
7561     {
7562       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7563         {
7564           const int *srcPt2=srcPt;
7565           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7566             pt[j*stepComp]=*srcPt2;
7567         }
7568     }
7569 }
7570
7571 /*!
7572  * Assign a given value to values at specified tuples and components of \a this array.
7573  * The tree parameters defining set of indices of tuples and components are similar to
7574  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7575  *  \param [in] a - the value to assign.
7576  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7577  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7578  *              are located.
7579  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7580  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7581  *  \param [in] endComp - index of the component before which the components to assign
7582  *              to are located.
7583  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7584  *  \throw If \a this is not allocated.
7585  *  \throw If parameters specifying tuples and components to assign to, do not give a
7586  *            non-empty range of increasing indices or indices are out of a valid range
7587  *            for \this array.
7588  *
7589  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7590  */
7591 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7592 {
7593   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7594   checkAllocated();
7595   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7596   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7597   int nbComp=getNumberOfComponents();
7598   int nbOfTuples=getNumberOfTuples();
7599   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7600   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7601   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7602   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7603     for(int j=0;j<newNbOfComp;j++)
7604       pt[j*stepComp]=a;
7605 }
7606
7607
7608 /*!
7609  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7610  * components of \a this array. Textual data is not copied.
7611  * The tuples and components to assign to are defined by C arrays of indices.
7612  * There are two *modes of usage*:
7613  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7614  *   of \a a is assigned to its own location within \a this array. 
7615  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7616  *   components of every specified tuple of \a this array. In this mode it is required
7617  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7618  * 
7619  *  \param [in] a - the array to copy values from.
7620  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7621  *              assign values of \a a to.
7622  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7623  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7624  *              \a bgTuples <= \a pi < \a endTuples.
7625  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7626  *              assign values of \a a to.
7627  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7628  *              pointer to a component index <em>(pi)</em> varies as this: 
7629  *              \a bgComp <= \a pi < \a endComp.
7630  *  \param [in] strictCompoCompare - this parameter is checked only if the
7631  *               *mode of usage* is the first; if it is \a true (default), 
7632  *               then \a a->getNumberOfComponents() must be equal 
7633  *               to the number of specified columns, else this is not required.
7634  *  \throw If \a a is NULL.
7635  *  \throw If \a a is not allocated.
7636  *  \throw If \a this is not allocated.
7637  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7638  *         out of a valid range for \a this array.
7639  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7640  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7641  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7642  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7643  *
7644  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7645  */
7646 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7647 {
7648   if(!a)
7649     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7650   const char msg[]="DataArrayInt::setPartOfValues2";
7651   checkAllocated();
7652   a->checkAllocated();
7653   int nbComp=getNumberOfComponents();
7654   int nbOfTuples=getNumberOfTuples();
7655   for(const int *z=bgComp;z!=endComp;z++)
7656     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7657   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7658   int newNbOfComp=(int)std::distance(bgComp,endComp);
7659   bool assignTech=true;
7660   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7661     {
7662       if(strictCompoCompare)
7663         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7664     }
7665   else
7666     {
7667       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7668       assignTech=false;
7669     }
7670   int *pt=getPointer();
7671   const int *srcPt=a->getConstPointer();
7672   if(assignTech)
7673     {    
7674       for(const int *w=bgTuples;w!=endTuples;w++)
7675         {
7676           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7677           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7678             {    
7679               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7680             }
7681         }
7682     }
7683   else
7684     {
7685       for(const int *w=bgTuples;w!=endTuples;w++)
7686         {
7687           const int *srcPt2=srcPt;
7688           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7689           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7690             {    
7691               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7692             }
7693         }
7694     }
7695 }
7696
7697 /*!
7698  * Assign a given value to values at specified tuples and components of \a this array.
7699  * The tuples and components to assign to are defined by C arrays of indices.
7700  *  \param [in] a - the value to assign.
7701  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7702  *              assign \a a to.
7703  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7704  *              pointer to a tuple index (\a pi) varies as this: 
7705  *              \a bgTuples <= \a pi < \a endTuples.
7706  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7707  *              assign \a a to.
7708  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7709  *              pointer to a component index (\a pi) varies as this: 
7710  *              \a bgComp <= \a pi < \a endComp.
7711  *  \throw If \a this is not allocated.
7712  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7713  *         out of a valid range for \a this array.
7714  *
7715  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7716  */
7717 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7718 {
7719   checkAllocated();
7720   int nbComp=getNumberOfComponents();
7721   int nbOfTuples=getNumberOfTuples();
7722   for(const int *z=bgComp;z!=endComp;z++)
7723     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7724   int *pt=getPointer();
7725   for(const int *w=bgTuples;w!=endTuples;w++)
7726     for(const int *z=bgComp;z!=endComp;z++)
7727       {
7728         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7729         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7730       }
7731 }
7732
7733 /*!
7734  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7735  * components of \a this array. Textual data is not copied.
7736  * The tuples to assign to are defined by a C array of indices.
7737  * The components to assign to are defined by three values similar to parameters of
7738  * the Python function \c range(\c start,\c stop,\c step).
7739  * There are two *modes of usage*:
7740  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7741  *   of \a a is assigned to its own location within \a this array. 
7742  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7743  *   components of every specified tuple of \a this array. In this mode it is required
7744  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7745  *
7746  *  \param [in] a - the array to copy values from.
7747  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7748  *              assign values of \a a to.
7749  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7750  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7751  *              \a bgTuples <= \a pi < \a endTuples.
7752  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7753  *  \param [in] endComp - index of the component before which the components to assign
7754  *              to are located.
7755  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7756  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7757  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7758  *               then \a a->getNumberOfComponents() must be equal 
7759  *               to the number of specified columns, else this is not required.
7760  *  \throw If \a a is NULL.
7761  *  \throw If \a a is not allocated.
7762  *  \throw If \a this is not allocated.
7763  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7764  *         \a this array.
7765  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7766  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7767  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7768  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7769  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7770  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7771  *  \throw If parameters specifying components to assign to, do not give a
7772  *            non-empty range of increasing indices or indices are out of a valid range
7773  *            for \this array.
7774  *
7775  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7776  */
7777 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7778 {
7779   if(!a)
7780     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7781   const char msg[]="DataArrayInt::setPartOfValues3";
7782   checkAllocated();
7783   a->checkAllocated();
7784   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7785   int nbComp=getNumberOfComponents();
7786   int nbOfTuples=getNumberOfTuples();
7787   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7788   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7789   bool assignTech=true;
7790   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7791     {
7792       if(strictCompoCompare)
7793         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7794     }
7795   else
7796     {
7797       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7798       assignTech=false;
7799     }
7800   int *pt=getPointer()+bgComp;
7801   const int *srcPt=a->getConstPointer();
7802   if(assignTech)
7803     {
7804       for(const int *w=bgTuples;w!=endTuples;w++)
7805         for(int j=0;j<newNbOfComp;j++,srcPt++)
7806           {
7807             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7808             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7809           }
7810     }
7811   else
7812     {
7813       for(const int *w=bgTuples;w!=endTuples;w++)
7814         {
7815           const int *srcPt2=srcPt;
7816           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7817             {
7818               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7819               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7820             }
7821         }
7822     }
7823 }
7824
7825 /*!
7826  * Assign a given value to values at specified tuples and components of \a this array.
7827  * The tuples to assign to are defined by a C array of indices.
7828  * The components to assign to are defined by three values similar to parameters of
7829  * the Python function \c range(\c start,\c stop,\c step).
7830  *  \param [in] a - the value to assign.
7831  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7832  *              assign \a a to.
7833  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7834  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7835  *              \a bgTuples <= \a pi < \a endTuples.
7836  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7837  *  \param [in] endComp - index of the component before which the components to assign
7838  *              to are located.
7839  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7840  *  \throw If \a this is not allocated.
7841  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7842  *         \a this array.
7843  *  \throw If parameters specifying components to assign to, do not give a
7844  *            non-empty range of increasing indices or indices are out of a valid range
7845  *            for \this array.
7846  *
7847  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7848  */
7849 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7850 {
7851   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7852   checkAllocated();
7853   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7854   int nbComp=getNumberOfComponents();
7855   int nbOfTuples=getNumberOfTuples();
7856   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7857   int *pt=getPointer()+bgComp;
7858   for(const int *w=bgTuples;w!=endTuples;w++)
7859     for(int j=0;j<newNbOfComp;j++)
7860       {
7861         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7862         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7863       }
7864 }
7865
7866 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7867 {
7868   if(!a)
7869     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7870   const char msg[]="DataArrayInt::setPartOfValues4";
7871   checkAllocated();
7872   a->checkAllocated();
7873   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7874   int newNbOfComp=(int)std::distance(bgComp,endComp);
7875   int nbComp=getNumberOfComponents();
7876   for(const int *z=bgComp;z!=endComp;z++)
7877     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7878   int nbOfTuples=getNumberOfTuples();
7879   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7880   bool assignTech=true;
7881   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7882     {
7883       if(strictCompoCompare)
7884         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7885     }
7886   else
7887     {
7888       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7889       assignTech=false;
7890     }
7891   const int *srcPt=a->getConstPointer();
7892   int *pt=getPointer()+bgTuples*nbComp;
7893   if(assignTech)
7894     {
7895       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7896         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7897           pt[*z]=*srcPt;
7898     }
7899   else
7900     {
7901       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7902         {
7903           const int *srcPt2=srcPt;
7904           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7905             pt[*z]=*srcPt2;
7906         }
7907     }
7908 }
7909
7910 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7911 {
7912   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7913   checkAllocated();
7914   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7915   int nbComp=getNumberOfComponents();
7916   for(const int *z=bgComp;z!=endComp;z++)
7917     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7918   int nbOfTuples=getNumberOfTuples();
7919   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7920   int *pt=getPointer()+bgTuples*nbComp;
7921   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7922     for(const int *z=bgComp;z!=endComp;z++)
7923       pt[*z]=a;
7924 }
7925
7926 /*!
7927  * Copy some tuples from another DataArrayInt into specified tuples
7928  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7929  * components.
7930  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7931  * All components of selected tuples are copied.
7932  *  \param [in] a - the array to copy values from.
7933  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7934  *              target tuples of \a this. \a tuplesSelec has two components, and the
7935  *              first component specifies index of the source tuple and the second
7936  *              one specifies index of the target tuple.
7937  *  \throw If \a this is not allocated.
7938  *  \throw If \a a is NULL.
7939  *  \throw If \a a is not allocated.
7940  *  \throw If \a tuplesSelec is NULL.
7941  *  \throw If \a tuplesSelec is not allocated.
7942  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7943  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7944  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7945  *         the corresponding (\a this or \a a) array.
7946  */
7947 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7948 {
7949   if(!a || !tuplesSelec)
7950     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7951   checkAllocated();
7952   a->checkAllocated();
7953   tuplesSelec->checkAllocated();
7954   int nbOfComp=getNumberOfComponents();
7955   if(nbOfComp!=a->getNumberOfComponents())
7956     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7957   if(tuplesSelec->getNumberOfComponents()!=2)
7958     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7959   int thisNt=getNumberOfTuples();
7960   int aNt=a->getNumberOfTuples();
7961   int *valsToSet=getPointer();
7962   const int *valsSrc=a->getConstPointer();
7963   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7964     {
7965       if(tuple[1]>=0 && tuple[1]<aNt)
7966         {
7967           if(tuple[0]>=0 && tuple[0]<thisNt)
7968             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7969           else
7970             {
7971               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7972               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7973               throw INTERP_KERNEL::Exception(oss.str().c_str());
7974             }
7975         }
7976       else
7977         {
7978           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7979           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7980           throw INTERP_KERNEL::Exception(oss.str().c_str());
7981         }
7982     }
7983 }
7984
7985 /*!
7986  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
7987  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7988  * components.
7989  * The tuples to assign to are defined by index of the first tuple, and
7990  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7991  * The tuples to copy are defined by values of a DataArrayInt.
7992  * All components of selected tuples are copied.
7993  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7994  *              values to.
7995  *  \param [in] aBase - the array to copy values from.
7996  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
7997  *  \throw If \a this is not allocated.
7998  *  \throw If \a aBase is NULL.
7999  *  \throw If \a aBase is not allocated.
8000  *  \throw If \a tuplesSelec is NULL.
8001  *  \throw If \a tuplesSelec is not allocated.
8002  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8003  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8004  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8005  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8006  *         \a aBase array.
8007  */
8008 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
8009 {
8010   if(!aBase || !tuplesSelec)
8011     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8012   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8013   if(!a)
8014     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8015   checkAllocated();
8016   a->checkAllocated();
8017   tuplesSelec->checkAllocated();
8018   int nbOfComp=getNumberOfComponents();
8019   if(nbOfComp!=a->getNumberOfComponents())
8020     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8021   if(tuplesSelec->getNumberOfComponents()!=1)
8022     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8023   int thisNt=getNumberOfTuples();
8024   int aNt=a->getNumberOfTuples();
8025   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8026   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8027   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8028     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8029   const int *valsSrc=a->getConstPointer();
8030   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8031     {
8032       if(*tuple>=0 && *tuple<aNt)
8033         {
8034           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8035         }
8036       else
8037         {
8038           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8039           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8040           throw INTERP_KERNEL::Exception(oss.str().c_str());
8041         }
8042     }
8043 }
8044
8045 /*!
8046  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8047  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8048  * components.
8049  * The tuples to copy are defined by three values similar to parameters of
8050  * the Python function \c range(\c start,\c stop,\c step).
8051  * The tuples to assign to are defined by index of the first tuple, and
8052  * their number is defined by number of tuples to copy.
8053  * All components of selected tuples are copied.
8054  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8055  *              values to.
8056  *  \param [in] aBase - the array to copy values from.
8057  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8058  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8059  *              are located.
8060  *  \param [in] step - index increment to get index of the next tuple to copy.
8061  *  \throw If \a this is not allocated.
8062  *  \throw If \a aBase is NULL.
8063  *  \throw If \a aBase is not allocated.
8064  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8065  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8066  *  \throw If parameters specifying tuples to copy, do not give a
8067  *            non-empty range of increasing indices or indices are out of a valid range
8068  *            for the array \a aBase.
8069  */
8070 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
8071 {
8072   if(!aBase)
8073     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8074   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8075   if(!a)
8076     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8077   checkAllocated();
8078   a->checkAllocated();
8079   int nbOfComp=getNumberOfComponents();
8080   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8081   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8082   if(nbOfComp!=a->getNumberOfComponents())
8083     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8084   int thisNt=getNumberOfTuples();
8085   int aNt=a->getNumberOfTuples();
8086   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8087   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8088     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8089   if(end2>aNt)
8090     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8091   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8092   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8093     {
8094       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8095     }
8096 }
8097
8098 /*!
8099  * Returns a value located at specified tuple and component.
8100  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8101  * parameters is checked. So this method is safe but expensive if used to go through
8102  * all values of \a this.
8103  *  \param [in] tupleId - index of tuple of interest.
8104  *  \param [in] compoId - index of component of interest.
8105  *  \return double - value located by \a tupleId and \a compoId.
8106  *  \throw If \a this is not allocated.
8107  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8108  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8109  */
8110 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
8111 {
8112   checkAllocated();
8113   if(tupleId<0 || tupleId>=getNumberOfTuples())
8114     {
8115       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8116       throw INTERP_KERNEL::Exception(oss.str().c_str());
8117     }
8118   if(compoId<0 || compoId>=getNumberOfComponents())
8119     {
8120       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8121       throw INTERP_KERNEL::Exception(oss.str().c_str());
8122     }
8123   return _mem[tupleId*_info_on_compo.size()+compoId];
8124 }
8125
8126 /*!
8127  * Returns the first value of \a this. 
8128  *  \return int - the last value of \a this array.
8129  *  \throw If \a this is not allocated.
8130  *  \throw If \a this->getNumberOfComponents() != 1.
8131  *  \throw If \a this->getNumberOfTuples() < 1.
8132  */
8133 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
8134 {
8135   checkAllocated();
8136   if(getNumberOfComponents()!=1)
8137     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8138   int nbOfTuples=getNumberOfTuples();
8139   if(nbOfTuples<1)
8140     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8141   return *(getConstPointer());
8142 }
8143
8144 /*!
8145  * Returns the last value of \a this. 
8146  *  \return int - the last value of \a this array.
8147  *  \throw If \a this is not allocated.
8148  *  \throw If \a this->getNumberOfComponents() != 1.
8149  *  \throw If \a this->getNumberOfTuples() < 1.
8150  */
8151 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
8152 {
8153   checkAllocated();
8154   if(getNumberOfComponents()!=1)
8155     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8156   int nbOfTuples=getNumberOfTuples();
8157   if(nbOfTuples<1)
8158     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8159   return *(getConstPointer()+nbOfTuples-1);
8160 }
8161
8162 /*!
8163  * Assign pointer to one array to a pointer to another appay. Reference counter of
8164  * \a arrayToSet is incremented / decremented.
8165  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8166  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8167  */
8168 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8169 {
8170   if(newArray!=arrayToSet)
8171     {
8172       if(arrayToSet)
8173         arrayToSet->decrRef();
8174       arrayToSet=newArray;
8175       if(arrayToSet)
8176         arrayToSet->incrRef();
8177     }
8178 }
8179
8180 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
8181 {
8182   return new DataArrayIntIterator(this);
8183 }
8184
8185 /*!
8186  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8187  * given one.
8188  *  \param [in] val - the value to find within \a this.
8189  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8190  *          array using decrRef() as it is no more needed.
8191  *  \throw If \a this is not allocated.
8192  *  \throw If \a this->getNumberOfComponents() != 1.
8193  */
8194 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
8195 {
8196   checkAllocated();
8197   if(getNumberOfComponents()!=1)
8198     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8199   const int *cptr=getConstPointer();
8200   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8201   int nbOfTuples=getNumberOfTuples();
8202   for(int i=0;i<nbOfTuples;i++,cptr++)
8203     if(*cptr==val)
8204       ret->pushBackSilent(i);
8205   return ret.retn();
8206 }
8207
8208 /*!
8209  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8210  * equal to a given one. 
8211  *  \param [in] val - the value to ignore within \a this.
8212  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8213  *          array using decrRef() as it is no more needed.
8214  *  \throw If \a this is not allocated.
8215  *  \throw If \a this->getNumberOfComponents() != 1.
8216  */
8217 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
8218 {
8219   checkAllocated();
8220   if(getNumberOfComponents()!=1)
8221     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8222   const int *cptr=getConstPointer();
8223   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8224   int nbOfTuples=getNumberOfTuples();
8225   for(int i=0;i<nbOfTuples;i++,cptr++)
8226     if(*cptr!=val)
8227       ret->pushBackSilent(i);
8228   return ret.retn();
8229 }
8230
8231
8232 /*!
8233  * Assigns \a newValue to all elements holding \a oldValue within \a this
8234  * one-dimensional array.
8235  *  \param [in] oldValue - the value to replace.
8236  *  \param [in] newValue - the value to assign.
8237  *  \return int - number of replacements performed.
8238  *  \throw If \a this is not allocated.
8239  *  \throw If \a this->getNumberOfComponents() != 1.
8240  */
8241 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
8242 {
8243   checkAllocated();
8244   if(getNumberOfComponents()!=1)
8245     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8246   int *start=getPointer();
8247   int *end2=start+getNbOfElems();
8248   int ret=0;
8249   for(int *val=start;val!=end2;val++)
8250     {
8251       if(*val==oldValue)
8252         {
8253           *val=newValue;
8254           ret++;
8255         }
8256     }
8257   return ret;
8258 }
8259
8260 /*!
8261  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8262  * one of given values.
8263  *  \param [in] valsBg - an array of values to find within \a this array.
8264  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8265  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8266  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8267  *          array using decrRef() as it is no more needed.
8268  *  \throw If \a this->getNumberOfComponents() != 1.
8269  */
8270 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8271 {
8272   if(getNumberOfComponents()!=1)
8273     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8274   std::set<int> vals2(valsBg,valsEnd);
8275   const int *cptr=getConstPointer();
8276   std::vector<int> res;
8277   int nbOfTuples=getNumberOfTuples();
8278   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8279   for(int i=0;i<nbOfTuples;i++,cptr++)
8280     if(vals2.find(*cptr)!=vals2.end())
8281       ret->pushBackSilent(i);
8282   return ret.retn();
8283 }
8284
8285 /*!
8286  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8287  * equal to any of given values.
8288  *  \param [in] valsBg - an array of values to ignore within \a this array.
8289  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8290  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8291  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8292  *          array using decrRef() as it is no more needed.
8293  *  \throw If \a this->getNumberOfComponents() != 1.
8294  */
8295 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8296 {
8297   if(getNumberOfComponents()!=1)
8298     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8299   std::set<int> vals2(valsBg,valsEnd);
8300   const int *cptr=getConstPointer();
8301   std::vector<int> res;
8302   int nbOfTuples=getNumberOfTuples();
8303   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8304   for(int i=0;i<nbOfTuples;i++,cptr++)
8305     if(vals2.find(*cptr)==vals2.end())
8306       ret->pushBackSilent(i);
8307   return ret.retn();
8308 }
8309
8310 /*!
8311  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8312  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8313  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8314  * If any the tuple id is returned. If not -1 is returned.
8315  * 
8316  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8317  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8318  *
8319  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8320  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8321  */
8322 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8323 {
8324   checkAllocated();
8325   int nbOfCompo=getNumberOfComponents();
8326   if(nbOfCompo==0)
8327     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8328   if(nbOfCompo!=(int)tupl.size())
8329     {
8330       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8331       throw INTERP_KERNEL::Exception(oss.str().c_str());
8332     }
8333   const int *cptr=getConstPointer();
8334   std::size_t nbOfVals=getNbOfElems();
8335   for(const int *work=cptr;work!=cptr+nbOfVals;)
8336     {
8337       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8338       if(work!=cptr+nbOfVals)
8339         {
8340           if(std::distance(cptr,work)%nbOfCompo!=0)
8341             work++;
8342           else
8343             return std::distance(cptr,work)/nbOfCompo;
8344         }
8345     }
8346   return -1;
8347 }
8348
8349 /*!
8350  * This method searches the sequence specified in input parameter \b vals in \b this.
8351  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8352  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8353  * \sa DataArrayInt::locateTuple
8354  */
8355 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8356 {
8357   checkAllocated();
8358   int nbOfCompo=getNumberOfComponents();
8359   if(nbOfCompo!=1)
8360     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8361   const int *cptr=getConstPointer();
8362   std::size_t nbOfVals=getNbOfElems();
8363   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8364   if(loc!=cptr+nbOfVals)
8365     return std::distance(cptr,loc);
8366   return -1;
8367 }
8368
8369 /*!
8370  * This method expects to be called when number of components of this is equal to one.
8371  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8372  * If not any tuple contains \b value -1 is returned.
8373  * \sa DataArrayInt::presenceOfValue
8374  */
8375 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8376 {
8377   checkAllocated();
8378   if(getNumberOfComponents()!=1)
8379     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8380   const int *cptr=getConstPointer();
8381   int nbOfTuples=getNumberOfTuples();
8382   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8383   if(ret!=cptr+nbOfTuples)
8384     return std::distance(cptr,ret);
8385   return -1;
8386 }
8387
8388 /*!
8389  * This method expects to be called when number of components of this is equal to one.
8390  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8391  * If not any tuple contains one of the values contained in 'vals' false is returned.
8392  * \sa DataArrayInt::presenceOfValue
8393  */
8394 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8395 {
8396   checkAllocated();
8397   if(getNumberOfComponents()!=1)
8398     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8399   std::set<int> vals2(vals.begin(),vals.end());
8400   const int *cptr=getConstPointer();
8401   int nbOfTuples=getNumberOfTuples();
8402   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8403     if(vals2.find(*w)!=vals2.end())
8404       return std::distance(cptr,w);
8405   return -1;
8406 }
8407
8408 /*!
8409  * This method returns the number of values in \a this that are equals to input parameter \a value.
8410  * This method only works for single component array.
8411  *
8412  * \return a value in [ 0, \c this->getNumberOfTuples() )
8413  *
8414  * \throw If \a this is not allocated
8415  *
8416  */
8417 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8418 {
8419   int ret=0;
8420   checkAllocated();
8421   if(getNumberOfComponents()!=1)
8422     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8423   const int *vals=begin();
8424   int nbOfTuples=getNumberOfTuples();
8425   for(int i=0;i<nbOfTuples;i++,vals++)
8426     if(*vals==value)
8427       ret++;
8428   return ret;
8429 }
8430
8431 /*!
8432  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8433  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8434  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8435  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8436  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8437  * \sa DataArrayInt::locateTuple
8438  */
8439 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8440 {
8441   return locateTuple(tupl)!=-1;
8442 }
8443
8444
8445 /*!
8446  * Returns \a true if a given value is present within \a this one-dimensional array.
8447  *  \param [in] value - the value to find within \a this array.
8448  *  \return bool - \a true in case if \a value is present within \a this array.
8449  *  \throw If \a this is not allocated.
8450  *  \throw If \a this->getNumberOfComponents() != 1.
8451  *  \sa locateValue()
8452  */
8453 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8454 {
8455   return locateValue(value)!=-1;
8456 }
8457
8458 /*!
8459  * This method expects to be called when number of components of this is equal to one.
8460  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8461  * If not any tuple contains one of the values contained in 'vals' false is returned.
8462  * \sa DataArrayInt::locateValue
8463  */
8464 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8465 {
8466   return locateValue(vals)!=-1;
8467 }
8468
8469 /*!
8470  * Accumulates values of each component of \a this array.
8471  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8472  *         by the caller, that is filled by this method with sum value for each
8473  *         component.
8474  *  \throw If \a this is not allocated.
8475  */
8476 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8477 {
8478   checkAllocated();
8479   const int *ptr=getConstPointer();
8480   int nbTuple=getNumberOfTuples();
8481   int nbComps=getNumberOfComponents();
8482   std::fill(res,res+nbComps,0);
8483   for(int i=0;i<nbTuple;i++)
8484     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8485 }
8486
8487 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8488 {
8489   checkAllocated();
8490   const int *ptr=getConstPointer();
8491   int nbTuple=getNumberOfTuples();
8492   int nbComps=getNumberOfComponents();
8493   if(compId<0 || compId>=nbComps)
8494     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8495   int ret=0;
8496   for(int i=0;i<nbTuple;i++)
8497     ret+=ptr[i*nbComps+compId];
8498   return ret;
8499 }
8500
8501 /*!
8502  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8503  * The returned array will have same number of components than \a this and number of tuples equal to
8504  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8505  *
8506  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8507  *
8508  * \param [in] bgOfIndex - begin (included) of the input index array.
8509  * \param [in] endOfIndex - end (excluded) of the input index array.
8510  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8511  * 
8512  * \throw If bgOfIndex or end is NULL.
8513  * \throw If input index array is not ascendingly sorted.
8514  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8515  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8516  */
8517 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8518 {
8519   if(!bgOfIndex || !endOfIndex)
8520     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8521   checkAllocated();
8522   int nbCompo=getNumberOfComponents();
8523   int nbOfTuples=getNumberOfTuples();
8524   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8525   if(sz<1)
8526     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8527   sz--;
8528   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8529   const int *w=bgOfIndex;
8530   if(*w<0 || *w>=nbOfTuples)
8531     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8532   const int *srcPt=begin()+(*w)*nbCompo;
8533   int *tmp=ret->getPointer();
8534   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8535     {
8536       std::fill(tmp,tmp+nbCompo,0.);
8537       if(w[1]>=w[0])
8538         {
8539           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8540             {
8541               if(j>=0 && j<nbOfTuples)
8542                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8543               else
8544                 {
8545                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8546                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8547                 }
8548             }
8549         }
8550       else
8551         {
8552           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8553           throw INTERP_KERNEL::Exception(oss.str().c_str());
8554         }
8555     }
8556   ret->copyStringInfoFrom(*this);
8557   return ret.retn();
8558 }
8559
8560 /*!
8561  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8562  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8563  * offsetA2</em> and (2)
8564  * the number of component in the result array is same as that of each of given arrays.
8565  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8566  * Info on components is copied from the first of the given arrays. Number of components
8567  * in the given arrays must be the same.
8568  *  \param [in] a1 - an array to include in the result array.
8569  *  \param [in] a2 - another array to include in the result array.
8570  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8571  *  \return DataArrayInt * - the new instance of DataArrayInt.
8572  *          The caller is to delete this result array using decrRef() as it is no more
8573  *          needed.
8574  *  \throw If either \a a1 or \a a2 is NULL.
8575  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8576  */
8577 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8578 {
8579   if(!a1 || !a2)
8580     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8581   int nbOfComp=a1->getNumberOfComponents();
8582   if(nbOfComp!=a2->getNumberOfComponents())
8583     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8584   int nbOfTuple1=a1->getNumberOfTuples();
8585   int nbOfTuple2=a2->getNumberOfTuples();
8586   DataArrayInt *ret=DataArrayInt::New();
8587   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8588   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8589   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8590   ret->copyStringInfoFrom(*a1);
8591   return ret;
8592 }
8593
8594 /*!
8595  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8596  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8597  * the number of component in the result array is same as that of each of given arrays.
8598  * Info on components is copied from the first of the given arrays. Number of components
8599  * in the given arrays must be  the same.
8600  *  \param [in] arr - a sequence of arrays to include in the result array.
8601  *  \return DataArrayInt * - the new instance of DataArrayInt.
8602  *          The caller is to delete this result array using decrRef() as it is no more
8603  *          needed.
8604  *  \throw If all arrays within \a arr are NULL.
8605  *  \throw If getNumberOfComponents() of arrays within \a arr.
8606  */
8607 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8608 {
8609   std::vector<const DataArrayInt *> a;
8610   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8611     if(*it4)
8612       a.push_back(*it4);
8613   if(a.empty())
8614     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8615   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8616   int nbOfComp=(*it)->getNumberOfComponents();
8617   int nbt=(*it++)->getNumberOfTuples();
8618   for(int i=1;it!=a.end();it++,i++)
8619     {
8620       if((*it)->getNumberOfComponents()!=nbOfComp)
8621         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8622       nbt+=(*it)->getNumberOfTuples();
8623     }
8624   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8625   ret->alloc(nbt,nbOfComp);
8626   int *pt=ret->getPointer();
8627   for(it=a.begin();it!=a.end();it++)
8628     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8629   ret->copyStringInfoFrom(*(a[0]));
8630   return ret.retn();
8631 }
8632
8633 /*!
8634  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8635  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8636  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8637  * 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.
8638  * 
8639  * \return DataArrayInt * - a new object to be managed by the caller.
8640  */
8641 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8642 {
8643   int retSz=1;
8644   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8645     {
8646       if(*it4)
8647         {
8648           (*it4)->checkAllocated();
8649           if((*it4)->getNumberOfComponents()!=1)
8650             {
8651               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8652               throw INTERP_KERNEL::Exception(oss.str().c_str());
8653             }
8654           int nbTupl=(*it4)->getNumberOfTuples();
8655           if(nbTupl<1)
8656             {
8657               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8658               throw INTERP_KERNEL::Exception(oss.str().c_str());
8659             }
8660           if((*it4)->front()!=0)
8661             {
8662               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8663               throw INTERP_KERNEL::Exception(oss.str().c_str());
8664             }
8665           retSz+=nbTupl-1;
8666         }
8667       else
8668         {
8669           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8670           throw INTERP_KERNEL::Exception(oss.str().c_str());
8671         }
8672     }
8673   if(arrs.empty())
8674     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8675   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8676   ret->alloc(retSz,1);
8677   int *pt=ret->getPointer(); *pt++=0;
8678   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8679     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8680   ret->copyStringInfoFrom(*(arrs[0]));
8681   return ret.retn();
8682 }
8683
8684 /*!
8685  * Returns the maximal value and its location within \a this one-dimensional array.
8686  *  \param [out] tupleId - index of the tuple holding the maximal value.
8687  *  \return int - the maximal value among all values of \a this array.
8688  *  \throw If \a this->getNumberOfComponents() != 1
8689  *  \throw If \a this->getNumberOfTuples() < 1
8690  */
8691 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8692 {
8693   checkAllocated();
8694   if(getNumberOfComponents()!=1)
8695     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8696   int nbOfTuples=getNumberOfTuples();
8697   if(nbOfTuples<=0)
8698     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8699   const int *vals=getConstPointer();
8700   const int *loc=std::max_element(vals,vals+nbOfTuples);
8701   tupleId=(int)std::distance(vals,loc);
8702   return *loc;
8703 }
8704
8705 /*!
8706  * Returns the maximal value within \a this array that is allowed to have more than
8707  *  one component.
8708  *  \return int - the maximal value among all values of \a this array.
8709  *  \throw If \a this is not allocated.
8710  */
8711 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8712 {
8713   checkAllocated();
8714   const int *loc=std::max_element(begin(),end());
8715   return *loc;
8716 }
8717
8718 /*!
8719  * Returns the minimal value and its location within \a this one-dimensional array.
8720  *  \param [out] tupleId - index of the tuple holding the minimal value.
8721  *  \return int - the minimal value among all values of \a this array.
8722  *  \throw If \a this->getNumberOfComponents() != 1
8723  *  \throw If \a this->getNumberOfTuples() < 1
8724  */
8725 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8726 {
8727   checkAllocated();
8728   if(getNumberOfComponents()!=1)
8729     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8730   int nbOfTuples=getNumberOfTuples();
8731   if(nbOfTuples<=0)
8732     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8733   const int *vals=getConstPointer();
8734   const int *loc=std::min_element(vals,vals+nbOfTuples);
8735   tupleId=(int)std::distance(vals,loc);
8736   return *loc;
8737 }
8738
8739 /*!
8740  * Returns the minimal value within \a this array that is allowed to have more than
8741  *  one component.
8742  *  \return int - the minimal value among all values of \a this array.
8743  *  \throw If \a this is not allocated.
8744  */
8745 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8746 {
8747   checkAllocated();
8748   const int *loc=std::min_element(begin(),end());
8749   return *loc;
8750 }
8751
8752 /*!
8753  * Converts every value of \a this array to its absolute value.
8754  *  \throw If \a this is not allocated.
8755  */
8756 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8757 {
8758   checkAllocated();
8759   int *ptr=getPointer();
8760   std::size_t nbOfElems=getNbOfElems();
8761   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8762   declareAsNew();
8763 }
8764
8765 /*!
8766  * Apply a liner function to a given component of \a this array, so that
8767  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8768  *  \param [in] a - the first coefficient of the function.
8769  *  \param [in] b - the second coefficient of the function.
8770  *  \param [in] compoId - the index of component to modify.
8771  *  \throw If \a this is not allocated.
8772  */
8773 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8774 {
8775   checkAllocated();
8776   int *ptr=getPointer()+compoId;
8777   int nbOfComp=getNumberOfComponents();
8778   int nbOfTuple=getNumberOfTuples();
8779   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8780     *ptr=a*(*ptr)+b;
8781   declareAsNew();
8782 }
8783
8784 /*!
8785  * Apply a liner function to all elements of \a this array, so that
8786  * an element _x_ becomes \f$ a * x + b \f$.
8787  *  \param [in] a - the first coefficient of the function.
8788  *  \param [in] b - the second coefficient of the function.
8789  *  \throw If \a this is not allocated.
8790  */
8791 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8792 {
8793   checkAllocated();
8794   int *ptr=getPointer();
8795   std::size_t nbOfElems=getNbOfElems();
8796   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8797     *ptr=a*(*ptr)+b;
8798   declareAsNew();
8799 }
8800
8801 /*!
8802  * Returns a full copy of \a this array except that sign of all elements is reversed.
8803  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8804  *          same number of tuples and component as \a this array.
8805  *          The caller is to delete this result array using decrRef() as it is no more
8806  *          needed.
8807  *  \throw If \a this is not allocated.
8808  */
8809 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8810 {
8811   checkAllocated();
8812   DataArrayInt *newArr=DataArrayInt::New();
8813   int nbOfTuples=getNumberOfTuples();
8814   int nbOfComp=getNumberOfComponents();
8815   newArr->alloc(nbOfTuples,nbOfComp);
8816   const int *cptr=getConstPointer();
8817   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8818   newArr->copyStringInfoFrom(*this);
8819   return newArr;
8820 }
8821
8822 /*!
8823  * Modify all elements of \a this array, so that
8824  * an element _x_ becomes \f$ numerator / x \f$.
8825  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8826  *           array, all elements processed before detection of the zero element remain
8827  *           modified.
8828  *  \param [in] numerator - the numerator used to modify array elements.
8829  *  \throw If \a this is not allocated.
8830  *  \throw If there is an element equal to 0 in \a this array.
8831  */
8832 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8833 {
8834   checkAllocated();
8835   int *ptr=getPointer();
8836   std::size_t nbOfElems=getNbOfElems();
8837   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8838     {
8839       if(*ptr!=0)
8840         {
8841           *ptr=numerator/(*ptr);
8842         }
8843       else
8844         {
8845           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8846           oss << " !";
8847           throw INTERP_KERNEL::Exception(oss.str().c_str());
8848         }
8849     }
8850   declareAsNew();
8851 }
8852
8853 /*!
8854  * Modify all elements of \a this array, so that
8855  * an element _x_ becomes \f$ x / val \f$.
8856  *  \param [in] val - the denominator used to modify array elements.
8857  *  \throw If \a this is not allocated.
8858  *  \throw If \a val == 0.
8859  */
8860 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8861 {
8862   if(val==0)
8863     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8864   checkAllocated();
8865   int *ptr=getPointer();
8866   std::size_t nbOfElems=getNbOfElems();
8867   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8868   declareAsNew();
8869 }
8870
8871 /*!
8872  * Modify all elements of \a this array, so that
8873  * an element _x_ becomes  <em> x % val </em>.
8874  *  \param [in] val - the divisor used to modify array elements.
8875  *  \throw If \a this is not allocated.
8876  *  \throw If \a val <= 0.
8877  */
8878 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8879 {
8880   if(val<=0)
8881     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8882   checkAllocated();
8883   int *ptr=getPointer();
8884   std::size_t nbOfElems=getNbOfElems();
8885   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8886   declareAsNew();
8887 }
8888
8889 /*!
8890  * This method works only on data array with one component.
8891  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8892  * this[*id] in [\b vmin,\b vmax)
8893  * 
8894  * \param [in] vmin begin of range. This value is included in range (included).
8895  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8896  * \return a newly allocated data array that the caller should deal with.
8897  */
8898 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8899 {
8900   checkAllocated();
8901   if(getNumberOfComponents()!=1)
8902     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8903   const int *cptr=getConstPointer();
8904   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8905   int nbOfTuples=getNumberOfTuples();
8906   for(int i=0;i<nbOfTuples;i++,cptr++)
8907     if(*cptr>=vmin && *cptr<vmax)
8908       ret->pushBackSilent(i);
8909   return ret.retn();
8910 }
8911
8912 /*!
8913  * This method works only on data array with one component.
8914  * 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.
8915  * 
8916  * \param [in] vmin begin of range. This value is included in range (included).
8917  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8918  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8919  */
8920 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8921 {
8922   checkAllocated();
8923   if(getNumberOfComponents()!=1)
8924     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8925   int nbOfTuples=getNumberOfTuples();
8926   bool ret=true;
8927   const int *cptr=getConstPointer();
8928   for(int i=0;i<nbOfTuples;i++,cptr++)
8929     {
8930       if(*cptr>=vmin && *cptr<vmax)
8931         { ret=ret && *cptr==i; }
8932       else
8933         {
8934           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8935           throw INTERP_KERNEL::Exception(oss.str().c_str());
8936         }
8937     }
8938   return ret;
8939 }
8940
8941 /*!
8942  * Modify all elements of \a this array, so that
8943  * an element _x_ becomes <em> val % x </em>.
8944  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8945  *           array, all elements processed before detection of the zero element remain
8946  *           modified.
8947  *  \param [in] val - the divident used to modify array elements.
8948  *  \throw If \a this is not allocated.
8949  *  \throw If there is an element equal to or less than 0 in \a this array.
8950  */
8951 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8952 {
8953   checkAllocated();
8954   int *ptr=getPointer();
8955   std::size_t nbOfElems=getNbOfElems();
8956   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8957     {
8958       if(*ptr>0)
8959         {
8960           *ptr=val%(*ptr);
8961         }
8962       else
8963         {
8964           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8965           oss << " !";
8966           throw INTERP_KERNEL::Exception(oss.str().c_str());
8967         }
8968     }
8969   declareAsNew();
8970 }
8971
8972 /*!
8973  * Modify all elements of \a this array, so that
8974  * an element _x_ becomes <em> val ^ x </em>.
8975  *  \param [in] val - the value used to apply pow on all array elements.
8976  *  \throw If \a this is not allocated.
8977  *  \throw If \a val < 0.
8978  */
8979 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8980 {
8981   checkAllocated();
8982   if(val<0)
8983     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8984   int *ptr=getPointer();
8985   std::size_t nbOfElems=getNbOfElems();
8986   if(val==0)
8987     {
8988       std::fill(ptr,ptr+nbOfElems,1.);
8989       return ;
8990     }
8991   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8992     {
8993       int tmp=1;
8994       for(int j=0;j<val;j++)
8995         tmp*=*ptr;
8996       *ptr=tmp;
8997     }
8998   declareAsNew();
8999 }
9000
9001 /*!
9002  * Modify all elements of \a this array, so that
9003  * an element _x_ becomes \f$ val ^ x \f$.
9004  *  \param [in] val - the value used to apply pow on all array elements.
9005  *  \throw If \a this is not allocated.
9006  *  \throw If there is an element < 0 in \a this array.
9007  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9008  *           array, all elements processed before detection of the zero element remain
9009  *           modified.
9010  */
9011 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
9012 {
9013   checkAllocated();
9014   int *ptr=getPointer();
9015   std::size_t nbOfElems=getNbOfElems();
9016   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9017     {
9018       if(*ptr>=0)
9019         {
9020           int tmp=1;
9021           for(int j=0;j<*ptr;j++)
9022             tmp*=val;
9023           *ptr=tmp;
9024         }
9025       else
9026         {
9027           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9028           oss << " !";
9029           throw INTERP_KERNEL::Exception(oss.str().c_str());
9030         }
9031     }
9032   declareAsNew();
9033 }
9034
9035 /*!
9036  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9037  * of components in the result array is a sum of the number of components of given arrays
9038  * and (2) the number of tuples in the result array is same as that of each of given
9039  * arrays. In other words the i-th tuple of result array includes all components of
9040  * i-th tuples of all given arrays.
9041  * Number of tuples in the given arrays must be the same.
9042  *  \param [in] a1 - an array to include in the result array.
9043  *  \param [in] a2 - another array to include in the result array.
9044  *  \return DataArrayInt * - the new instance of DataArrayInt.
9045  *          The caller is to delete this result array using decrRef() as it is no more
9046  *          needed.
9047  *  \throw If both \a a1 and \a a2 are NULL.
9048  *  \throw If any given array is not allocated.
9049  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9050  */
9051 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9052 {
9053   std::vector<const DataArrayInt *> arr(2);
9054   arr[0]=a1; arr[1]=a2;
9055   return Meld(arr);
9056 }
9057
9058 /*!
9059  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9060  * of components in the result array is a sum of the number of components of given arrays
9061  * and (2) the number of tuples in the result array is same as that of each of given
9062  * arrays. In other words the i-th tuple of result array includes all components of
9063  * i-th tuples of all given arrays.
9064  * Number of tuples in the given arrays must be  the same.
9065  *  \param [in] arr - a sequence of arrays to include in the result array.
9066  *  \return DataArrayInt * - the new instance of DataArrayInt.
9067  *          The caller is to delete this result array using decrRef() as it is no more
9068  *          needed.
9069  *  \throw If all arrays within \a arr are NULL.
9070  *  \throw If any given array is not allocated.
9071  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9072  */
9073 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9074 {
9075   std::vector<const DataArrayInt *> a;
9076   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9077     if(*it4)
9078       a.push_back(*it4);
9079   if(a.empty())
9080     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9081   std::vector<const DataArrayInt *>::const_iterator it;
9082   for(it=a.begin();it!=a.end();it++)
9083     (*it)->checkAllocated();
9084   it=a.begin();
9085   int nbOfTuples=(*it)->getNumberOfTuples();
9086   std::vector<int> nbc(a.size());
9087   std::vector<const int *> pts(a.size());
9088   nbc[0]=(*it)->getNumberOfComponents();
9089   pts[0]=(*it++)->getConstPointer();
9090   for(int i=1;it!=a.end();it++,i++)
9091     {
9092       if(nbOfTuples!=(*it)->getNumberOfTuples())
9093         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9094       nbc[i]=(*it)->getNumberOfComponents();
9095       pts[i]=(*it)->getConstPointer();
9096     }
9097   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9098   DataArrayInt *ret=DataArrayInt::New();
9099   ret->alloc(nbOfTuples,totalNbOfComp);
9100   int *retPtr=ret->getPointer();
9101   for(int i=0;i<nbOfTuples;i++)
9102     for(int j=0;j<(int)a.size();j++)
9103       {
9104         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9105         pts[j]+=nbc[j];
9106       }
9107   int k=0;
9108   for(int i=0;i<(int)a.size();i++)
9109     for(int j=0;j<nbc[i];j++,k++)
9110       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9111   return ret;
9112 }
9113
9114 /*!
9115  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9116  * The i-th item of the result array is an ID of a set of elements belonging to a
9117  * unique set of groups, which the i-th element is a part of. This set of elements
9118  * belonging to a unique set of groups is called \a family, so the result array contains
9119  * IDs of families each element belongs to.
9120  *
9121  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9122  * then there are 3 families:
9123  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9124  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9125  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9126  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9127  * stands for the element #3 which is in none of groups.
9128  *
9129  *  \param [in] groups - sequence of groups of element IDs.
9130  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9131  *         in \a groups.
9132  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9133  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9134  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9135  *         delete this array using decrRef() as it is no more needed.
9136  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9137  */
9138 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
9139 {
9140   std::vector<const DataArrayInt *> groups2;
9141   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9142     if(*it4)
9143       groups2.push_back(*it4);
9144   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9145   ret->alloc(newNb,1);
9146   int *retPtr=ret->getPointer();
9147   std::fill(retPtr,retPtr+newNb,0);
9148   int fid=1;
9149   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9150     {
9151       const int *ptr=(*iter)->getConstPointer();
9152       std::size_t nbOfElem=(*iter)->getNbOfElems();
9153       int sfid=fid;
9154       for(int j=0;j<sfid;j++)
9155         {
9156           bool found=false;
9157           for(std::size_t i=0;i<nbOfElem;i++)
9158             {
9159               if(ptr[i]>=0 && ptr[i]<newNb)
9160                 {
9161                   if(retPtr[ptr[i]]==j)
9162                     {
9163                       retPtr[ptr[i]]=fid;
9164                       found=true;
9165                     }
9166                 }
9167               else
9168                 {
9169                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9170                   oss << ") !";
9171                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9172                 }
9173             }
9174           if(found)
9175             fid++;
9176         }
9177     }
9178   fidsOfGroups.clear();
9179   fidsOfGroups.resize(groups2.size());
9180   int grId=0;
9181   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9182     {
9183       std::set<int> tmp;
9184       const int *ptr=(*iter)->getConstPointer();
9185       std::size_t nbOfElem=(*iter)->getNbOfElems();
9186       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9187         tmp.insert(retPtr[*p]);
9188       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9189     }
9190   return ret.retn();
9191 }
9192
9193 /*!
9194  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9195  * arrays. The result array does not contain any duplicates and its values
9196  * are sorted in ascending order.
9197  *  \param [in] arr - sequence of DataArrayInt's to unite.
9198  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9199  *         array using decrRef() as it is no more needed.
9200  *  \throw If any \a arr[i] is not allocated.
9201  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9202  */
9203 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9204 {
9205   std::vector<const DataArrayInt *> a;
9206   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9207     if(*it4)
9208       a.push_back(*it4);
9209   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9210     {
9211       (*it)->checkAllocated();
9212       if((*it)->getNumberOfComponents()!=1)
9213         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9214     }
9215   //
9216   std::set<int> r;
9217   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9218     {
9219       const int *pt=(*it)->getConstPointer();
9220       int nbOfTuples=(*it)->getNumberOfTuples();
9221       r.insert(pt,pt+nbOfTuples);
9222     }
9223   DataArrayInt *ret=DataArrayInt::New();
9224   ret->alloc((int)r.size(),1);
9225   std::copy(r.begin(),r.end(),ret->getPointer());
9226   return ret;
9227 }
9228
9229 /*!
9230  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9231  * arrays. The result array does not contain any duplicates and its values
9232  * are sorted in ascending order.
9233  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9234  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9235  *         array using decrRef() as it is no more needed.
9236  *  \throw If any \a arr[i] is not allocated.
9237  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9238  */
9239 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9240 {
9241   std::vector<const DataArrayInt *> a;
9242   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9243     if(*it4)
9244       a.push_back(*it4);
9245   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9246     {
9247       (*it)->checkAllocated();
9248       if((*it)->getNumberOfComponents()!=1)
9249         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9250     }
9251   //
9252   std::set<int> r;
9253   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9254     {
9255       const int *pt=(*it)->getConstPointer();
9256       int nbOfTuples=(*it)->getNumberOfTuples();
9257       std::set<int> s1(pt,pt+nbOfTuples);
9258       if(it!=a.begin())
9259         {
9260           std::set<int> r2;
9261           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9262           r=r2;
9263         }
9264       else
9265         r=s1;
9266     }
9267   DataArrayInt *ret=DataArrayInt::New();
9268   ret->alloc((int)r.size(),1);
9269   std::copy(r.begin(),r.end(),ret->getPointer());
9270   return ret;
9271 }
9272
9273 /*!
9274  * Returns a new DataArrayInt which contains a complement of elements of \a this
9275  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9276  * \a nbOfElement) not present in \a this array.
9277  *  \param [in] nbOfElement - maximal size of the result array.
9278  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9279  *         array using decrRef() as it is no more needed.
9280  *  \throw If \a this is not allocated.
9281  *  \throw If \a this->getNumberOfComponents() != 1.
9282  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9283  *         nbOfElement ).
9284  */
9285 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9286 {
9287    checkAllocated();
9288    if(getNumberOfComponents()!=1)
9289      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9290    std::vector<bool> tmp(nbOfElement);
9291    const int *pt=getConstPointer();
9292    int nbOfTuples=getNumberOfTuples();
9293    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9294      if(*w>=0 && *w<nbOfElement)
9295        tmp[*w]=true;
9296      else
9297        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9298    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9299    DataArrayInt *ret=DataArrayInt::New();
9300    ret->alloc(nbOfRetVal,1);
9301    int j=0;
9302    int *retPtr=ret->getPointer();
9303    for(int i=0;i<nbOfElement;i++)
9304      if(!tmp[i])
9305        retPtr[j++]=i;
9306    return ret;
9307 }
9308
9309 /*!
9310  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9311  * from an \a other one-dimensional array.
9312  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9313  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9314  *         caller is to delete this array using decrRef() as it is no more needed.
9315  *  \throw If \a other is NULL.
9316  *  \throw If \a other is not allocated.
9317  *  \throw If \a other->getNumberOfComponents() != 1.
9318  *  \throw If \a this is not allocated.
9319  *  \throw If \a this->getNumberOfComponents() != 1.
9320  *  \sa DataArrayInt::buildSubstractionOptimized()
9321  */
9322 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9323 {
9324   if(!other)
9325     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9326   checkAllocated();
9327   other->checkAllocated();
9328   if(getNumberOfComponents()!=1)
9329      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9330   if(other->getNumberOfComponents()!=1)
9331      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9332   const int *pt=getConstPointer();
9333   int nbOfTuples=getNumberOfTuples();
9334   std::set<int> s1(pt,pt+nbOfTuples);
9335   pt=other->getConstPointer();
9336   nbOfTuples=other->getNumberOfTuples();
9337   std::set<int> s2(pt,pt+nbOfTuples);
9338   std::vector<int> r;
9339   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9340   DataArrayInt *ret=DataArrayInt::New();
9341   ret->alloc((int)r.size(),1);
9342   std::copy(r.begin(),r.end(),ret->getPointer());
9343   return ret;
9344 }
9345
9346 /*!
9347  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9348  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9349  * 
9350  * \param [in] other an array with one component and expected to be sorted ascendingly.
9351  * \ret list of ids in \a this but not in \a other.
9352  * \sa DataArrayInt::buildSubstraction
9353  */
9354 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9355 {
9356   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9357   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9358   checkAllocated(); other->checkAllocated();
9359   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9360   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9361   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9362   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9363   for(;work1!=pt1End;work1++)
9364     {
9365       if(work2!=pt2End && *work1==*work2)
9366         work2++;
9367       else
9368         ret->pushBackSilent(*work1);
9369     }
9370   return ret.retn();
9371 }
9372
9373
9374 /*!
9375  * Returns a new DataArrayInt which contains all elements of \a this and a given
9376  * one-dimensional arrays. The result array does not contain any duplicates
9377  * and its values are sorted in ascending order.
9378  *  \param [in] other - an array to unite with \a this one.
9379  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9380  *         array using decrRef() as it is no more needed.
9381  *  \throw If \a this or \a other is not allocated.
9382  *  \throw If \a this->getNumberOfComponents() != 1.
9383  *  \throw If \a other->getNumberOfComponents() != 1.
9384  */
9385 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9386 {
9387   std::vector<const DataArrayInt *>arrs(2);
9388   arrs[0]=this; arrs[1]=other;
9389   return BuildUnion(arrs);
9390 }
9391
9392
9393 /*!
9394  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9395  * one-dimensional arrays. The result array does not contain any duplicates
9396  * and its values are sorted in ascending order.
9397  *  \param [in] other - an array to intersect with \a this one.
9398  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9399  *         array using decrRef() as it is no more needed.
9400  *  \throw If \a this or \a other is not allocated.
9401  *  \throw If \a this->getNumberOfComponents() != 1.
9402  *  \throw If \a other->getNumberOfComponents() != 1.
9403  */
9404 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9405 {
9406   std::vector<const DataArrayInt *>arrs(2);
9407   arrs[0]=this; arrs[1]=other;
9408   return BuildIntersection(arrs);
9409 }
9410
9411 /*!
9412  * This method can be applied on allocated with one component DataArrayInt instance.
9413  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9414  * 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]
9415  * 
9416  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9417  * \throw if \a this is not allocated or if \a this has not exactly one component.
9418  */
9419 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9420 {
9421   checkAllocated();
9422   if(getNumberOfComponents()!=1)
9423      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9424   int nbOfTuples=getNumberOfTuples();
9425   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9426   int *data=tmp->getPointer();
9427   int *last=std::unique(data,data+nbOfTuples);
9428   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9429   ret->alloc(std::distance(data,last),1);
9430   std::copy(data,last,ret->getPointer());
9431   return ret.retn();
9432 }
9433
9434 /*!
9435  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9436  * "index" array. Such "index" array is returned for example by 
9437  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9438  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9439  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9440  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9441  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9442  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9443  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9444  *          The caller is to delete this array using decrRef() as it is no more needed. 
9445  *  \throw If \a this is not allocated.
9446  *  \throw If \a this->getNumberOfComponents() != 1.
9447  *  \throw If \a this->getNumberOfTuples() < 2.
9448  *
9449  *  \b Example: <br> 
9450  *         - this contains [1,3,6,7,7,9,15]
9451  *         - result array contains [2,3,1,0,2,6],
9452  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9453  *
9454  * \sa DataArrayInt::computeOffsets2
9455  */
9456 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9457 {
9458   checkAllocated();
9459   if(getNumberOfComponents()!=1)
9460      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9461   int nbOfTuples=getNumberOfTuples();
9462   if(nbOfTuples<2)
9463     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9464   const int *ptr=getConstPointer();
9465   DataArrayInt *ret=DataArrayInt::New();
9466   ret->alloc(nbOfTuples-1,1);
9467   int *out=ret->getPointer();
9468   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9469   return ret;
9470 }
9471
9472 /*!
9473  * Modifies \a this one-dimensional array so that value of each element \a x
9474  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9475  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9476  * and components remains the same.<br>
9477  * This method is useful for allToAllV in MPI with contiguous policy. This method
9478  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9479  * this one.
9480  *  \throw If \a this is not allocated.
9481  *  \throw If \a this->getNumberOfComponents() != 1.
9482  *
9483  *  \b Example: <br>
9484  *          - Before \a this contains [3,5,1,2,0,8]
9485  *          - After \a this contains  [0,3,8,9,11,11]<br>
9486  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9487  *          array is retained and thus there is no space to store the last element.
9488  */
9489 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9490 {
9491   checkAllocated();
9492   if(getNumberOfComponents()!=1)
9493      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9494   int nbOfTuples=getNumberOfTuples();
9495   if(nbOfTuples==0)
9496     return ;
9497   int *work=getPointer();
9498   int tmp=work[0];
9499   work[0]=0;
9500   for(int i=1;i<nbOfTuples;i++)
9501     {
9502       int tmp2=work[i];
9503       work[i]=work[i-1]+tmp;
9504       tmp=tmp2;
9505     }
9506   declareAsNew();
9507 }
9508
9509
9510 /*!
9511  * Modifies \a this one-dimensional array so that value of each element \a x
9512  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9513  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9514  * components remains the same and number of tuples is inceamented by one.<br>
9515  * This method is useful for allToAllV in MPI with contiguous policy. This method
9516  * differs from computeOffsets() in that the number of tuples is changed by this one.
9517  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9518  *  \throw If \a this is not allocated.
9519  *  \throw If \a this->getNumberOfComponents() != 1.
9520  *
9521  *  \b Example: <br>
9522  *          - Before \a this contains [3,5,1,2,0,8]
9523  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9524  * \sa DataArrayInt::deltaShiftIndex
9525  */
9526 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9527 {
9528   checkAllocated();
9529   if(getNumberOfComponents()!=1)
9530     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9531   int nbOfTuples=getNumberOfTuples();
9532   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9533   if(nbOfTuples==0)
9534     return ;
9535   const int *work=getConstPointer();
9536   ret[0]=0;
9537   for(int i=0;i<nbOfTuples;i++)
9538     ret[i+1]=work[i]+ret[i];
9539   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9540   declareAsNew();
9541 }
9542
9543 /*!
9544  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9545  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9546  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9547  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9548  * filling completely one of the ranges in \a this.
9549  *
9550  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9551  * \param [out] rangeIdsFetched the range ids fetched
9552  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9553  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9554  *
9555  * \sa DataArrayInt::computeOffsets2
9556  *
9557  *  \b Example: <br>
9558  *          - \a this : [0,3,7,9,15,18]
9559  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9560  *          - \a rangeIdsFetched result array: [0,2,4]
9561  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9562  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9563  * <br>
9564  */
9565 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9566 {
9567   if(!listOfIds)
9568     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9569   listOfIds->checkAllocated(); checkAllocated();
9570   if(listOfIds->getNumberOfComponents()!=1)
9571     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9572   if(getNumberOfComponents()!=1)
9573     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9574   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9575   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9576   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9577   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9578   while(tupPtr!=tupEnd && offPtr!=offEnd)
9579     {
9580       if(*tupPtr==*offPtr)
9581         {
9582           int i=offPtr[0];
9583           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9584           if(i==offPtr[1])
9585             {
9586               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9587               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9588               offPtr++;
9589             }
9590         }
9591       else
9592         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9593     }
9594   rangeIdsFetched=ret0.retn();
9595   idsInInputListThatFetch=ret1.retn();
9596 }
9597
9598 /*!
9599  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9600  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9601  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9602  * beginning within the "iota" array. And \a this is a one-dimensional array
9603  * considered as a selector of groups described by \a offsets to include into the result array.
9604  *  \throw If \a offsets is NULL.
9605  *  \throw If \a offsets is not allocated.
9606  *  \throw If \a offsets->getNumberOfComponents() != 1.
9607  *  \throw If \a offsets is not monotonically increasing.
9608  *  \throw If \a this is not allocated.
9609  *  \throw If \a this->getNumberOfComponents() != 1.
9610  *  \throw If any element of \a this is not a valid index for \a offsets array.
9611  *
9612  *  \b Example: <br>
9613  *          - \a this: [0,2,3]
9614  *          - \a offsets: [0,3,6,10,14,20]
9615  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9616  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9617  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9618  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9619  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9620  */
9621 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9622 {
9623   if(!offsets)
9624     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9625   checkAllocated();
9626   if(getNumberOfComponents()!=1)
9627      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9628   offsets->checkAllocated();
9629   if(offsets->getNumberOfComponents()!=1)
9630      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9631   int othNbTuples=offsets->getNumberOfTuples()-1;
9632   int nbOfTuples=getNumberOfTuples();
9633   int retNbOftuples=0;
9634   const int *work=getConstPointer();
9635   const int *offPtr=offsets->getConstPointer();
9636   for(int i=0;i<nbOfTuples;i++)
9637     {
9638       int val=work[i];
9639       if(val>=0 && val<othNbTuples)
9640         {
9641           int delta=offPtr[val+1]-offPtr[val];
9642           if(delta>=0)
9643             retNbOftuples+=delta;
9644           else
9645             {
9646               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9647               throw INTERP_KERNEL::Exception(oss.str().c_str());
9648             }
9649         }
9650       else
9651         {
9652           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9653           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9654           throw INTERP_KERNEL::Exception(oss.str().c_str());
9655         }
9656     }
9657   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9658   ret->alloc(retNbOftuples,1);
9659   int *retPtr=ret->getPointer();
9660   for(int i=0;i<nbOfTuples;i++)
9661     {
9662       int val=work[i];
9663       int start=offPtr[val];
9664       int off=offPtr[val+1]-start;
9665       for(int j=0;j<off;j++,retPtr++)
9666         *retPtr=start+j;
9667     }
9668   return ret.retn();
9669 }
9670
9671 /*!
9672  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9673  * scaled array (monotonically increasing).
9674 from that of \a this and \a
9675  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9676  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9677  * beginning within the "iota" array. And \a this is a one-dimensional array
9678  * considered as a selector of groups described by \a offsets to include into the result array.
9679  *  \throw If \a  is NULL.
9680  *  \throw If \a this is not allocated.
9681  *  \throw If \a this->getNumberOfComponents() != 1.
9682  *  \throw If \a this->getNumberOfTuples() == 0.
9683  *  \throw If \a this is not monotonically increasing.
9684  *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
9685  *
9686  *  \b Example: <br>
9687  *          - \a bg , \a end and \a step : (0,5,2)
9688  *          - \a this: [0,3,6,10,14,20]
9689  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9690  */
9691 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const throw(INTERP_KERNEL::Exception)
9692 {
9693   if(!isAllocated())
9694     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9695   if(getNumberOfComponents()!=1)
9696     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9697   int nbOfTuples(getNumberOfTuples());
9698   if(nbOfTuples==0)
9699     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9700   const int *ids(begin());
9701   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9702   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9703     {
9704       if(pos>=0 && pos<nbOfTuples-1)
9705         {
9706           int delta(ids[pos+1]-ids[pos]);
9707           sz+=delta;
9708           if(delta<0)
9709             {
9710               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9711               throw INTERP_KERNEL::Exception(oss.str().c_str());
9712             }          
9713         }
9714       else
9715         {
9716           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9717           throw INTERP_KERNEL::Exception(oss.str().c_str());
9718         }
9719     }
9720   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9721   int *retPtr(ret->getPointer());
9722   pos=bg;
9723   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9724     {
9725       int delta(ids[pos+1]-ids[pos]);
9726       for(int j=0;j<delta;j++,retPtr++)
9727         *retPtr=pos;
9728     }
9729   return ret.retn();
9730 }
9731
9732 /*!
9733  * 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.
9734  * 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
9735  * in tuple **i** of returned DataArrayInt.
9736  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9737  *
9738  * 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)]
9739  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9740  * 
9741  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9742  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9743  * \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
9744  *        is thrown if no ranges in \a ranges contains value in \a this.
9745  * 
9746  * \sa DataArrayInt::findIdInRangeForEachTuple
9747  */
9748 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9749 {
9750   if(!ranges)
9751     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9752   if(ranges->getNumberOfComponents()!=2)
9753     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9754   checkAllocated();
9755   if(getNumberOfComponents()!=1)
9756     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9757   int nbTuples=getNumberOfTuples();
9758   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9759   int nbOfRanges=ranges->getNumberOfTuples();
9760   const int *rangesPtr=ranges->getConstPointer();
9761   int *retPtr=ret->getPointer();
9762   const int *inPtr=getConstPointer();
9763   for(int i=0;i<nbTuples;i++,retPtr++)
9764     {
9765       int val=inPtr[i];
9766       bool found=false;
9767       for(int j=0;j<nbOfRanges && !found;j++)
9768         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9769           { *retPtr=j; found=true; }
9770       if(found)
9771         continue;
9772       else
9773         {
9774           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9775           throw INTERP_KERNEL::Exception(oss.str().c_str());
9776         }
9777     }
9778   return ret.retn();
9779 }
9780
9781 /*!
9782  * 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.
9783  * 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
9784  * in tuple **i** of returned DataArrayInt.
9785  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9786  *
9787  * 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)]
9788  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9789  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9790  * 
9791  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9792  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9793  * \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
9794  *        is thrown if no ranges in \a ranges contains value in \a this.
9795  * \sa DataArrayInt::findRangeIdForEachTuple
9796  */
9797 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9798 {
9799   if(!ranges)
9800     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9801   if(ranges->getNumberOfComponents()!=2)
9802     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9803   checkAllocated();
9804   if(getNumberOfComponents()!=1)
9805     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9806   int nbTuples=getNumberOfTuples();
9807   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9808   int nbOfRanges=ranges->getNumberOfTuples();
9809   const int *rangesPtr=ranges->getConstPointer();
9810   int *retPtr=ret->getPointer();
9811   const int *inPtr=getConstPointer();
9812   for(int i=0;i<nbTuples;i++,retPtr++)
9813     {
9814       int val=inPtr[i];
9815       bool found=false;
9816       for(int j=0;j<nbOfRanges && !found;j++)
9817         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9818           { *retPtr=val-rangesPtr[2*j]; found=true; }
9819       if(found)
9820         continue;
9821       else
9822         {
9823           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9824           throw INTERP_KERNEL::Exception(oss.str().c_str());
9825         }
9826     }
9827   return ret.retn();
9828 }
9829
9830 /*!
9831  * 
9832  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9833  *             \a nbTimes  should be at least equal to 1.
9834  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9835  * \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.
9836  */
9837 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9838 {
9839   checkAllocated();
9840   if(getNumberOfComponents()!=1)
9841     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9842   if(nbTimes<1)
9843     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9844   int nbTuples=getNumberOfTuples();
9845   const int *inPtr=getConstPointer();
9846   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9847   int *retPtr=ret->getPointer();
9848   for(int i=0;i<nbTuples;i++,inPtr++)
9849     {
9850       int val=*inPtr;
9851       for(int j=0;j<nbTimes;j++,retPtr++)
9852         *retPtr=val;
9853     }
9854   ret->copyStringInfoFrom(*this);
9855   return ret.retn();
9856 }
9857
9858 /*!
9859  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9860  * But the number of components can be different from one.
9861  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9862  */
9863 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9864 {
9865   checkAllocated();
9866   std::set<int> ret;
9867   ret.insert(begin(),end());
9868   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9869   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9870   return ret2.retn();
9871 }
9872
9873 /*!
9874  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9875  * them it tells which tuple id have this id.
9876  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9877  * This method returns two arrays having same size.
9878  * 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.
9879  * 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]]
9880  */
9881 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9882 {
9883   checkAllocated();
9884   if(getNumberOfComponents()!=1)
9885     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9886   int id=0;
9887   std::map<int,int> m,m2,m3;
9888   for(const int *w=begin();w!=end();w++)
9889     m[*w]++;
9890   differentIds.resize(m.size());
9891   std::vector<DataArrayInt *> ret(m.size());
9892   std::vector<int *> retPtr(m.size());
9893   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9894     {
9895       m2[(*it).first]=id;
9896       ret[id]=DataArrayInt::New();
9897       ret[id]->alloc((*it).second,1);
9898       retPtr[id]=ret[id]->getPointer();
9899       differentIds[id]=(*it).first;
9900     }
9901   id=0;
9902   for(const int *w=begin();w!=end();w++,id++)
9903     {
9904       retPtr[m2[*w]][m3[*w]++]=id;
9905     }
9906   return ret;
9907 }
9908
9909 /*!
9910  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
9911  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
9912  *
9913  * \param [in] nbOfSlices - number of slices expected.
9914  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
9915  * 
9916  * \sa DataArray::GetSlice
9917  * \throw If \a this is not allocated or not with exactly one component.
9918  * \throw If an element in \a this if < 0.
9919  */
9920 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception)
9921 {
9922   if(!isAllocated() || getNumberOfComponents()!=1)
9923     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
9924   if(nbOfSlices<=0)
9925     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
9926   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
9927   int sumPerSlc(sum/nbOfSlices),pos(0);
9928   const int *w(begin());
9929   std::vector< std::pair<int,int> > ret(nbOfSlices);
9930   for(int i=0;i<nbOfSlices;i++)
9931     {
9932       std::pair<int,int> p(pos,-1);
9933       int locSum(0);
9934       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
9935       if(i!=nbOfSlices-1)
9936         p.second=pos;
9937       else
9938         p.second=nbOfTuples;
9939       ret[i]=p;
9940     }
9941   return ret;
9942 }
9943
9944 /*!
9945  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9946  * valid cases.
9947  * 1.  The arrays have same number of tuples and components. Then each value of
9948  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9949  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9950  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9951  *   component. Then
9952  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9953  * 3.  The arrays have same number of components and one array, say _a2_, has one
9954  *   tuple. Then
9955  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9956  *
9957  * Info on components is copied either from the first array (in the first case) or from
9958  * the array with maximal number of elements (getNbOfElems()).
9959  *  \param [in] a1 - an array to sum up.
9960  *  \param [in] a2 - another array to sum up.
9961  *  \return DataArrayInt * - the new instance of DataArrayInt.
9962  *          The caller is to delete this result array using decrRef() as it is no more
9963  *          needed.
9964  *  \throw If either \a a1 or \a a2 is NULL.
9965  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9966  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9967  *         none of them has number of tuples or components equal to 1.
9968  */
9969 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9970 {
9971   if(!a1 || !a2)
9972     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9973   int nbOfTuple=a1->getNumberOfTuples();
9974   int nbOfTuple2=a2->getNumberOfTuples();
9975   int nbOfComp=a1->getNumberOfComponents();
9976   int nbOfComp2=a2->getNumberOfComponents();
9977   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9978   if(nbOfTuple==nbOfTuple2)
9979     {
9980       if(nbOfComp==nbOfComp2)
9981         {
9982           ret=DataArrayInt::New();
9983           ret->alloc(nbOfTuple,nbOfComp);
9984           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9985           ret->copyStringInfoFrom(*a1);
9986         }
9987       else
9988         {
9989           int nbOfCompMin,nbOfCompMax;
9990           const DataArrayInt *aMin, *aMax;
9991           if(nbOfComp>nbOfComp2)
9992             {
9993               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9994               aMin=a2; aMax=a1;
9995             }
9996           else
9997             {
9998               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9999               aMin=a1; aMax=a2;
10000             }
10001           if(nbOfCompMin==1)
10002             {
10003               ret=DataArrayInt::New();
10004               ret->alloc(nbOfTuple,nbOfCompMax);
10005               const int *aMinPtr=aMin->getConstPointer();
10006               const int *aMaxPtr=aMax->getConstPointer();
10007               int *res=ret->getPointer();
10008               for(int i=0;i<nbOfTuple;i++)
10009                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10010               ret->copyStringInfoFrom(*aMax);
10011             }
10012           else
10013             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10014         }
10015     }
10016   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10017     {
10018       if(nbOfComp==nbOfComp2)
10019         {
10020           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10021           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10022           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10023           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10024           ret=DataArrayInt::New();
10025           ret->alloc(nbOfTupleMax,nbOfComp);
10026           int *res=ret->getPointer();
10027           for(int i=0;i<nbOfTupleMax;i++)
10028             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10029           ret->copyStringInfoFrom(*aMax);
10030         }
10031       else
10032         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10033     }
10034   else
10035     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10036   return ret.retn();
10037 }
10038
10039 /*!
10040  * Adds values of another DataArrayInt to values of \a this one. There are 3
10041  * valid cases.
10042  * 1.  The arrays have same number of tuples and components. Then each value of
10043  *   \a other array is added to the corresponding value of \a this array, i.e.:
10044  *   _a_ [ i, j ] += _other_ [ i, j ].
10045  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10046  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10047  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10048  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10049  *
10050  *  \param [in] other - an array to add to \a this one.
10051  *  \throw If \a other is NULL.
10052  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10053  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10054  *         \a other has number of both tuples and components not equal to 1.
10055  */
10056 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10057 {
10058   if(!other)
10059     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10060   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10061   checkAllocated(); other->checkAllocated();
10062   int nbOfTuple=getNumberOfTuples();
10063   int nbOfTuple2=other->getNumberOfTuples();
10064   int nbOfComp=getNumberOfComponents();
10065   int nbOfComp2=other->getNumberOfComponents();
10066   if(nbOfTuple==nbOfTuple2)
10067     {
10068       if(nbOfComp==nbOfComp2)
10069         {
10070           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10071         }
10072       else if(nbOfComp2==1)
10073         {
10074           int *ptr=getPointer();
10075           const int *ptrc=other->getConstPointer();
10076           for(int i=0;i<nbOfTuple;i++)
10077             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10078         }
10079       else
10080         throw INTERP_KERNEL::Exception(msg);
10081     }
10082   else if(nbOfTuple2==1)
10083     {
10084       if(nbOfComp2==nbOfComp)
10085         {
10086           int *ptr=getPointer();
10087           const int *ptrc=other->getConstPointer();
10088           for(int i=0;i<nbOfTuple;i++)
10089             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10090         }
10091       else
10092         throw INTERP_KERNEL::Exception(msg);
10093     }
10094   else
10095     throw INTERP_KERNEL::Exception(msg);
10096   declareAsNew();
10097 }
10098
10099 /*!
10100  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10101  * valid cases.
10102  * 1.  The arrays have same number of tuples and components. Then each value of
10103  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10104  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10105  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10106  *   component. Then
10107  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10108  * 3.  The arrays have same number of components and one array, say _a2_, has one
10109  *   tuple. Then
10110  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10111  *
10112  * Info on components is copied either from the first array (in the first case) or from
10113  * the array with maximal number of elements (getNbOfElems()).
10114  *  \param [in] a1 - an array to subtract from.
10115  *  \param [in] a2 - an array to subtract.
10116  *  \return DataArrayInt * - the new instance of DataArrayInt.
10117  *          The caller is to delete this result array using decrRef() as it is no more
10118  *          needed.
10119  *  \throw If either \a a1 or \a a2 is NULL.
10120  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10121  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10122  *         none of them has number of tuples or components equal to 1.
10123  */
10124 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10125 {
10126   if(!a1 || !a2)
10127     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10128   int nbOfTuple1=a1->getNumberOfTuples();
10129   int nbOfTuple2=a2->getNumberOfTuples();
10130   int nbOfComp1=a1->getNumberOfComponents();
10131   int nbOfComp2=a2->getNumberOfComponents();
10132   if(nbOfTuple2==nbOfTuple1)
10133     {
10134       if(nbOfComp1==nbOfComp2)
10135         {
10136           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10137           ret->alloc(nbOfTuple2,nbOfComp1);
10138           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10139           ret->copyStringInfoFrom(*a1);
10140           return ret.retn();
10141         }
10142       else if(nbOfComp2==1)
10143         {
10144           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10145           ret->alloc(nbOfTuple1,nbOfComp1);
10146           const int *a2Ptr=a2->getConstPointer();
10147           const int *a1Ptr=a1->getConstPointer();
10148           int *res=ret->getPointer();
10149           for(int i=0;i<nbOfTuple1;i++)
10150             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10151           ret->copyStringInfoFrom(*a1);
10152           return ret.retn();
10153         }
10154       else
10155         {
10156           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10157           return 0;
10158         }
10159     }
10160   else if(nbOfTuple2==1)
10161     {
10162       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10163       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10164       ret->alloc(nbOfTuple1,nbOfComp1);
10165       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10166       int *pt=ret->getPointer();
10167       for(int i=0;i<nbOfTuple1;i++)
10168         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10169       ret->copyStringInfoFrom(*a1);
10170       return ret.retn();
10171     }
10172   else
10173     {
10174       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10175       return 0;
10176     }
10177 }
10178
10179 /*!
10180  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10181  * valid cases.
10182  * 1.  The arrays have same number of tuples and components. Then each value of
10183  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10184  *   _a_ [ i, j ] -= _other_ [ i, j ].
10185  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10186  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10187  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10188  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10189  *
10190  *  \param [in] other - an array to subtract from \a this one.
10191  *  \throw If \a other is NULL.
10192  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10193  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10194  *         \a other has number of both tuples and components not equal to 1.
10195  */
10196 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10197 {
10198   if(!other)
10199     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10200   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10201   checkAllocated(); other->checkAllocated();
10202   int nbOfTuple=getNumberOfTuples();
10203   int nbOfTuple2=other->getNumberOfTuples();
10204   int nbOfComp=getNumberOfComponents();
10205   int nbOfComp2=other->getNumberOfComponents();
10206   if(nbOfTuple==nbOfTuple2)
10207     {
10208       if(nbOfComp==nbOfComp2)
10209         {
10210           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10211         }
10212       else if(nbOfComp2==1)
10213         {
10214           int *ptr=getPointer();
10215           const int *ptrc=other->getConstPointer();
10216           for(int i=0;i<nbOfTuple;i++)
10217             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10218         }
10219       else
10220         throw INTERP_KERNEL::Exception(msg);
10221     }
10222   else if(nbOfTuple2==1)
10223     {
10224       int *ptr=getPointer();
10225       const int *ptrc=other->getConstPointer();
10226       for(int i=0;i<nbOfTuple;i++)
10227         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10228     }
10229   else
10230     throw INTERP_KERNEL::Exception(msg);
10231   declareAsNew();
10232 }
10233
10234 /*!
10235  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10236  * valid cases.
10237  * 1.  The arrays have same number of tuples and components. Then each value of
10238  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10239  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10240  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10241  *   component. Then
10242  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10243  * 3.  The arrays have same number of components and one array, say _a2_, has one
10244  *   tuple. Then
10245  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10246  *
10247  * Info on components is copied either from the first array (in the first case) or from
10248  * the array with maximal number of elements (getNbOfElems()).
10249  *  \param [in] a1 - a factor array.
10250  *  \param [in] a2 - another factor array.
10251  *  \return DataArrayInt * - the new instance of DataArrayInt.
10252  *          The caller is to delete this result array using decrRef() as it is no more
10253  *          needed.
10254  *  \throw If either \a a1 or \a a2 is NULL.
10255  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10256  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10257  *         none of them has number of tuples or components equal to 1.
10258  */
10259 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10260 {
10261   if(!a1 || !a2)
10262     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10263   int nbOfTuple=a1->getNumberOfTuples();
10264   int nbOfTuple2=a2->getNumberOfTuples();
10265   int nbOfComp=a1->getNumberOfComponents();
10266   int nbOfComp2=a2->getNumberOfComponents();
10267   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10268   if(nbOfTuple==nbOfTuple2)
10269     {
10270       if(nbOfComp==nbOfComp2)
10271         {
10272           ret=DataArrayInt::New();
10273           ret->alloc(nbOfTuple,nbOfComp);
10274           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10275           ret->copyStringInfoFrom(*a1);
10276         }
10277       else
10278         {
10279           int nbOfCompMin,nbOfCompMax;
10280           const DataArrayInt *aMin, *aMax;
10281           if(nbOfComp>nbOfComp2)
10282             {
10283               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10284               aMin=a2; aMax=a1;
10285             }
10286           else
10287             {
10288               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10289               aMin=a1; aMax=a2;
10290             }
10291           if(nbOfCompMin==1)
10292             {
10293               ret=DataArrayInt::New();
10294               ret->alloc(nbOfTuple,nbOfCompMax);
10295               const int *aMinPtr=aMin->getConstPointer();
10296               const int *aMaxPtr=aMax->getConstPointer();
10297               int *res=ret->getPointer();
10298               for(int i=0;i<nbOfTuple;i++)
10299                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10300               ret->copyStringInfoFrom(*aMax);
10301             }
10302           else
10303             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10304         }
10305     }
10306   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10307     {
10308       if(nbOfComp==nbOfComp2)
10309         {
10310           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10311           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10312           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10313           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10314           ret=DataArrayInt::New();
10315           ret->alloc(nbOfTupleMax,nbOfComp);
10316           int *res=ret->getPointer();
10317           for(int i=0;i<nbOfTupleMax;i++)
10318             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10319           ret->copyStringInfoFrom(*aMax);
10320         }
10321       else
10322         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10323     }
10324   else
10325     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10326   return ret.retn();
10327 }
10328
10329
10330 /*!
10331  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10332  * valid cases.
10333  * 1.  The arrays have same number of tuples and components. Then each value of
10334  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10335  *   _a_ [ i, j ] *= _other_ [ i, j ].
10336  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10337  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10338  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10339  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10340  *
10341  *  \param [in] other - an array to multiply to \a this one.
10342  *  \throw If \a other is NULL.
10343  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10344  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10345  *         \a other has number of both tuples and components not equal to 1.
10346  */
10347 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10348 {
10349   if(!other)
10350     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10351   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10352   checkAllocated(); other->checkAllocated();
10353   int nbOfTuple=getNumberOfTuples();
10354   int nbOfTuple2=other->getNumberOfTuples();
10355   int nbOfComp=getNumberOfComponents();
10356   int nbOfComp2=other->getNumberOfComponents();
10357   if(nbOfTuple==nbOfTuple2)
10358     {
10359       if(nbOfComp==nbOfComp2)
10360         {
10361           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10362         }
10363       else if(nbOfComp2==1)
10364         {
10365           int *ptr=getPointer();
10366           const int *ptrc=other->getConstPointer();
10367           for(int i=0;i<nbOfTuple;i++)
10368             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10369         }
10370       else
10371         throw INTERP_KERNEL::Exception(msg);
10372     }
10373   else if(nbOfTuple2==1)
10374     {
10375       if(nbOfComp2==nbOfComp)
10376         {
10377           int *ptr=getPointer();
10378           const int *ptrc=other->getConstPointer();
10379           for(int i=0;i<nbOfTuple;i++)
10380             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10381         }
10382       else
10383         throw INTERP_KERNEL::Exception(msg);
10384     }
10385   else
10386     throw INTERP_KERNEL::Exception(msg);
10387   declareAsNew();
10388 }
10389
10390
10391 /*!
10392  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10393  * valid cases.
10394  * 1.  The arrays have same number of tuples and components. Then each value of
10395  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10396  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10397  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10398  *   component. Then
10399  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10400  * 3.  The arrays have same number of components and one array, say _a2_, has one
10401  *   tuple. Then
10402  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10403  *
10404  * Info on components is copied either from the first array (in the first case) or from
10405  * the array with maximal number of elements (getNbOfElems()).
10406  *  \warning No check of division by zero is performed!
10407  *  \param [in] a1 - a numerator array.
10408  *  \param [in] a2 - a denominator array.
10409  *  \return DataArrayInt * - the new instance of DataArrayInt.
10410  *          The caller is to delete this result array using decrRef() as it is no more
10411  *          needed.
10412  *  \throw If either \a a1 or \a a2 is NULL.
10413  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10414  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10415  *         none of them has number of tuples or components equal to 1.
10416  */
10417 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10418 {
10419   if(!a1 || !a2)
10420     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10421   int nbOfTuple1=a1->getNumberOfTuples();
10422   int nbOfTuple2=a2->getNumberOfTuples();
10423   int nbOfComp1=a1->getNumberOfComponents();
10424   int nbOfComp2=a2->getNumberOfComponents();
10425   if(nbOfTuple2==nbOfTuple1)
10426     {
10427       if(nbOfComp1==nbOfComp2)
10428         {
10429           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10430           ret->alloc(nbOfTuple2,nbOfComp1);
10431           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10432           ret->copyStringInfoFrom(*a1);
10433           return ret.retn();
10434         }
10435       else if(nbOfComp2==1)
10436         {
10437           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10438           ret->alloc(nbOfTuple1,nbOfComp1);
10439           const int *a2Ptr=a2->getConstPointer();
10440           const int *a1Ptr=a1->getConstPointer();
10441           int *res=ret->getPointer();
10442           for(int i=0;i<nbOfTuple1;i++)
10443             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10444           ret->copyStringInfoFrom(*a1);
10445           return ret.retn();
10446         }
10447       else
10448         {
10449           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10450           return 0;
10451         }
10452     }
10453   else if(nbOfTuple2==1)
10454     {
10455       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10456       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10457       ret->alloc(nbOfTuple1,nbOfComp1);
10458       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10459       int *pt=ret->getPointer();
10460       for(int i=0;i<nbOfTuple1;i++)
10461         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10462       ret->copyStringInfoFrom(*a1);
10463       return ret.retn();
10464     }
10465   else
10466     {
10467       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10468       return 0;
10469     }
10470 }
10471
10472 /*!
10473  * Divide values of \a this array by values of another DataArrayInt. There are 3
10474  * valid cases.
10475  * 1.  The arrays have same number of tuples and components. Then each value of
10476  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10477  *   _a_ [ i, j ] /= _other_ [ i, j ].
10478  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10479  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10480  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10481  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10482  *
10483  *  \warning No check of division by zero is performed!
10484  *  \param [in] other - an array to divide \a this one by.
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::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10491 {
10492   if(!other)
10493     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10494   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
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::divides<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::divides<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::divides<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 /*!
10535  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10536  * valid cases.
10537  * 1.  The arrays have same number of tuples and components. Then each value of
10538  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10539  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10540  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10541  *   component. Then
10542  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10543  * 3.  The arrays have same number of components and one array, say _a2_, has one
10544  *   tuple. Then
10545  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10546  *
10547  * Info on components is copied either from the first array (in the first case) or from
10548  * the array with maximal number of elements (getNbOfElems()).
10549  *  \warning No check of division by zero is performed!
10550  *  \param [in] a1 - a dividend array.
10551  *  \param [in] a2 - a divisor array.
10552  *  \return DataArrayInt * - the new instance of DataArrayInt.
10553  *          The caller is to delete this result array using decrRef() as it is no more
10554  *          needed.
10555  *  \throw If either \a a1 or \a a2 is NULL.
10556  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10557  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10558  *         none of them has number of tuples or components equal to 1.
10559  */
10560 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10561 {
10562     if(!a1 || !a2)
10563     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10564   int nbOfTuple1=a1->getNumberOfTuples();
10565   int nbOfTuple2=a2->getNumberOfTuples();
10566   int nbOfComp1=a1->getNumberOfComponents();
10567   int nbOfComp2=a2->getNumberOfComponents();
10568   if(nbOfTuple2==nbOfTuple1)
10569     {
10570       if(nbOfComp1==nbOfComp2)
10571         {
10572           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10573           ret->alloc(nbOfTuple2,nbOfComp1);
10574           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10575           ret->copyStringInfoFrom(*a1);
10576           return ret.retn();
10577         }
10578       else if(nbOfComp2==1)
10579         {
10580           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10581           ret->alloc(nbOfTuple1,nbOfComp1);
10582           const int *a2Ptr=a2->getConstPointer();
10583           const int *a1Ptr=a1->getConstPointer();
10584           int *res=ret->getPointer();
10585           for(int i=0;i<nbOfTuple1;i++)
10586             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10587           ret->copyStringInfoFrom(*a1);
10588           return ret.retn();
10589         }
10590       else
10591         {
10592           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10593           return 0;
10594         }
10595     }
10596   else if(nbOfTuple2==1)
10597     {
10598       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10599       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10600       ret->alloc(nbOfTuple1,nbOfComp1);
10601       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10602       int *pt=ret->getPointer();
10603       for(int i=0;i<nbOfTuple1;i++)
10604         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10605       ret->copyStringInfoFrom(*a1);
10606       return ret.retn();
10607     }
10608   else
10609     {
10610       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10611       return 0;
10612     }
10613 }
10614
10615 /*!
10616  * Modify \a this array so that each value becomes a modulus of division of this value by
10617  * a value of another DataArrayInt. There are 3 valid cases.
10618  * 1.  The arrays have same number of tuples and components. Then each value of
10619  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10620  *   _a_ [ i, j ] %= _other_ [ i, j ].
10621  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10622  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10623  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10624  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10625  *
10626  *  \warning No check of division by zero is performed!
10627  *  \param [in] other - a divisor array.
10628  *  \throw If \a other is NULL.
10629  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10630  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10631  *         \a other has number of both tuples and components not equal to 1.
10632  */
10633 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10634 {
10635   if(!other)
10636     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10637   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10638   checkAllocated(); other->checkAllocated();
10639   int nbOfTuple=getNumberOfTuples();
10640   int nbOfTuple2=other->getNumberOfTuples();
10641   int nbOfComp=getNumberOfComponents();
10642   int nbOfComp2=other->getNumberOfComponents();
10643   if(nbOfTuple==nbOfTuple2)
10644     {
10645       if(nbOfComp==nbOfComp2)
10646         {
10647           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10648         }
10649       else if(nbOfComp2==1)
10650         {
10651           if(nbOfComp2==nbOfComp)
10652             {
10653               int *ptr=getPointer();
10654               const int *ptrc=other->getConstPointer();
10655               for(int i=0;i<nbOfTuple;i++)
10656                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10657             }
10658           else
10659             throw INTERP_KERNEL::Exception(msg);
10660         }
10661       else
10662         throw INTERP_KERNEL::Exception(msg);
10663     }
10664   else if(nbOfTuple2==1)
10665     {
10666       int *ptr=getPointer();
10667       const int *ptrc=other->getConstPointer();
10668       for(int i=0;i<nbOfTuple;i++)
10669         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10670     }
10671   else
10672     throw INTERP_KERNEL::Exception(msg);
10673   declareAsNew();
10674 }
10675
10676 /*!
10677  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10678  * valid cases.
10679  *
10680  *  \param [in] a1 - an array to pow up.
10681  *  \param [in] a2 - another array to sum up.
10682  *  \return DataArrayInt * - the new instance of DataArrayInt.
10683  *          The caller is to delete this result array using decrRef() as it is no more
10684  *          needed.
10685  *  \throw If either \a a1 or \a a2 is NULL.
10686  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10687  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10688  *  \throw If there is a negative value in \a a2.
10689  */
10690 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10691 {
10692   if(!a1 || !a2)
10693     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10694   int nbOfTuple=a1->getNumberOfTuples();
10695   int nbOfTuple2=a2->getNumberOfTuples();
10696   int nbOfComp=a1->getNumberOfComponents();
10697   int nbOfComp2=a2->getNumberOfComponents();
10698   if(nbOfTuple!=nbOfTuple2)
10699     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10700   if(nbOfComp!=1 || nbOfComp2!=1)
10701     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10702   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10703   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10704   int *ptr=ret->getPointer();
10705   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10706     {
10707       if(*ptr2>=0)
10708         {
10709           int tmp=1;
10710           for(int j=0;j<*ptr2;j++)
10711             tmp*=*ptr1;
10712           *ptr=tmp;
10713         }
10714       else
10715         {
10716           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10717           throw INTERP_KERNEL::Exception(oss.str().c_str());
10718         }
10719     }
10720   return ret.retn();
10721 }
10722
10723 /*!
10724  * Apply pow on values of another DataArrayInt to values of \a this one.
10725  *
10726  *  \param [in] other - an array to pow to \a this one.
10727  *  \throw If \a other is NULL.
10728  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10729  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10730  *  \throw If there is a negative value in \a other.
10731  */
10732 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10733 {
10734   if(!other)
10735     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10736   int nbOfTuple=getNumberOfTuples();
10737   int nbOfTuple2=other->getNumberOfTuples();
10738   int nbOfComp=getNumberOfComponents();
10739   int nbOfComp2=other->getNumberOfComponents();
10740   if(nbOfTuple!=nbOfTuple2)
10741     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10742   if(nbOfComp!=1 || nbOfComp2!=1)
10743     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10744   int *ptr=getPointer();
10745   const int *ptrc=other->begin();
10746   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10747     {
10748       if(*ptrc>=0)
10749         {
10750           int tmp=1;
10751           for(int j=0;j<*ptrc;j++)
10752             tmp*=*ptr;
10753           *ptr=tmp;
10754         }
10755       else
10756         {
10757           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10758           throw INTERP_KERNEL::Exception(oss.str().c_str());
10759         }
10760     }
10761   declareAsNew();
10762 }
10763
10764 /*!
10765  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10766  * This map, if applied to \a start array, would make it sorted. For example, if
10767  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10768  * [5,6,0,3,2,7,1,4].
10769  *  \param [in] start - pointer to the first element of the array for which the
10770  *         permutation map is computed.
10771  *  \param [in] end - pointer specifying the end of the array \a start, so that
10772  *         the last value of \a start is \a end[ -1 ].
10773  *  \return int * - the result permutation array that the caller is to delete as it is no
10774  *         more needed.
10775  *  \throw If there are equal values in the input array.
10776  */
10777 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10778 {
10779   std::size_t sz=std::distance(start,end);
10780   int *ret=(int *)malloc(sz*sizeof(int));
10781   int *work=new int[sz];
10782   std::copy(start,end,work);
10783   std::sort(work,work+sz);
10784   if(std::unique(work,work+sz)!=work+sz)
10785     {
10786       delete [] work;
10787       free(ret);
10788       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10789     }
10790   std::map<int,int> m;
10791   for(int *workPt=work;workPt!=work+sz;workPt++)
10792     m[*workPt]=(int)std::distance(work,workPt);
10793   int *iter2=ret;
10794   for(const int *iter=start;iter!=end;iter++,iter2++)
10795     *iter2=m[*iter];
10796   delete [] work;
10797   return ret;
10798 }
10799
10800 /*!
10801  * Returns a new DataArrayInt containing an arithmetic progression
10802  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10803  * function.
10804  *  \param [in] begin - the start value of the result sequence.
10805  *  \param [in] end - limiting value, so that every value of the result array is less than
10806  *              \a end.
10807  *  \param [in] step - specifies the increment or decrement.
10808  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10809  *          array using decrRef() as it is no more needed.
10810  *  \throw If \a step == 0.
10811  *  \throw If \a end < \a begin && \a step > 0.
10812  *  \throw If \a end > \a begin && \a step < 0.
10813  */
10814 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10815 {
10816   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10817   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10818   ret->alloc(nbOfTuples,1);
10819   int *ptr=ret->getPointer();
10820   if(step>0)
10821     {
10822       for(int i=begin;i<end;i+=step,ptr++)
10823         *ptr=i;
10824     }
10825   else
10826     {
10827       for(int i=begin;i>end;i+=step,ptr++)
10828         *ptr=i;
10829     }
10830   return ret.retn();
10831 }
10832
10833 /*!
10834  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10835  * Server side.
10836  */
10837 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10838 {
10839   tinyInfo.resize(2);
10840   if(isAllocated())
10841     {
10842       tinyInfo[0]=getNumberOfTuples();
10843       tinyInfo[1]=getNumberOfComponents();
10844     }
10845   else
10846     {
10847       tinyInfo[0]=-1;
10848       tinyInfo[1]=-1;
10849     }
10850 }
10851
10852 /*!
10853  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10854  * Server side.
10855  */
10856 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10857 {
10858   if(isAllocated())
10859     {
10860       int nbOfCompo=getNumberOfComponents();
10861       tinyInfo.resize(nbOfCompo+1);
10862       tinyInfo[0]=getName();
10863       for(int i=0;i<nbOfCompo;i++)
10864         tinyInfo[i+1]=getInfoOnComponent(i);
10865     }
10866   else
10867     {
10868       tinyInfo.resize(1);
10869       tinyInfo[0]=getName();
10870     }
10871 }
10872
10873 /*!
10874  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10875  * This method returns if a feeding is needed.
10876  */
10877 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10878 {
10879   int nbOfTuple=tinyInfoI[0];
10880   int nbOfComp=tinyInfoI[1];
10881   if(nbOfTuple!=-1 || nbOfComp!=-1)
10882     {
10883       alloc(nbOfTuple,nbOfComp);
10884       return true;
10885     }
10886   return false;
10887 }
10888
10889 /*!
10890  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10891  * This method returns if a feeding is needed.
10892  */
10893 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10894 {
10895   setName(tinyInfoS[0].c_str());
10896   if(isAllocated())
10897     {
10898       int nbOfCompo=tinyInfoI[1];
10899       for(int i=0;i<nbOfCompo;i++)
10900         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10901     }
10902 }
10903
10904 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10905 {
10906   if(_da)
10907     {
10908       _da->incrRef();
10909       if(_da->isAllocated())
10910         {
10911           _nb_comp=da->getNumberOfComponents();
10912           _nb_tuple=da->getNumberOfTuples();
10913           _pt=da->getPointer();
10914         }
10915     }
10916 }
10917
10918 DataArrayIntIterator::~DataArrayIntIterator()
10919 {
10920   if(_da)
10921     _da->decrRef();
10922 }
10923
10924 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10925 {
10926   if(_tuple_id<_nb_tuple)
10927     {
10928       _tuple_id++;
10929       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10930       _pt+=_nb_comp;
10931       return ret;
10932     }
10933   else
10934     return 0;
10935 }
10936
10937 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10938 {
10939 }
10940
10941 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10942 {
10943   std::ostringstream oss; oss << "(";
10944   for(int i=0;i<_nb_of_compo-1;i++)
10945     oss << _pt[i] << ", ";
10946   oss << _pt[_nb_of_compo-1] << ")";
10947   return oss.str();
10948 }
10949
10950 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10951 {
10952   if(_nb_of_compo==1)
10953     return *_pt;
10954   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10955 }
10956
10957 /*!
10958  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10959  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10960  * 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
10961  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10962  */
10963 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10964 {
10965   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10966     {
10967       DataArrayInt *ret=DataArrayInt::New();
10968       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10969       return ret;
10970     }
10971   else
10972     {
10973       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10974       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10975       throw INTERP_KERNEL::Exception(oss.str().c_str());
10976     }
10977 }