Salome HOME
getHeapMemorySize rearch
[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 "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildren() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const char *name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
427  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
428  * the number of component in the result array is same as that of each of given arrays.
429  * Info on components is copied from the first of the given arrays. Number of components
430  * in the given arrays must be  the same.
431  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
432  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
433  *          The caller is to delete this result array using decrRef() as it is no more
434  *          needed.
435  *  \throw If all arrays within \a arrs are NULL.
436  *  \throw If all not null arrays in \a arrs have not the same type.
437  *  \throw If getNumberOfComponents() of arrays within \a arrs.
438  */
439 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs) throw(INTERP_KERNEL::Exception)
440 {
441   std::vector<const DataArray *> arr2;
442   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
443     if(*it)
444       arr2.push_back(*it);
445   if(arr2.empty())
446     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
447   std::vector<const DataArrayDouble *> arrd;
448   std::vector<const DataArrayInt *> arri;
449   std::vector<const DataArrayChar *> arrc;
450   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
451     {
452       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
453       if(a)
454         { arrd.push_back(a); continue; }
455       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
456       if(b)
457         { arri.push_back(b); continue; }
458       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
459       if(c)
460         { arrc.push_back(c); continue; }
461       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
462     }
463   if(arr2.size()==arrd.size())
464     return DataArrayDouble::Aggregate(arrd);
465   if(arr2.size()==arri.size())
466     return DataArrayInt::Aggregate(arri);
467   if(arr2.size()==arrc.size())
468     return DataArrayChar::Aggregate(arrc);
469   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
470 }
471
472 /*!
473  * Sets information on a component specified by an index.
474  * To know more on format of this information
475  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
476  *  \warning Don't pass NULL as \a info!
477  *  \param [in] i - the index (zero based) of the component of interest.
478  *  \param [in] info - the string containing the information.
479  *  \throw If \a i is not a valid component index.
480  */
481 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
482 {
483   if(i<(int)_info_on_compo.size() && i>=0)
484     _info_on_compo[i]=info;
485   else
486     {
487       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();
488       throw INTERP_KERNEL::Exception(oss.str().c_str());
489     }
490 }
491
492 /*!
493  * Sets information on all components. This method can change number of components
494  * at certain conditions; if the conditions are not respected, an exception is thrown.
495  * The number of components can be changed in \a this only if \a this is not allocated.
496  * The condition of number of components must not be changed.
497  *
498  * To know more on format of the component information see
499  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
500  *  \param [in] info - a vector of component infos.
501  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
502  */
503 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
504 {
505   if(getNumberOfComponents()!=(int)info.size())
506     {
507       if(!isAllocated())
508         _info_on_compo=info;
509       else
510         {
511           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 !";
512           throw INTERP_KERNEL::Exception(oss.str().c_str());
513         }
514     }
515   else
516     _info_on_compo=info;
517 }
518
519 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
520 {
521   if(getNumberOfTuples()!=nbOfTuples)
522     {
523       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
524       throw INTERP_KERNEL::Exception(oss.str().c_str());
525     }
526 }
527
528 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
529 {
530   if(getNumberOfComponents()!=nbOfCompo)
531     {
532       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
533       throw INTERP_KERNEL::Exception(oss.str().c_str());
534     }
535 }
536
537 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
538 {
539   if(getNbOfElems()!=nbOfElems)
540     {
541       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
542       throw INTERP_KERNEL::Exception(oss.str().c_str());
543     }
544 }
545
546 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
547 {
548    if(getNumberOfTuples()!=other.getNumberOfTuples())
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553   if(getNumberOfComponents()!=other.getNumberOfComponents())
554     {
555       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
556       throw INTERP_KERNEL::Exception(oss.str().c_str());
557     }
558 }
559
560 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
561 {
562   checkNbOfTuples(nbOfTuples,msg);
563   checkNbOfComps(nbOfCompo,msg);
564 }
565
566 /*!
567  * Simply this method checks that \b value is in [0,\b ref).
568  */
569 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
570 {
571   if(value<0 || value>=ref)
572     {
573       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
574       throw INTERP_KERNEL::Exception(oss.str().c_str());
575     }
576 }
577
578 /*!
579  * This method checks that [\b start, \b end) is compliant with ref length \b value.
580  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
581  */
582 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
583 {
584   if(start<0 || start>=value)
585     {
586       if(value!=start || end!=start)
587         {
588           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
589           throw INTERP_KERNEL::Exception(oss.str().c_str());
590         }
591     }
592   if(end<0 || end>value)
593     {
594       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
595       throw INTERP_KERNEL::Exception(oss.str().c_str());
596     }
597 }
598
599 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
600 {
601   if(value<0 || value>ref)
602     {
603       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
604       throw INTERP_KERNEL::Exception(oss.str().c_str());
605     }
606 }
607
608 /*!
609  * 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, 
610  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
611  *
612  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
613  *
614  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
615  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
616  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
617  * \param [in] sliceId - the slice id considered
618  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
619  * \param [out] startSlice - the start of the slice considered
620  * \param [out] stopSlice - the stop of the slice consided
621  * 
622  * \throw If \a step == 0
623  * \throw If \a nbOfSlices not > 0
624  * \throw If \a sliceId not in [0,nbOfSlices)
625  */
626 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
627 {
628   if(nbOfSlices<=0)
629     {
630       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633   if(sliceId<0 || sliceId>=nbOfSlices)
634     {
635       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
636       throw INTERP_KERNEL::Exception(oss.str().c_str());
637     }
638   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
639   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
640   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
641   if(sliceId<nbOfSlices-1)
642     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
643   else
644     stopSlice=stop;
645 }
646
647 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
648 {
649   if(end<begin)
650     {
651       std::ostringstream oss; oss << msg << " : end before begin !";
652       throw INTERP_KERNEL::Exception(oss.str().c_str());
653     }
654   if(end==begin)
655     return 0;
656   if(step<=0)
657     {
658       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
659       throw INTERP_KERNEL::Exception(oss.str().c_str());
660     }
661   return (end-1-begin)/step+1;
662 }
663
664 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
665 {
666   if(step==0)
667     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
668   if(end<begin && step>0)
669     {
670       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   if(begin<end && step<0)
674     {
675       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
676       throw INTERP_KERNEL::Exception(oss.str().c_str());
677     }
678   if(begin!=end)
679     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
680   else
681     return 0;
682 }
683
684 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
685 {
686   if(step!=0)
687     {
688       if(step>0)
689         {
690           if(begin<=value && value<end)
691             {
692               if((value-begin)%step==0)
693                 return (value-begin)/step;
694               else
695                 return -1;
696             }
697           else
698             return -1;
699         }
700       else
701         {
702           if(begin>=value && value>end)
703             {
704               if((begin-value)%(-step)==0)
705                 return (begin-value)/(-step);
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712     }
713   else
714     return -1;
715 }
716
717 /*!
718  * Returns a new instance of DataArrayDouble. The caller is to delete this array
719  * using decrRef() as it is no more needed. 
720  */
721 DataArrayDouble *DataArrayDouble::New()
722 {
723   return new DataArrayDouble;
724 }
725
726 /*!
727  * Checks if raw data is allocated. Read more on the raw data
728  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
729  *  \return bool - \a true if the raw data is allocated, \a false else.
730  */
731 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
732 {
733   return getConstPointer()!=0;
734 }
735
736 /*!
737  * Checks if raw data is allocated and throws an exception if it is not the case.
738  *  \throw If the raw data is not allocated.
739  */
740 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
741 {
742   if(!isAllocated())
743     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
744 }
745
746 /*!
747  * This method desallocated \a this without modification of informations relative to the components.
748  * After call of this method, DataArrayDouble::isAllocated will return false.
749  * If \a this is already not allocated, \a this is let unchanged.
750  */
751 void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
752 {
753   _mem.destroy();
754 }
755
756 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
757 {
758   std::size_t sz(_mem.getNbOfElemAllocated());
759   sz*=sizeof(double);
760   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
761 }
762
763 /*!
764  * Returns the only one value in \a this, if and only if number of elements
765  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
766  *  \return double - the sole value stored in \a this array.
767  *  \throw If at least one of conditions stated above is not fulfilled.
768  */
769 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
770 {
771   if(isAllocated())
772     {
773       if(getNbOfElems()==1)
774         {
775           return *getConstPointer();
776         }
777       else
778         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
779     }
780   else
781     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
782 }
783
784 /*!
785  * Checks the number of tuples.
786  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
787  *  \throw If \a this is not allocated.
788  */
789 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
790 {
791   checkAllocated();
792   return getNumberOfTuples()==0;
793 }
794
795 /*!
796  * Returns a full copy of \a this. For more info on copying data arrays see
797  * \ref MEDCouplingArrayBasicsCopyDeep.
798  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
799  *          delete this array using decrRef() as it is no more needed. 
800  */
801 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
802 {
803   return new DataArrayDouble(*this);
804 }
805
806 /*!
807  * Returns either a \a deep or \a shallow copy of this array. For more info see
808  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
809  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
810  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
811  *          == \a true) or \a this instance (if \a dCpy == \a false).
812  */
813 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
814 {
815   if(dCpy)
816     return deepCpy();
817   else
818     {
819       incrRef();
820       return const_cast<DataArrayDouble *>(this);
821     }
822 }
823
824 /*!
825  * Copies all the data from another DataArrayDouble. For more info see
826  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
827  *  \param [in] other - another instance of DataArrayDouble to copy data from.
828  *  \throw If the \a other is not allocated.
829  */
830 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
831 {
832   other.checkAllocated();
833   int nbOfTuples=other.getNumberOfTuples();
834   int nbOfComp=other.getNumberOfComponents();
835   allocIfNecessary(nbOfTuples,nbOfComp);
836   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
837   double *pt=getPointer();
838   const double *ptI=other.getConstPointer();
839   for(std::size_t i=0;i<nbOfElems;i++)
840     pt[i]=ptI[i];
841   copyStringInfoFrom(other);
842 }
843
844 /*!
845  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
846  * 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.
847  * If \a this has not already been allocated, number of components is set to one.
848  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
849  * 
850  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
851  */
852 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
853 {
854   int nbCompo=getNumberOfComponents();
855   if(nbCompo==1)
856     {
857       _mem.reserve(nbOfElems);
858     }
859   else if(nbCompo==0)
860     {
861       _mem.reserve(nbOfElems);
862       _info_on_compo.resize(1);
863     }
864   else
865     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
866 }
867
868 /*!
869  * 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
870  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
871  *
872  * \param [in] val the value to be added in \a this
873  * \throw If \a this has already been allocated with number of components different from one.
874  * \sa DataArrayDouble::pushBackValsSilent
875  */
876 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
877 {
878   int nbCompo=getNumberOfComponents();
879   if(nbCompo==1)
880     _mem.pushBack(val);
881   else if(nbCompo==0)
882     {
883       _info_on_compo.resize(1);
884       _mem.pushBack(val);
885     }
886   else
887     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
888 }
889
890 /*!
891  * 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
892  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
893  *
894  *  \param [in] valsBg - an array of values to push at the end of \this.
895  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
896  *              the last value of \a valsBg is \a valsEnd[ -1 ].
897  * \throw If \a this has already been allocated with number of components different from one.
898  * \sa DataArrayDouble::pushBackSilent
899  */
900 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
901 {
902   int nbCompo=getNumberOfComponents();
903   if(nbCompo==1)
904     _mem.insertAtTheEnd(valsBg,valsEnd);
905   else if(nbCompo==0)
906     {
907       _info_on_compo.resize(1);
908       _mem.insertAtTheEnd(valsBg,valsEnd);
909     }
910   else
911     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
912 }
913
914 /*!
915  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
916  * \throw If \a this is already empty.
917  * \throw If \a this has number of components different from one.
918  */
919 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
920 {
921   if(getNumberOfComponents()==1)
922     return _mem.popBack();
923   else
924     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
925 }
926
927 /*!
928  * 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.
929  *
930  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
931  */
932 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
933 {
934   _mem.pack();
935 }
936
937 /*!
938  * Allocates the raw data in memory. If exactly same memory as needed already
939  * allocated, it is not re-allocated.
940  *  \param [in] nbOfTuple - number of tuples of data to allocate.
941  *  \param [in] nbOfCompo - number of components of data to allocate.
942  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
943  */
944 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
945 {
946   if(isAllocated())
947     {
948       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
949         alloc(nbOfTuple,nbOfCompo);
950     }
951   else
952     alloc(nbOfTuple,nbOfCompo);
953 }
954
955 /*!
956  * Allocates the raw data in memory. If the memory was already allocated, then it is
957  * freed and re-allocated. See an example of this method use
958  * \ref MEDCouplingArraySteps1WC "here".
959  *  \param [in] nbOfTuple - number of tuples of data to allocate.
960  *  \param [in] nbOfCompo - number of components of data to allocate.
961  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
962  */
963 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
964 {
965   if(nbOfTuple<0 || nbOfCompo<0)
966     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
967   _info_on_compo.resize(nbOfCompo);
968   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
969   declareAsNew();
970 }
971
972 /*!
973  * Assign zero to all values in \a this array. To know more on filling arrays see
974  * \ref MEDCouplingArrayFill.
975  * \throw If \a this is not allocated.
976  */
977 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
978 {
979   checkAllocated();
980   _mem.fillWithValue(0.);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign \a val to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  *  \param [in] val - the value to fill with.
988  *  \throw If \a this is not allocated.
989  */
990 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
991 {
992   checkAllocated();
993   _mem.fillWithValue(val);
994   declareAsNew();
995 }
996
997 /*!
998  * Set all values in \a this array so that the i-th element equals to \a init + i
999  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1000  *  \param [in] init - value to assign to the first element of array.
1001  *  \throw If \a this->getNumberOfComponents() != 1
1002  *  \throw If \a this is not allocated.
1003  */
1004 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
1005 {
1006   checkAllocated();
1007   if(getNumberOfComponents()!=1)
1008     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1009   double *ptr=getPointer();
1010   int ntuples=getNumberOfTuples();
1011   for(int i=0;i<ntuples;i++)
1012     ptr[i]=init+double(i);
1013   declareAsNew();
1014 }
1015
1016 /*!
1017  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1018  *  \param [in] val - value to check equality of array values to.
1019  *  \param [in] eps - precision to check the equality.
1020  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1021  *                 \a false else.
1022  *  \throw If \a this->getNumberOfComponents() != 1
1023  *  \throw If \a this is not allocated.
1024  */
1025 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
1026 {
1027   checkAllocated();
1028   if(getNumberOfComponents()!=1)
1029     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1030   int nbOfTuples=getNumberOfTuples();
1031   const double *w=getConstPointer();
1032   const double *end2=w+nbOfTuples;
1033   const double vmin=val-eps;
1034   const double vmax=val+eps;
1035   for(;w!=end2;w++)
1036     if(*w<vmin || *w>vmax)
1037       return false;
1038   return true;
1039 }
1040
1041 /*!
1042  * Sorts values of the array.
1043  *  \param [in] asc - \a true means ascending order, \a false, descending.
1044  *  \throw If \a this is not allocated.
1045  *  \throw If \a this->getNumberOfComponents() != 1.
1046  */
1047 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
1048 {
1049   checkAllocated();
1050   if(getNumberOfComponents()!=1)
1051     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1052   _mem.sort(asc);
1053   declareAsNew();
1054 }
1055
1056 /*!
1057  * Reverse the array values.
1058  *  \throw If \a this->getNumberOfComponents() < 1.
1059  *  \throw If \a this is not allocated.
1060  */
1061 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
1062 {
1063   checkAllocated();
1064   _mem.reverse(getNumberOfComponents());
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1070  * with at least absolute difference value of |\a eps| at each step.
1071  * If not an exception is thrown.
1072  *  \param [in] increasing - if \a true, the array values should be increasing.
1073  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1074  *                    the values are considered different.
1075  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1076  *         increasing arg.
1077  *  \throw If \a this->getNumberOfComponents() != 1.
1078  *  \throw If \a this is not allocated.
1079  */
1080 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1081 {
1082   if(!isMonotonic(increasing,eps))
1083     {
1084       if (increasing)
1085         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1086       else
1087         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1088     }
1089 }
1090
1091 /*!
1092  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1093  * with at least absolute difference value of |\a eps| at each step.
1094  *  \param [in] increasing - if \a true, array values should be increasing.
1095  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1096  *                    the values are considered different.
1097  *  \return bool - \a true if values change in accordance with \a increasing arg.
1098  *  \throw If \a this->getNumberOfComponents() != 1.
1099  *  \throw If \a this is not allocated.
1100  */
1101 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1102 {
1103   checkAllocated();
1104   if(getNumberOfComponents()!=1)
1105     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1106   int nbOfElements=getNumberOfTuples();
1107   const double *ptr=getConstPointer();
1108   if(nbOfElements==0)
1109     return true;
1110   double ref=ptr[0];
1111   double absEps=fabs(eps);
1112   if(increasing)
1113     {
1114       for(int i=1;i<nbOfElements;i++)
1115         {
1116           if(ptr[i]<(ref+absEps))
1117             return false;
1118           ref=ptr[i];
1119         }
1120       return true;
1121     }
1122   else
1123     {
1124       for(int i=1;i<nbOfElements;i++)
1125         {
1126           if(ptr[i]>(ref-absEps))
1127             return false;
1128           ref=ptr[i];
1129         }
1130       return true;
1131     }
1132 }
1133
1134 /*!
1135  * Returns a textual and human readable representation of \a this instance of
1136  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1137  *  \return std::string - text describing \a this DataArrayDouble.
1138  */
1139 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1140 {
1141   std::ostringstream ret;
1142   reprStream(ret);
1143   return ret.str();
1144 }
1145
1146 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1147 {
1148   std::ostringstream ret;
1149   reprZipStream(ret);
1150   return ret.str();
1151 }
1152
1153 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile, DataArrayByte *byteArr) const throw(INTERP_KERNEL::Exception)
1154 {
1155   static const char SPACE[4]={' ',' ',' ',' '};
1156   checkAllocated();
1157   std::string idt(indent,' ');
1158   ofs.precision(17);
1159   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1160   if(byteArr)
1161     {
1162       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1163       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1164       std::copy(begin(),end(),(float *)tmp);
1165       const char *data(reinterpret_cast<const char *>((float *)tmp));
1166       std::size_t sz(getNbOfElems()*sizeof(float));
1167       byteArr->insertAtTheEnd(data,data+sz);
1168       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1169     }
1170   else
1171     {
1172       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1173       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1174     }
1175   ofs << std::endl << idt << "</DataArray>\n";
1176 }
1177
1178 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1179 {
1180   stream << "Name of double array : \"" << _name << "\"\n";
1181   reprWithoutNameStream(stream);
1182 }
1183
1184 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1185 {
1186   stream << "Name of double array : \"" << _name << "\"\n";
1187   reprZipWithoutNameStream(stream);
1188 }
1189
1190 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1191 {
1192   DataArray::reprWithoutNameStream(stream);
1193   stream.precision(17);
1194   _mem.repr(getNumberOfComponents(),stream);
1195 }
1196
1197 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1198 {
1199   DataArray::reprWithoutNameStream(stream);
1200   stream.precision(17);
1201   _mem.reprZip(getNumberOfComponents(),stream);
1202 }
1203
1204 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1205 {
1206   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1207   const double *data=getConstPointer();
1208   stream.precision(17);
1209   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1210   if(nbTuples*nbComp>=1)
1211     {
1212       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1213       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1214       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1215       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1216     }
1217   else
1218     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1219   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1220 }
1221
1222 /*!
1223  * Method that gives a quick overvien of \a this for python.
1224  */
1225 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1226 {
1227   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1228   stream << "DataArrayDouble C++ instance at " << this << ". ";
1229   if(isAllocated())
1230     {
1231       int nbOfCompo=(int)_info_on_compo.size();
1232       if(nbOfCompo>=1)
1233         {
1234           int nbOfTuples=getNumberOfTuples();
1235           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1236           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1237         }
1238       else
1239         stream << "Number of components : 0.";
1240     }
1241   else
1242     stream << "*** No data allocated ****";
1243 }
1244
1245 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1246 {
1247   const double *data=begin();
1248   int nbOfTuples=getNumberOfTuples();
1249   int nbOfCompo=(int)_info_on_compo.size();
1250   std::ostringstream oss2; oss2 << "[";
1251   oss2.precision(17);
1252   std::string oss2Str(oss2.str());
1253   bool isFinished=true;
1254   for(int i=0;i<nbOfTuples && isFinished;i++)
1255     {
1256       if(nbOfCompo>1)
1257         {
1258           oss2 << "(";
1259           for(int j=0;j<nbOfCompo;j++,data++)
1260             {
1261               oss2 << *data;
1262               if(j!=nbOfCompo-1) oss2 << ", ";
1263             }
1264           oss2 << ")";
1265         }
1266       else
1267         oss2 << *data++;
1268       if(i!=nbOfTuples-1) oss2 << ", ";
1269       std::string oss3Str(oss2.str());
1270       if(oss3Str.length()<maxNbOfByteInRepr)
1271         oss2Str=oss3Str;
1272       else
1273         isFinished=false;
1274     }
1275   stream << oss2Str;
1276   if(!isFinished)
1277     stream << "... ";
1278   stream << "]";
1279 }
1280
1281 /*!
1282  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1283  * mismatch is given.
1284  * 
1285  * \param [in] other the instance to be compared with \a this
1286  * \param [in] prec the precision to compare numeric data of the arrays.
1287  * \param [out] reason In case of inequality returns the reason.
1288  * \sa DataArrayDouble::isEqual
1289  */
1290 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1291 {
1292   if(!areInfoEqualsIfNotWhy(other,reason))
1293     return false;
1294   return _mem.isEqual(other._mem,prec,reason);
1295 }
1296
1297 /*!
1298  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1299  * \ref MEDCouplingArrayBasicsCompare.
1300  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1301  *  \param [in] prec - precision value to compare numeric data of the arrays.
1302  *  \return bool - \a true if the two arrays are equal, \a false else.
1303  */
1304 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1305 {
1306   std::string tmp;
1307   return isEqualIfNotWhy(other,prec,tmp);
1308 }
1309
1310 /*!
1311  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1312  * \ref MEDCouplingArrayBasicsCompare.
1313  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1314  *  \param [in] prec - precision value to compare numeric data of the arrays.
1315  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1316  */
1317 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1318 {
1319   std::string tmp;
1320   return _mem.isEqual(other._mem,prec,tmp);
1321 }
1322
1323 /*!
1324  * Changes number of tuples in the array. If the new number of tuples is smaller
1325  * than the current number the array is truncated, otherwise the array is extended.
1326  *  \param [in] nbOfTuples - new number of tuples. 
1327  *  \throw If \a this is not allocated.
1328  *  \throw If \a nbOfTuples is negative.
1329  */
1330 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1331 {
1332   if(nbOfTuples<0)
1333     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1334   checkAllocated();
1335   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1336   declareAsNew();
1337 }
1338
1339 /*!
1340  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1341  * array to the new one.
1342  *  \return DataArrayInt * - the new instance of DataArrayInt.
1343  */
1344 DataArrayInt *DataArrayDouble::convertToIntArr() const
1345 {
1346   DataArrayInt *ret=DataArrayInt::New();
1347   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1348   std::size_t nbOfVals=getNbOfElems();
1349   const double *src=getConstPointer();
1350   int *dest=ret->getPointer();
1351   std::copy(src,src+nbOfVals,dest);
1352   ret->copyStringInfoFrom(*this);
1353   return ret;
1354 }
1355
1356 /*!
1357  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1358  * arranged in memory. If \a this array holds 2 components of 3 values:
1359  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1360  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1361  *  \warning Do not confuse this method with transpose()!
1362  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1363  *          is to delete using decrRef() as it is no more needed.
1364  *  \throw If \a this is not allocated.
1365  */
1366 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1367 {
1368   if(_mem.isNull())
1369     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1370   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1371   DataArrayDouble *ret=DataArrayDouble::New();
1372   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1373   return ret;
1374 }
1375
1376 /*!
1377  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1378  * arranged in memory. If \a this array holds 2 components of 3 values:
1379  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1380  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1381  *  \warning Do not confuse this method with transpose()!
1382  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1383  *          is to delete using decrRef() as it is no more needed.
1384  *  \throw If \a this is not allocated.
1385  */
1386 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1387 {
1388   if(_mem.isNull())
1389     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1390   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1391   DataArrayDouble *ret=DataArrayDouble::New();
1392   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1393   return ret;
1394 }
1395
1396 /*!
1397  * Permutes values of \a this array as required by \a old2New array. The values are
1398  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1399  * the same as in \this one.
1400  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1401  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1402  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1403  *     giving a new position for i-th old value.
1404  */
1405 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1406 {
1407   checkAllocated();
1408   int nbTuples=getNumberOfTuples();
1409   int nbOfCompo=getNumberOfComponents();
1410   double *tmp=new double[nbTuples*nbOfCompo];
1411   const double *iptr=getConstPointer();
1412   for(int i=0;i<nbTuples;i++)
1413     {
1414       int v=old2New[i];
1415       if(v>=0 && v<nbTuples)
1416         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1417       else
1418         {
1419           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1420           throw INTERP_KERNEL::Exception(oss.str().c_str());
1421         }
1422     }
1423   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1424   delete [] tmp;
1425   declareAsNew();
1426 }
1427
1428 /*!
1429  * Permutes values of \a this array as required by \a new2Old array. The values are
1430  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1431  * the same as in \this one.
1432  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1433  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1434  *     giving a previous position of i-th new value.
1435  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1436  *          is to delete using decrRef() as it is no more needed.
1437  */
1438 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1439 {
1440   checkAllocated();
1441   int nbTuples=getNumberOfTuples();
1442   int nbOfCompo=getNumberOfComponents();
1443   double *tmp=new double[nbTuples*nbOfCompo];
1444   const double *iptr=getConstPointer();
1445   for(int i=0;i<nbTuples;i++)
1446     {
1447       int v=new2Old[i];
1448       if(v>=0 && v<nbTuples)
1449         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1450       else
1451         {
1452           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1453           throw INTERP_KERNEL::Exception(oss.str().c_str());
1454         }
1455     }
1456   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1457   delete [] tmp;
1458   declareAsNew();
1459 }
1460
1461 /*!
1462  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1463  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1464  * Number of tuples in the result array remains the same as in \this one.
1465  * If a permutation reduction is needed, renumberAndReduce() should be used.
1466  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1467  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1468  *          giving a new position for i-th old value.
1469  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1470  *          is to delete using decrRef() as it is no more needed.
1471  *  \throw If \a this is not allocated.
1472  */
1473 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1474 {
1475   checkAllocated();
1476   int nbTuples=getNumberOfTuples();
1477   int nbOfCompo=getNumberOfComponents();
1478   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1479   ret->alloc(nbTuples,nbOfCompo);
1480   ret->copyStringInfoFrom(*this);
1481   const double *iptr=getConstPointer();
1482   double *optr=ret->getPointer();
1483   for(int i=0;i<nbTuples;i++)
1484     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1485   ret->copyStringInfoFrom(*this);
1486   return ret.retn();
1487 }
1488
1489 /*!
1490  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1491  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1492  * tuples in the result array remains the same as in \this one.
1493  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1494  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1495  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1496  *     giving a previous position of i-th new value.
1497  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1498  *          is to delete using decrRef() as it is no more needed.
1499  */
1500 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1501 {
1502   checkAllocated();
1503   int nbTuples=getNumberOfTuples();
1504   int nbOfCompo=getNumberOfComponents();
1505   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1506   ret->alloc(nbTuples,nbOfCompo);
1507   ret->copyStringInfoFrom(*this);
1508   const double *iptr=getConstPointer();
1509   double *optr=ret->getPointer();
1510   for(int i=0;i<nbTuples;i++)
1511     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1512   ret->copyStringInfoFrom(*this);
1513   return ret.retn();
1514 }
1515
1516 /*!
1517  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1518  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1519  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1520  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1521  * \a old2New[ i ] is negative, is missing from the result array.
1522  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1523  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1524  *     giving a new position for i-th old tuple and giving negative position for
1525  *     for i-th old tuple that should be omitted.
1526  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1527  *          is to delete using decrRef() as it is no more needed.
1528  */
1529 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1530 {
1531   checkAllocated();
1532   int nbTuples=getNumberOfTuples();
1533   int nbOfCompo=getNumberOfComponents();
1534   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1535   ret->alloc(newNbOfTuple,nbOfCompo);
1536   const double *iptr=getConstPointer();
1537   double *optr=ret->getPointer();
1538   for(int i=0;i<nbTuples;i++)
1539     {
1540       int w=old2New[i];
1541       if(w>=0)
1542         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1543     }
1544   ret->copyStringInfoFrom(*this);
1545   return ret.retn();
1546 }
1547
1548 /*!
1549  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1550  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1551  * \a new2OldBg array.
1552  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1553  * This method is equivalent to renumberAndReduce() except that convention in input is
1554  * \c new2old and \b not \c old2new.
1555  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1556  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1557  *              tuple index in \a this array to fill the i-th tuple in the new array.
1558  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1559  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1560  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1561  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1562  *          is to delete using decrRef() as it is no more needed.
1563  */
1564 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1565 {
1566   checkAllocated();
1567   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1568   int nbComp=getNumberOfComponents();
1569   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1570   ret->copyStringInfoFrom(*this);
1571   double *pt=ret->getPointer();
1572   const double *srcPt=getConstPointer();
1573   int i=0;
1574   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1575     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1576   ret->copyStringInfoFrom(*this);
1577   return ret.retn();
1578 }
1579
1580 /*!
1581  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1582  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1583  * \a new2OldBg array.
1584  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1585  * This method is equivalent to renumberAndReduce() except that convention in input is
1586  * \c new2old and \b not \c old2new.
1587  * This method is equivalent to selectByTupleId() except that it prevents coping data
1588  * from behind the end of \a this array.
1589  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1590  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1591  *              tuple index in \a this array to fill the i-th tuple in the new array.
1592  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1593  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1594  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1595  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1596  *          is to delete using decrRef() as it is no more needed.
1597  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1598  */
1599 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1600 {
1601   checkAllocated();
1602   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1603   int nbComp=getNumberOfComponents();
1604   int oldNbOfTuples=getNumberOfTuples();
1605   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1606   ret->copyStringInfoFrom(*this);
1607   double *pt=ret->getPointer();
1608   const double *srcPt=getConstPointer();
1609   int i=0;
1610   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1611     if(*w>=0 && *w<oldNbOfTuples)
1612       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1613     else
1614       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1615   ret->copyStringInfoFrom(*this);
1616   return ret.retn();
1617 }
1618
1619 /*!
1620  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1621  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1622  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1623  * command \c range( \a bg, \a end2, \a step ).
1624  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1625  * not constructed explicitly.
1626  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1627  *  \param [in] bg - index of the first tuple to copy from \a this array.
1628  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1629  *  \param [in] step - index increment to get index of the next tuple to copy.
1630  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1631  *          is to delete using decrRef() as it is no more needed.
1632  *  \sa DataArrayDouble::substr.
1633  */
1634 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1635 {
1636   checkAllocated();
1637   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1638   int nbComp=getNumberOfComponents();
1639   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1640   ret->alloc(newNbOfTuples,nbComp);
1641   double *pt=ret->getPointer();
1642   const double *srcPt=getConstPointer()+bg*nbComp;
1643   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1644     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1645   ret->copyStringInfoFrom(*this);
1646   return ret.retn();
1647 }
1648
1649 /*!
1650  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1651  * of tuples specified by \a ranges parameter.
1652  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1653  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1654  *              of tuples in [\c begin,\c end) format.
1655  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1656  *          is to delete using decrRef() as it is no more needed.
1657  *  \throw If \a end < \a begin.
1658  *  \throw If \a end > \a this->getNumberOfTuples().
1659  *  \throw If \a this is not allocated.
1660  */
1661 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1662 {
1663   checkAllocated();
1664   int nbOfComp=getNumberOfComponents();
1665   int nbOfTuplesThis=getNumberOfTuples();
1666   if(ranges.empty())
1667     {
1668       DataArrayDouble *ret=DataArrayDouble::New();
1669       ret->alloc(0,nbOfComp);
1670       ret->copyStringInfoFrom(*this);
1671       return ret;
1672     }
1673   int ref=ranges.front().first;
1674   int nbOfTuples=0;
1675   bool isIncreasing=true;
1676   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1677     {
1678       if((*it).first<=(*it).second)
1679         {
1680           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1681             {
1682               nbOfTuples+=(*it).second-(*it).first;
1683               if(isIncreasing)
1684                 isIncreasing=ref<=(*it).first;
1685               ref=(*it).second;
1686             }
1687           else
1688             {
1689               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1690               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1691               throw INTERP_KERNEL::Exception(oss.str().c_str());
1692             }
1693         }
1694       else
1695         {
1696           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1697           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1698           throw INTERP_KERNEL::Exception(oss.str().c_str());
1699         }
1700     }
1701   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1702     return deepCpy();
1703   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1704   ret->alloc(nbOfTuples,nbOfComp);
1705   ret->copyStringInfoFrom(*this);
1706   const double *src=getConstPointer();
1707   double *work=ret->getPointer();
1708   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1709     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1710   return ret.retn();
1711 }
1712
1713 /*!
1714  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1715  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1716  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1717  * This method is a specialization of selectByTupleId2().
1718  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1719  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1720  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1721  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1722  *          is to delete using decrRef() as it is no more needed.
1723  *  \throw If \a tupleIdBg < 0.
1724  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1725     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1726  *  \sa DataArrayDouble::selectByTupleId2
1727  */
1728 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1729 {
1730   checkAllocated();
1731   int nbt=getNumberOfTuples();
1732   if(tupleIdBg<0)
1733     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1734   if(tupleIdBg>nbt)
1735     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1736   int trueEnd=tupleIdEnd;
1737   if(tupleIdEnd!=-1)
1738     {
1739       if(tupleIdEnd>nbt)
1740         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1741     }
1742   else
1743     trueEnd=nbt;
1744   int nbComp=getNumberOfComponents();
1745   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1746   ret->alloc(trueEnd-tupleIdBg,nbComp);
1747   ret->copyStringInfoFrom(*this);
1748   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1749   return ret.retn();
1750 }
1751
1752 /*!
1753  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1754  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1755  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1756  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1757  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1758  * components.  
1759  *  \param [in] newNbOfComp - number of components for the new array to have.
1760  *  \param [in] dftValue - value assigned to new values added to the new array.
1761  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1762  *          is to delete using decrRef() as it is no more needed.
1763  *  \throw If \a this is not allocated.
1764  */
1765 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1766 {
1767   checkAllocated();
1768   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1769   ret->alloc(getNumberOfTuples(),newNbOfComp);
1770   const double *oldc=getConstPointer();
1771   double *nc=ret->getPointer();
1772   int nbOfTuples=getNumberOfTuples();
1773   int oldNbOfComp=getNumberOfComponents();
1774   int dim=std::min(oldNbOfComp,newNbOfComp);
1775   for(int i=0;i<nbOfTuples;i++)
1776     {
1777       int j=0;
1778       for(;j<dim;j++)
1779         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1780       for(;j<newNbOfComp;j++)
1781         nc[newNbOfComp*i+j]=dftValue;
1782     }
1783   ret->setName(getName().c_str());
1784   for(int i=0;i<dim;i++)
1785     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1786   ret->setName(getName().c_str());
1787   return ret.retn();
1788 }
1789
1790 /*!
1791  * Changes the number of components within \a this array so that its raw data **does
1792  * not** change, instead splitting this data into tuples changes.
1793  *  \warning This method erases all (name and unit) component info set before!
1794  *  \param [in] newNbOfComp - number of components for \a this array to have.
1795  *  \throw If \a this is not allocated
1796  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1797  *  \throw If \a newNbOfCompo is lower than 1.
1798  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1799  *  \warning This method erases all (name and unit) component info set before!
1800  */
1801 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1802 {
1803   checkAllocated();
1804   if(newNbOfCompo<1)
1805     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1806   std::size_t nbOfElems=getNbOfElems();
1807   if(nbOfElems%newNbOfCompo!=0)
1808     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1809   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1810     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1811   _info_on_compo.clear();
1812   _info_on_compo.resize(newNbOfCompo);
1813   declareAsNew();
1814 }
1815
1816 /*!
1817  * Changes the number of components within \a this array to be equal to its number
1818  * of tuples, and inversely its number of tuples to become equal to its number of 
1819  * components. So that its raw data **does not** change, instead splitting this
1820  * data into tuples changes.
1821  *  \warning This method erases all (name and unit) component info set before!
1822  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1823  *  \throw If \a this is not allocated.
1824  *  \sa rearrange()
1825  */
1826 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1827 {
1828   checkAllocated();
1829   int nbOfTuples=getNumberOfTuples();
1830   rearrange(nbOfTuples);
1831 }
1832
1833 /*!
1834  * Returns a copy of \a this array composed of selected components.
1835  * The new DataArrayDouble has the same number of tuples but includes components
1836  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1837  * can be either less, same or more than \a this->getNbOfElems().
1838  *  \param [in] compoIds - sequence of zero based indices of components to include
1839  *              into the new array.
1840  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1841  *          is to delete using decrRef() as it is no more needed.
1842  *  \throw If \a this is not allocated.
1843  *  \throw If a component index (\a i) is not valid: 
1844  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1845  *
1846  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1847  */
1848 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1849 {
1850   checkAllocated();
1851   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1852   std::size_t newNbOfCompo=compoIds.size();
1853   int oldNbOfCompo=getNumberOfComponents();
1854   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1855     if((*it)<0 || (*it)>=oldNbOfCompo)
1856       {
1857         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1858         throw INTERP_KERNEL::Exception(oss.str().c_str());
1859       }
1860   int nbOfTuples=getNumberOfTuples();
1861   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1862   ret->copyPartOfStringInfoFrom(*this,compoIds);
1863   const double *oldc=getConstPointer();
1864   double *nc=ret->getPointer();
1865   for(int i=0;i<nbOfTuples;i++)
1866     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1867       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1868   return ret.retn();
1869 }
1870
1871 /*!
1872  * Appends components of another array to components of \a this one, tuple by tuple.
1873  * So that the number of tuples of \a this array remains the same and the number of 
1874  * components increases.
1875  *  \param [in] other - the DataArrayDouble to append to \a this one.
1876  *  \throw If \a this is not allocated.
1877  *  \throw If \a this and \a other arrays have different number of tuples.
1878  *
1879  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1880  *
1881  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1882  */
1883 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1884 {
1885   checkAllocated();
1886   other->checkAllocated();
1887   int nbOfTuples=getNumberOfTuples();
1888   if(nbOfTuples!=other->getNumberOfTuples())
1889     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1890   int nbOfComp1=getNumberOfComponents();
1891   int nbOfComp2=other->getNumberOfComponents();
1892   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1893   double *w=newArr;
1894   const double *inp1=getConstPointer();
1895   const double *inp2=other->getConstPointer();
1896   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1897     {
1898       w=std::copy(inp1,inp1+nbOfComp1,w);
1899       w=std::copy(inp2,inp2+nbOfComp2,w);
1900     }
1901   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1902   std::vector<int> compIds(nbOfComp2);
1903   for(int i=0;i<nbOfComp2;i++)
1904     compIds[i]=nbOfComp1+i;
1905   copyPartOfStringInfoFrom2(compIds,*other);
1906 }
1907
1908 /*!
1909  * This method checks that all tuples in \a other are in \a this.
1910  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1911  * 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.
1912  *
1913  * \param [in] other - the array having the same number of components than \a this.
1914  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1915  * \sa DataArrayDouble::findCommonTuples
1916  */
1917 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1918 {
1919   if(!other)
1920     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1921   checkAllocated(); other->checkAllocated();
1922   if(getNumberOfComponents()!=other->getNumberOfComponents())
1923     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1924   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1925   DataArrayInt *c=0,*ci=0;
1926   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1927   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1928   int newNbOfTuples=-1;
1929   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1930   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1931   tupleIds=ret1.retn();
1932   return newNbOfTuples==getNumberOfTuples();
1933 }
1934
1935 /*!
1936  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1937  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1938  * distance separating two points is computed with the infinite norm.
1939  *
1940  * Indices of coincident tuples are stored in output arrays.
1941  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1942  *
1943  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1944  * MEDCouplingUMesh::mergeNodes().
1945  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1946  *              considered not coincident.
1947  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1948  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1949  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1950  *               \a comm->getNumberOfComponents() == 1. 
1951  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1952  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1953  *               groups of (indices of) coincident tuples. Its every value is a tuple
1954  *               index where a next group of tuples begins. For example the second
1955  *               group of tuples in \a comm is described by following range of indices:
1956  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1957  *               gives the number of groups of coincident tuples.
1958  *  \throw If \a this is not allocated.
1959  *  \throw If the number of components is not in [1,2,3].
1960  *
1961  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1962  *
1963  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1964  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1965  */
1966 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1967 {
1968   checkAllocated();
1969   int nbOfCompo=getNumberOfComponents();
1970   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1971     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1972   
1973   int nbOfTuples=getNumberOfTuples();
1974   //
1975   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1976   switch(nbOfCompo)
1977     {
1978     case 3:
1979       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1980       break;
1981     case 2:
1982       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1983       break;
1984     case 1:
1985       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1986       break;
1987     default:
1988       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1989     }
1990   comm=c.retn();
1991   commIndex=cI.retn();
1992 }
1993
1994 /*!
1995  * 
1996  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1997  *             \a nbTimes  should be at least equal to 1.
1998  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1999  * \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.
2000  */
2001 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
2002 {
2003   checkAllocated();
2004   if(getNumberOfComponents()!=1)
2005     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2006   if(nbTimes<1)
2007     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2008   int nbTuples=getNumberOfTuples();
2009   const double *inPtr=getConstPointer();
2010   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2011   double *retPtr=ret->getPointer();
2012   for(int i=0;i<nbTuples;i++,inPtr++)
2013     {
2014       double val=*inPtr;
2015       for(int j=0;j<nbTimes;j++,retPtr++)
2016         *retPtr=val;
2017     }
2018   ret->copyStringInfoFrom(*this);
2019   return ret.retn();
2020 }
2021
2022 /*!
2023  * This methods returns the minimal distance between the two set of points \a this and \a other.
2024  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2025  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2026  *
2027  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2028  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2029  * \return the minimal distance between the two set of points \a this and \a other.
2030  * \sa DataArrayDouble::findClosestTupleId
2031  */
2032 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
2033 {
2034   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2035   int nbOfCompo(getNumberOfComponents());
2036   int otherNbTuples(other->getNumberOfTuples());
2037   const double *thisPt(begin()),*otherPt(other->begin());
2038   const int *part1Pt(part1->begin());
2039   double ret=std::numeric_limits<double>::max();
2040   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2041     {
2042       double tmp(0.);
2043       for(int j=0;j<nbOfCompo;j++)
2044         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2045       if(tmp<ret)
2046         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2047     }
2048   return sqrt(ret);
2049 }
2050
2051 /*!
2052  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2053  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2054  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2055  *
2056  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2057  * \sa DataArrayDouble::minimalDistanceTo
2058  */
2059 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
2060 {
2061   if(!other)
2062     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2063   checkAllocated(); other->checkAllocated();
2064   int nbOfCompo=getNumberOfComponents();
2065   if(nbOfCompo!=other->getNumberOfComponents())
2066     {
2067       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2068       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2069       throw INTERP_KERNEL::Exception(oss.str().c_str());
2070     }
2071   int nbOfTuples=other->getNumberOfTuples();
2072   int thisNbOfTuples=getNumberOfTuples();
2073   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2074   double bounds[6];
2075   getMinMaxPerComponent(bounds);
2076   switch(nbOfCompo)
2077     {
2078     case 3:
2079       {
2080         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2081         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2082         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2083         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2084         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2085         break;
2086       }
2087     case 2:
2088       {
2089         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2090         double delta=std::max(xDelta,yDelta);
2091         double characSize=sqrt(delta/(double)thisNbOfTuples);
2092         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2093         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2094         break;
2095       }
2096     case 1:
2097       {
2098         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2099         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2100         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2101         break;
2102       }
2103     default:
2104       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2105     }
2106   return ret.retn();
2107 }
2108
2109 /*!
2110  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2111  * 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
2112  * how many bounding boxes in \a otherBBoxFrmt.
2113  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2114  *
2115  * \param [in] otherBBoxFrmt - It is an array .
2116  * \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.
2117  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2118  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2119  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2120  */
2121 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception)
2122 {
2123   if(!otherBBoxFrmt)
2124     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2125   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2126     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2127   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2128   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2129     {
2130       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2131       throw INTERP_KERNEL::Exception(oss.str().c_str());
2132     }
2133   if(nbOfComp%2!=0)
2134     {
2135       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2136       throw INTERP_KERNEL::Exception(oss.str().c_str());
2137     }
2138   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2139   const double *thisBBPtr(begin());
2140   int *retPtr(ret->getPointer());
2141   switch(nbOfComp/2)
2142     {
2143     case 3:
2144       {
2145         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2146         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2147           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2148         break;
2149       }
2150     case 2:
2151       {
2152         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2153         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2154           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2155         break;
2156       }
2157     case 1:
2158       {
2159         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2160         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2161           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2162         break;
2163       }
2164     defaut:
2165       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2166     }
2167   
2168   return ret.retn();
2169 }
2170
2171 /*!
2172  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2173  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2174  * space. The distance between tuples is computed using norm2. If several tuples are
2175  * not far each from other than \a prec, only one of them remains in the result
2176  * array. The order of tuples in the result array is same as in \a this one except
2177  * that coincident tuples are excluded.
2178  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2179  *              considered not coincident.
2180  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2181  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2182  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2183  *          is to delete using decrRef() as it is no more needed.
2184  *  \throw If \a this is not allocated.
2185  *  \throw If the number of components is not in [1,2,3].
2186  *
2187  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2188  */
2189 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2190 {
2191   checkAllocated();
2192   DataArrayInt *c0=0,*cI0=0;
2193   findCommonTuples(prec,limitTupleId,c0,cI0);
2194   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2195   int newNbOfTuples=-1;
2196   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2197   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2198 }
2199
2200 /*!
2201  * Copy all components in a specified order from another DataArrayDouble.
2202  * Both numerical and textual data is copied. The number of tuples in \a this and
2203  * the other array can be different.
2204  *  \param [in] a - the array to copy data from.
2205  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2206  *              to be copied.
2207  *  \throw If \a a is NULL.
2208  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2209  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2210  *
2211  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2212  */
2213 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2214 {
2215   if(!a)
2216     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2217   checkAllocated();
2218   copyPartOfStringInfoFrom2(compoIds,*a);
2219   std::size_t partOfCompoSz=compoIds.size();
2220   int nbOfCompo=getNumberOfComponents();
2221   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2222   const double *ac=a->getConstPointer();
2223   double *nc=getPointer();
2224   for(int i=0;i<nbOfTuples;i++)
2225     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2226       nc[nbOfCompo*i+compoIds[j]]=*ac;
2227 }
2228
2229 /*!
2230  * Copy all values from another DataArrayDouble into specified tuples and components
2231  * of \a this array. Textual data is not copied.
2232  * The tree parameters defining set of indices of tuples and components are similar to
2233  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2234  *  \param [in] a - the array to copy values from.
2235  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2236  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2237  *              are located.
2238  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2239  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2240  *  \param [in] endComp - index of the component before which the components to assign
2241  *              to are located.
2242  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2243  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2244  *              must be equal to the number of columns to assign to, else an
2245  *              exception is thrown; if \a false, then it is only required that \a
2246  *              a->getNbOfElems() equals to number of values to assign to (this condition
2247  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2248  *              values to assign to is given by following Python expression:
2249  *              \a nbTargetValues = 
2250  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2251  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2252  *  \throw If \a a is NULL.
2253  *  \throw If \a a is not allocated.
2254  *  \throw If \a this is not allocated.
2255  *  \throw If parameters specifying tuples and components to assign to do not give a
2256  *            non-empty range of increasing indices.
2257  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2258  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2259  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2260  *
2261  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2262  */
2263 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2264 {
2265   if(!a)
2266     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2267   const char msg[]="DataArrayDouble::setPartOfValues1";
2268   checkAllocated();
2269   a->checkAllocated();
2270   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2271   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2272   int nbComp=getNumberOfComponents();
2273   int nbOfTuples=getNumberOfTuples();
2274   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2275   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2276   bool assignTech=true;
2277   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2278     {
2279       if(strictCompoCompare)
2280         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2281     }
2282   else
2283     {
2284       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2285       assignTech=false;
2286     }
2287   const double *srcPt=a->getConstPointer();
2288   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2289   if(assignTech)
2290     {
2291       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2292         for(int j=0;j<newNbOfComp;j++,srcPt++)
2293           pt[j*stepComp]=*srcPt;
2294     }
2295   else
2296     {
2297       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2298         {
2299           const double *srcPt2=srcPt;
2300           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2301             pt[j*stepComp]=*srcPt2;
2302         }
2303     }
2304 }
2305
2306 /*!
2307  * Assign a given value to values at specified tuples and components of \a this array.
2308  * The tree parameters defining set of indices of tuples and components are similar to
2309  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2310  *  \param [in] a - the value to assign.
2311  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2312  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2313  *              are located.
2314  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2315  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2316  *  \param [in] endComp - index of the component before which the components to assign
2317  *              to are located.
2318  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2319  *  \throw If \a this is not allocated.
2320  *  \throw If parameters specifying tuples and components to assign to, do not give a
2321  *            non-empty range of increasing indices or indices are out of a valid range
2322  *            for \this array.
2323  *
2324  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2325  */
2326 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2327 {
2328   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2329   checkAllocated();
2330   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2331   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2332   int nbComp=getNumberOfComponents();
2333   int nbOfTuples=getNumberOfTuples();
2334   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2335   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2336   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2337   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2338     for(int j=0;j<newNbOfComp;j++)
2339       pt[j*stepComp]=a;
2340 }
2341
2342 /*!
2343  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2344  * components of \a this array. Textual data is not copied.
2345  * The tuples and components to assign to are defined by C arrays of indices.
2346  * There are two *modes of usage*:
2347  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2348  *   of \a a is assigned to its own location within \a this array. 
2349  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2350  *   components of every specified tuple of \a this array. In this mode it is required
2351  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2352  *
2353  *  \param [in] a - the array to copy values from.
2354  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2355  *              assign values of \a a to.
2356  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2357  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2358  *              \a bgTuples <= \a pi < \a endTuples.
2359  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2360  *              assign values of \a a to.
2361  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2362  *              pointer to a component index <em>(pi)</em> varies as this: 
2363  *              \a bgComp <= \a pi < \a endComp.
2364  *  \param [in] strictCompoCompare - this parameter is checked only if the
2365  *               *mode of usage* is the first; if it is \a true (default), 
2366  *               then \a a->getNumberOfComponents() must be equal 
2367  *               to the number of specified columns, else this is not required.
2368  *  \throw If \a a is NULL.
2369  *  \throw If \a a is not allocated.
2370  *  \throw If \a this is not allocated.
2371  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2372  *         out of a valid range for \a this array.
2373  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2374  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2375  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2376  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2377  *
2378  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2379  */
2380 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2381 {
2382   if(!a)
2383     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2384   const char msg[]="DataArrayDouble::setPartOfValues2";
2385   checkAllocated();
2386   a->checkAllocated();
2387   int nbComp=getNumberOfComponents();
2388   int nbOfTuples=getNumberOfTuples();
2389   for(const int *z=bgComp;z!=endComp;z++)
2390     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2391   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2392   int newNbOfComp=(int)std::distance(bgComp,endComp);
2393   bool assignTech=true;
2394   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2395     {
2396       if(strictCompoCompare)
2397         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2398     }
2399   else
2400     {
2401       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2402       assignTech=false;
2403     }
2404   double *pt=getPointer();
2405   const double *srcPt=a->getConstPointer();
2406   if(assignTech)
2407     {    
2408       for(const int *w=bgTuples;w!=endTuples;w++)
2409         {
2410           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2411           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2412             {    
2413               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2414             }
2415         }
2416     }
2417   else
2418     {
2419       for(const int *w=bgTuples;w!=endTuples;w++)
2420         {
2421           const double *srcPt2=srcPt;
2422           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2423           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2424             {    
2425               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2426             }
2427         }
2428     }
2429 }
2430
2431 /*!
2432  * Assign a given value to values at specified tuples and components of \a this array.
2433  * The tuples and components to assign to are defined by C arrays of indices.
2434  *  \param [in] a - the value to assign.
2435  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2436  *              assign \a a to.
2437  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2438  *              pointer to a tuple index (\a pi) varies as this: 
2439  *              \a bgTuples <= \a pi < \a endTuples.
2440  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2441  *              assign \a a to.
2442  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2443  *              pointer to a component index (\a pi) varies as this: 
2444  *              \a bgComp <= \a pi < \a endComp.
2445  *  \throw If \a this is not allocated.
2446  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2447  *         out of a valid range for \a this array.
2448  *
2449  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2450  */
2451 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2452 {
2453   checkAllocated();
2454   int nbComp=getNumberOfComponents();
2455   int nbOfTuples=getNumberOfTuples();
2456   for(const int *z=bgComp;z!=endComp;z++)
2457     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2458   double *pt=getPointer();
2459   for(const int *w=bgTuples;w!=endTuples;w++)
2460     for(const int *z=bgComp;z!=endComp;z++)
2461       {
2462         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2463         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2464       }
2465 }
2466
2467 /*!
2468  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2469  * components of \a this array. Textual data is not copied.
2470  * The tuples to assign to are defined by a C array of indices.
2471  * The components to assign to are defined by three values similar to parameters of
2472  * the Python function \c range(\c start,\c stop,\c step).
2473  * There are two *modes of usage*:
2474  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2475  *   of \a a is assigned to its own location within \a this array. 
2476  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2477  *   components of every specified tuple of \a this array. In this mode it is required
2478  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2479  *
2480  *  \param [in] a - the array to copy values from.
2481  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2482  *              assign values of \a a to.
2483  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2484  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2485  *              \a bgTuples <= \a pi < \a endTuples.
2486  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2487  *  \param [in] endComp - index of the component before which the components to assign
2488  *              to are located.
2489  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2490  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2491  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2492  *               then \a a->getNumberOfComponents() must be equal 
2493  *               to the number of specified columns, else this is not required.
2494  *  \throw If \a a is NULL.
2495  *  \throw If \a a is not allocated.
2496  *  \throw If \a this is not allocated.
2497  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2498  *         \a this array.
2499  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2500  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2501  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2502  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2503  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2504  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2505  *  \throw If parameters specifying components to assign to, do not give a
2506  *            non-empty range of increasing indices or indices are out of a valid range
2507  *            for \this array.
2508  *
2509  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2510  */
2511 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2512 {
2513   if(!a)
2514     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2515   const char msg[]="DataArrayDouble::setPartOfValues3";
2516   checkAllocated();
2517   a->checkAllocated();
2518   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2519   int nbComp=getNumberOfComponents();
2520   int nbOfTuples=getNumberOfTuples();
2521   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2522   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2523   bool assignTech=true;
2524   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2525     {
2526       if(strictCompoCompare)
2527         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2528     }
2529   else
2530     {
2531       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2532       assignTech=false;
2533     }
2534   double *pt=getPointer()+bgComp;
2535   const double *srcPt=a->getConstPointer();
2536   if(assignTech)
2537     {
2538       for(const int *w=bgTuples;w!=endTuples;w++)
2539         for(int j=0;j<newNbOfComp;j++,srcPt++)
2540           {
2541             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2542             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2543           }
2544     }
2545   else
2546     {
2547       for(const int *w=bgTuples;w!=endTuples;w++)
2548         {
2549           const double *srcPt2=srcPt;
2550           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2551             {
2552               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2553               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2554             }
2555         }
2556     }
2557 }
2558
2559 /*!
2560  * Assign a given value to values at specified tuples and components of \a this array.
2561  * The tuples to assign to are defined by a C array of indices.
2562  * The components to assign to are defined by three values similar to parameters of
2563  * the Python function \c range(\c start,\c stop,\c step).
2564  *  \param [in] a - the value to assign.
2565  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2566  *              assign \a a to.
2567  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2568  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2569  *              \a bgTuples <= \a pi < \a endTuples.
2570  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2571  *  \param [in] endComp - index of the component before which the components to assign
2572  *              to are located.
2573  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2574  *  \throw If \a this is not allocated.
2575  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2576  *         \a this array.
2577  *  \throw If parameters specifying components to assign to, do not give a
2578  *            non-empty range of increasing indices or indices are out of a valid range
2579  *            for \this array.
2580  *
2581  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2582  */
2583 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2584 {
2585   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2586   checkAllocated();
2587   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2588   int nbComp=getNumberOfComponents();
2589   int nbOfTuples=getNumberOfTuples();
2590   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2591   double *pt=getPointer()+bgComp;
2592   for(const int *w=bgTuples;w!=endTuples;w++)
2593     for(int j=0;j<newNbOfComp;j++)
2594       {
2595         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2596         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2597       }
2598 }
2599
2600 /*!
2601  * Copy all values from another DataArrayDouble into specified tuples and components
2602  * of \a this array. Textual data is not copied.
2603  * The tree parameters defining set of indices of tuples and components are similar to
2604  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2605  *  \param [in] a - the array to copy values from.
2606  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2607  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2608  *              are located.
2609  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2610  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2611  *              assign \a a to.
2612  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2613  *              pointer to a component index (\a pi) varies as this: 
2614  *              \a bgComp <= \a pi < \a endComp.
2615  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2616  *              must be equal to the number of columns to assign to, else an
2617  *              exception is thrown; if \a false, then it is only required that \a
2618  *              a->getNbOfElems() equals to number of values to assign to (this condition
2619  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2620  *              values to assign to is given by following Python expression:
2621  *              \a nbTargetValues = 
2622  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2623  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2624  *  \throw If \a a is NULL.
2625  *  \throw If \a a is not allocated.
2626  *  \throw If \a this is not allocated.
2627  *  \throw If parameters specifying tuples and components to assign to do not give a
2628  *            non-empty range of increasing indices.
2629  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2630  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2631  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2632  *
2633  */
2634 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2635 {
2636   if(!a)
2637     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2638   const char msg[]="DataArrayDouble::setPartOfValues4";
2639   checkAllocated();
2640   a->checkAllocated();
2641   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2642   int newNbOfComp=(int)std::distance(bgComp,endComp);
2643   int nbComp=getNumberOfComponents();
2644   for(const int *z=bgComp;z!=endComp;z++)
2645     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2646   int nbOfTuples=getNumberOfTuples();
2647   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2648   bool assignTech=true;
2649   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2650     {
2651       if(strictCompoCompare)
2652         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2653     }
2654   else
2655     {
2656       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2657       assignTech=false;
2658     }
2659   const double *srcPt=a->getConstPointer();
2660   double *pt=getPointer()+bgTuples*nbComp;
2661   if(assignTech)
2662     {
2663       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2664         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2665           pt[*z]=*srcPt;
2666     }
2667   else
2668     {
2669       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2670         {
2671           const double *srcPt2=srcPt;
2672           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2673             pt[*z]=*srcPt2;
2674         }
2675     }
2676 }
2677
2678 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2679 {
2680   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2681   checkAllocated();
2682   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2683   int nbComp=getNumberOfComponents();
2684   for(const int *z=bgComp;z!=endComp;z++)
2685     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2686   int nbOfTuples=getNumberOfTuples();
2687   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2688   double *pt=getPointer()+bgTuples*nbComp;
2689   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2690     for(const int *z=bgComp;z!=endComp;z++)
2691       pt[*z]=a;
2692 }
2693
2694 /*!
2695  * Copy some tuples from another DataArrayDouble into specified tuples
2696  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2697  * components.
2698  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2699  * All components of selected tuples are copied.
2700  *  \param [in] a - the array to copy values from.
2701  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2702  *              target tuples of \a this. \a tuplesSelec has two components, and the
2703  *              first component specifies index of the source tuple and the second
2704  *              one specifies index of the target tuple.
2705  *  \throw If \a this is not allocated.
2706  *  \throw If \a a is NULL.
2707  *  \throw If \a a is not allocated.
2708  *  \throw If \a tuplesSelec is NULL.
2709  *  \throw If \a tuplesSelec is not allocated.
2710  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2711  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2712  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2713  *         the corresponding (\a this or \a a) array.
2714  */
2715 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2716 {
2717   if(!a || !tuplesSelec)
2718     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2719   checkAllocated();
2720   a->checkAllocated();
2721   tuplesSelec->checkAllocated();
2722   int nbOfComp=getNumberOfComponents();
2723   if(nbOfComp!=a->getNumberOfComponents())
2724     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2725   if(tuplesSelec->getNumberOfComponents()!=2)
2726     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2727   int thisNt=getNumberOfTuples();
2728   int aNt=a->getNumberOfTuples();
2729   double *valsToSet=getPointer();
2730   const double *valsSrc=a->getConstPointer();
2731   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2732     {
2733       if(tuple[1]>=0 && tuple[1]<aNt)
2734         {
2735           if(tuple[0]>=0 && tuple[0]<thisNt)
2736             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2737           else
2738             {
2739               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2740               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2741               throw INTERP_KERNEL::Exception(oss.str().c_str());
2742             }
2743         }
2744       else
2745         {
2746           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2747           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2748           throw INTERP_KERNEL::Exception(oss.str().c_str());
2749         }
2750     }
2751 }
2752
2753 /*!
2754  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2755  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2756  * components.
2757  * The tuples to assign to are defined by index of the first tuple, and
2758  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2759  * The tuples to copy are defined by values of a DataArrayInt.
2760  * All components of selected tuples are copied.
2761  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2762  *              values to.
2763  *  \param [in] aBase - the array to copy values from.
2764  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2765  *  \throw If \a this is not allocated.
2766  *  \throw If \a aBase is NULL.
2767  *  \throw If \a aBase is not allocated.
2768  *  \throw If \a tuplesSelec is NULL.
2769  *  \throw If \a tuplesSelec is not allocated.
2770  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2771  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2772  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2773  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2774  *         \a aBase array.
2775  */
2776 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2777 {
2778   if(!aBase || !tuplesSelec)
2779     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2780   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2781   if(!a)
2782     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2783   checkAllocated();
2784   a->checkAllocated();
2785   tuplesSelec->checkAllocated();
2786   int nbOfComp=getNumberOfComponents();
2787   if(nbOfComp!=a->getNumberOfComponents())
2788     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2789   if(tuplesSelec->getNumberOfComponents()!=1)
2790     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2791   int thisNt=getNumberOfTuples();
2792   int aNt=a->getNumberOfTuples();
2793   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2794   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2795   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2796     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2797   const double *valsSrc=a->getConstPointer();
2798   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2799     {
2800       if(*tuple>=0 && *tuple<aNt)
2801         {
2802           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2803         }
2804       else
2805         {
2806           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2807           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2808           throw INTERP_KERNEL::Exception(oss.str().c_str());
2809         }
2810     }
2811 }
2812
2813 /*!
2814  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2815  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2816  * components.
2817  * The tuples to copy are defined by three values similar to parameters of
2818  * the Python function \c range(\c start,\c stop,\c step).
2819  * The tuples to assign to are defined by index of the first tuple, and
2820  * their number is defined by number of tuples to copy.
2821  * All components of selected tuples are copied.
2822  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2823  *              values to.
2824  *  \param [in] aBase - the array to copy values from.
2825  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2826  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2827  *              are located.
2828  *  \param [in] step - index increment to get index of the next tuple to copy.
2829  *  \throw If \a this is not allocated.
2830  *  \throw If \a aBase is NULL.
2831  *  \throw If \a aBase is not allocated.
2832  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2833  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2834  *  \throw If parameters specifying tuples to copy, do not give a
2835  *            non-empty range of increasing indices or indices are out of a valid range
2836  *            for the array \a aBase.
2837  */
2838 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2839 {
2840   if(!aBase)
2841     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2842   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2843   if(!a)
2844     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2845   checkAllocated();
2846   a->checkAllocated();
2847   int nbOfComp=getNumberOfComponents();
2848   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2849   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2850   if(nbOfComp!=a->getNumberOfComponents())
2851     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2852   int thisNt=getNumberOfTuples();
2853   int aNt=a->getNumberOfTuples();
2854   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2855   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2856     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2857   if(end2>aNt)
2858     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2859   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2860   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2861     {
2862       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2863     }
2864 }
2865
2866 /*!
2867  * Returns a value located at specified tuple and component.
2868  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2869  * parameters is checked. So this method is safe but expensive if used to go through
2870  * all values of \a this.
2871  *  \param [in] tupleId - index of tuple of interest.
2872  *  \param [in] compoId - index of component of interest.
2873  *  \return double - value located by \a tupleId and \a compoId.
2874  *  \throw If \a this is not allocated.
2875  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2876  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2877  */
2878 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2879 {
2880   checkAllocated();
2881   if(tupleId<0 || tupleId>=getNumberOfTuples())
2882     {
2883       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2884       throw INTERP_KERNEL::Exception(oss.str().c_str());
2885     }
2886   if(compoId<0 || compoId>=getNumberOfComponents())
2887     {
2888       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2889       throw INTERP_KERNEL::Exception(oss.str().c_str());
2890     }
2891   return _mem[tupleId*_info_on_compo.size()+compoId];
2892 }
2893
2894 /*!
2895  * Returns the first value of \a this. 
2896  *  \return double - the last value of \a this array.
2897  *  \throw If \a this is not allocated.
2898  *  \throw If \a this->getNumberOfComponents() != 1.
2899  *  \throw If \a this->getNumberOfTuples() < 1.
2900  */
2901 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2902 {
2903   checkAllocated();
2904   if(getNumberOfComponents()!=1)
2905     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2906   int nbOfTuples=getNumberOfTuples();
2907   if(nbOfTuples<1)
2908     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2909   return *(getConstPointer());
2910 }
2911
2912 /*!
2913  * Returns the last value of \a this. 
2914  *  \return double - the last value of \a this array.
2915  *  \throw If \a this is not allocated.
2916  *  \throw If \a this->getNumberOfComponents() != 1.
2917  *  \throw If \a this->getNumberOfTuples() < 1.
2918  */
2919 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2920 {
2921   checkAllocated();
2922   if(getNumberOfComponents()!=1)
2923     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2924   int nbOfTuples=getNumberOfTuples();
2925   if(nbOfTuples<1)
2926     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2927   return *(getConstPointer()+nbOfTuples-1);
2928 }
2929
2930 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2931 {
2932   if(newArray!=arrayToSet)
2933     {
2934       if(arrayToSet)
2935         arrayToSet->decrRef();
2936       arrayToSet=newArray;
2937       if(arrayToSet)
2938         arrayToSet->incrRef();
2939     }
2940 }
2941
2942 /*!
2943  * Sets a C array to be used as raw data of \a this. The previously set info
2944  *  of components is retained and re-sized. 
2945  * For more info see \ref MEDCouplingArraySteps1.
2946  *  \param [in] array - the C array to be used as raw data of \a this.
2947  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2948  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2949  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2950  *                     \c free(\c array ) will be called.
2951  *  \param [in] nbOfTuple - new number of tuples in \a this.
2952  *  \param [in] nbOfCompo - new number of components in \a this.
2953  */
2954 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2955 {
2956   _info_on_compo.resize(nbOfCompo);
2957   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2958   declareAsNew();
2959 }
2960
2961 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2962 {
2963   _info_on_compo.resize(nbOfCompo);
2964   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2965   declareAsNew();
2966 }
2967
2968 /*!
2969  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2970  * is thrown.
2971  * \throw If zero is found in \a this array.
2972  */
2973 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2974 {
2975   const double *tmp=getConstPointer();
2976   std::size_t nbOfElems=getNbOfElems();
2977   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2978   if(where!=tmp+nbOfElems)
2979     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2980 }
2981
2982 /*!
2983  * Computes minimal and maximal value in each component. An output array is filled
2984  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2985  * enough memory before calling this method.
2986  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2987  *               It is filled as follows:<br>
2988  *               \a bounds[0] = \c min_of_component_0 <br>
2989  *               \a bounds[1] = \c max_of_component_0 <br>
2990  *               \a bounds[2] = \c min_of_component_1 <br>
2991  *               \a bounds[3] = \c max_of_component_1 <br>
2992  *               ...
2993  */
2994 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2995 {
2996   checkAllocated();
2997   int dim=getNumberOfComponents();
2998   for (int idim=0; idim<dim; idim++)
2999     {
3000       bounds[idim*2]=std::numeric_limits<double>::max();
3001       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3002     } 
3003   const double *ptr=getConstPointer();
3004   int nbOfTuples=getNumberOfTuples();
3005   for(int i=0;i<nbOfTuples;i++)
3006     {
3007       for(int idim=0;idim<dim;idim++)
3008         {
3009           if(bounds[idim*2]>ptr[i*dim+idim])
3010             {
3011               bounds[idim*2]=ptr[i*dim+idim];
3012             }
3013           if(bounds[idim*2+1]<ptr[i*dim+idim])
3014             {
3015               bounds[idim*2+1]=ptr[i*dim+idim];
3016             }
3017         }
3018     }
3019 }
3020
3021 /*!
3022  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3023  * to store both the min and max per component of each tuples. 
3024  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3025  *
3026  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3027  *
3028  * \throw If \a this is not allocated yet.
3029  */
3030 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
3031 {
3032   checkAllocated();
3033   const double *dataPtr=getConstPointer();
3034   int nbOfCompo=getNumberOfComponents();
3035   int nbTuples=getNumberOfTuples();
3036   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3037   bbox->alloc(nbTuples,2*nbOfCompo);
3038   double *bboxPtr=bbox->getPointer();
3039   for(int i=0;i<nbTuples;i++)
3040     {
3041       for(int j=0;j<nbOfCompo;j++)
3042         {
3043           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3044           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3045         }
3046     }
3047   return bbox.retn();
3048 }
3049
3050 /*!
3051  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3052  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3053  * 
3054  * \param [in] other a DataArrayDouble having same number of components than \a this.
3055  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3056  * \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.
3057  *             \a cI allows to extract information in \a c.
3058  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3059  *
3060  * \throw In case of:
3061  *  - \a this is not allocated
3062  *  - \a other is not allocated or null
3063  *  - \a this and \a other do not have the same number of components
3064  *  - if number of components of \a this is not in [1,2,3]
3065  *
3066  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3067  */
3068 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
3069 {
3070   if(!other)
3071     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3072   checkAllocated();
3073   other->checkAllocated();
3074   int nbOfCompo=getNumberOfComponents();
3075   int otherNbOfCompo=other->getNumberOfComponents();
3076   if(nbOfCompo!=otherNbOfCompo)
3077     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3078   int nbOfTuplesOther=other->getNumberOfTuples();
3079   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3080   switch(nbOfCompo)
3081     {
3082     case 3:
3083       {
3084         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3085         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3086         break;
3087       }
3088     case 2:
3089       {
3090         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3091         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3092         break;
3093       }
3094     case 1:
3095       {
3096         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3097         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3098         break;
3099       }
3100     default:
3101       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3102     }
3103   c=cArr.retn(); cI=cIArr.retn();
3104 }
3105
3106 /*!
3107  * 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
3108  * around origin of 'radius' 1.
3109  * 
3110  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3111  */
3112 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
3113 {
3114   checkAllocated();
3115   int dim=getNumberOfComponents();
3116   std::vector<double> bounds(2*dim);
3117   getMinMaxPerComponent(&bounds[0]);
3118   for(int i=0;i<dim;i++)
3119     {
3120       double delta=bounds[2*i+1]-bounds[2*i];
3121       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3122       if(delta>eps)
3123         applyLin(1./delta,-offset/delta,i);
3124       else
3125         applyLin(1.,-offset,i);
3126     }
3127 }
3128
3129 /*!
3130  * Returns the maximal value and its location within \a this one-dimensional array.
3131  *  \param [out] tupleId - index of the tuple holding the maximal value.
3132  *  \return double - the maximal value among all values of \a this array.
3133  *  \throw If \a this->getNumberOfComponents() != 1
3134  *  \throw If \a this->getNumberOfTuples() < 1
3135  */
3136 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3137 {
3138   checkAllocated();
3139   if(getNumberOfComponents()!=1)
3140     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 !");
3141   int nbOfTuples=getNumberOfTuples();
3142   if(nbOfTuples<=0)
3143     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3144   const double *vals=getConstPointer();
3145   const double *loc=std::max_element(vals,vals+nbOfTuples);
3146   tupleId=(int)std::distance(vals,loc);
3147   return *loc;
3148 }
3149
3150 /*!
3151  * Returns the maximal value within \a this array that is allowed to have more than
3152  *  one component.
3153  *  \return double - the maximal value among all values of \a this array.
3154  *  \throw If \a this is not allocated.
3155  */
3156 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
3157 {
3158   checkAllocated();
3159   const double *loc=std::max_element(begin(),end());
3160   return *loc;
3161 }
3162
3163 /*!
3164  * Returns the maximal value and all its locations within \a this one-dimensional array.
3165  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3166  *               tuples holding the maximal value. The caller is to delete it using
3167  *               decrRef() as it is no more needed.
3168  *  \return double - the maximal value among all values of \a this array.
3169  *  \throw If \a this->getNumberOfComponents() != 1
3170  *  \throw If \a this->getNumberOfTuples() < 1
3171  */
3172 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3173 {
3174   int tmp;
3175   tupleIds=0;
3176   double ret=getMaxValue(tmp);
3177   tupleIds=getIdsInRange(ret,ret);
3178   return ret;
3179 }
3180
3181 /*!
3182  * Returns the minimal value and its location within \a this one-dimensional array.
3183  *  \param [out] tupleId - index of the tuple holding the minimal value.
3184  *  \return double - the minimal value among all values of \a this array.
3185  *  \throw If \a this->getNumberOfComponents() != 1
3186  *  \throw If \a this->getNumberOfTuples() < 1
3187  */
3188 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3189 {
3190   checkAllocated();
3191   if(getNumberOfComponents()!=1)
3192     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3193   int nbOfTuples=getNumberOfTuples();
3194   if(nbOfTuples<=0)
3195     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3196   const double *vals=getConstPointer();
3197   const double *loc=std::min_element(vals,vals+nbOfTuples);
3198   tupleId=(int)std::distance(vals,loc);
3199   return *loc;
3200 }
3201
3202 /*!
3203  * Returns the minimal value within \a this array that is allowed to have more than
3204  *  one component.
3205  *  \return double - the minimal value among all values of \a this array.
3206  *  \throw If \a this is not allocated.
3207  */
3208 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3209 {
3210   checkAllocated();
3211   const double *loc=std::min_element(begin(),end());
3212   return *loc;
3213 }
3214
3215 /*!
3216  * Returns the minimal value and all its locations within \a this one-dimensional array.
3217  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3218  *               tuples holding the minimal value. The caller is to delete it using
3219  *               decrRef() as it is no more needed.
3220  *  \return double - the minimal value among all values of \a this array.
3221  *  \throw If \a this->getNumberOfComponents() != 1
3222  *  \throw If \a this->getNumberOfTuples() < 1
3223  */
3224 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3225 {
3226   int tmp;
3227   tupleIds=0;
3228   double ret=getMinValue(tmp);
3229   tupleIds=getIdsInRange(ret,ret);
3230   return ret;
3231 }
3232
3233 /*!
3234  * 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.
3235  * This method only works for single component array.
3236  *
3237  * \return a value in [ 0, \c this->getNumberOfTuples() )
3238  *
3239  * \throw If \a this is not allocated
3240  *
3241  */
3242 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3243 {
3244   int ret=0;
3245   checkAllocated();
3246   if(getNumberOfComponents()!=1)
3247     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3248   const double *vals=begin();
3249   int nbOfTuples=getNumberOfTuples();
3250   for(int i=0;i<nbOfTuples;i++,vals++)
3251     if(fabs(*vals-value)<=eps)
3252       ret++;
3253   return ret;
3254 }
3255
3256 /*!
3257  * Returns the average value of \a this one-dimensional array.
3258  *  \return double - the average value over all values of \a this array.
3259  *  \throw If \a this->getNumberOfComponents() != 1
3260  *  \throw If \a this->getNumberOfTuples() < 1
3261  */
3262 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3263 {
3264   if(getNumberOfComponents()!=1)
3265     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3266   int nbOfTuples=getNumberOfTuples();
3267   if(nbOfTuples<=0)
3268     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3269   const double *vals=getConstPointer();
3270   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3271   return ret/nbOfTuples;
3272 }
3273
3274 /*!
3275  * Returns the Euclidean norm of the vector defined by \a this array.
3276  *  \return double - the value of the Euclidean norm, i.e.
3277  *          the square root of the inner product of vector.
3278  *  \throw If \a this is not allocated.
3279  */
3280 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3281 {
3282   checkAllocated();
3283   double ret=0.;
3284   std::size_t nbOfElems=getNbOfElems();
3285   const double *pt=getConstPointer();
3286   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3287     ret+=(*pt)*(*pt);
3288   return sqrt(ret);
3289 }
3290
3291 /*!
3292  * Returns the maximum norm of the vector defined by \a this array.
3293  *  \return double - the value of the maximum norm, i.e.
3294  *          the maximal absolute value among values of \a this array.
3295  *  \throw If \a this is not allocated.
3296  */
3297 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3298 {
3299   checkAllocated();
3300   double ret=-1.;
3301   std::size_t nbOfElems=getNbOfElems();
3302   const double *pt=getConstPointer();
3303   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3304     {
3305       double val=std::abs(*pt);
3306       if(val>ret)
3307         ret=val;
3308     }
3309   return ret;
3310 }
3311
3312 /*!
3313  * Accumulates values of each component of \a this array.
3314  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3315  *         by the caller, that is filled by this method with sum value for each
3316  *         component.
3317  *  \throw If \a this is not allocated.
3318  */
3319 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3320 {
3321   checkAllocated();
3322   const double *ptr=getConstPointer();
3323   int nbTuple=getNumberOfTuples();
3324   int nbComps=getNumberOfComponents();
3325   std::fill(res,res+nbComps,0.);
3326   for(int i=0;i<nbTuple;i++)
3327     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3328 }
3329
3330 /*!
3331  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3332  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3333  *
3334  *
3335  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3336  * \a tupleEnd. If not an exception will be thrown.
3337  *
3338  * \param [in] tupleBg start pointer (included) of input external tuple
3339  * \param [in] tupleEnd end pointer (not included) of input external tuple
3340  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3341  * \return the min distance.
3342  * \sa MEDCouplingUMesh::distanceToPoint
3343  */
3344 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3345 {
3346   checkAllocated();
3347   int nbTuple=getNumberOfTuples();
3348   int nbComps=getNumberOfComponents();
3349   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3350     { 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()); }
3351   if(nbTuple==0)
3352     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3353   double ret0=std::numeric_limits<double>::max();
3354   tupleId=-1;
3355   const double *work=getConstPointer();
3356   for(int i=0;i<nbTuple;i++)
3357     {
3358       double val=0.;
3359       for(int j=0;j<nbComps;j++,work++) 
3360         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3361       if(val>=ret0)
3362         continue;
3363       else
3364         { ret0=val; tupleId=i; }
3365     }
3366   return sqrt(ret0);
3367 }
3368
3369 /*!
3370  * Accumulate values of the given component of \a this array.
3371  *  \param [in] compId - the index of the component of interest.
3372  *  \return double - a sum value of \a compId-th component.
3373  *  \throw If \a this is not allocated.
3374  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3375  *         not respected.
3376  */
3377 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3378 {
3379   checkAllocated();
3380   const double *ptr=getConstPointer();
3381   int nbTuple=getNumberOfTuples();
3382   int nbComps=getNumberOfComponents();
3383   if(compId<0 || compId>=nbComps)
3384     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3385   double ret=0.;
3386   for(int i=0;i<nbTuple;i++)
3387     ret+=ptr[i*nbComps+compId];
3388   return ret;
3389 }
3390
3391 /*!
3392  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3393  * The returned array will have same number of components than \a this and number of tuples equal to
3394  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3395  *
3396  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3397  * 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.
3398  *
3399  * \param [in] bgOfIndex - begin (included) of the input index array.
3400  * \param [in] endOfIndex - end (excluded) of the input index array.
3401  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3402  * 
3403  * \throw If bgOfIndex or end is NULL.
3404  * \throw If input index array is not ascendingly sorted.
3405  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3406  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3407  */
3408 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3409 {
3410   if(!bgOfIndex || !endOfIndex)
3411     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3412   checkAllocated();
3413   int nbCompo=getNumberOfComponents();
3414   int nbOfTuples=getNumberOfTuples();
3415   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3416   if(sz<1)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3418   sz--;
3419   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3420   const int *w=bgOfIndex;
3421   if(*w<0 || *w>=nbOfTuples)
3422     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3423   const double *srcPt=begin()+(*w)*nbCompo;
3424   double *tmp=ret->getPointer();
3425   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3426     {
3427       std::fill(tmp,tmp+nbCompo,0.);
3428       if(w[1]>=w[0])
3429         {
3430           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3431             {
3432               if(j>=0 && j<nbOfTuples)
3433                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3434               else
3435                 {
3436                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3437                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3438                 }
3439             }
3440         }
3441       else
3442         {
3443           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3444           throw INTERP_KERNEL::Exception(oss.str().c_str());
3445         }
3446     }
3447   ret->copyStringInfoFrom(*this);
3448   return ret.retn();
3449 }
3450
3451 /*!
3452  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3453  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3454  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3455  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3456  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3457  *          is to delete this array using decrRef() as it is no more needed. The array
3458  *          does not contain any textual info on components.
3459  *  \throw If \a this->getNumberOfComponents() != 2.
3460  */
3461 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3462 {
3463   checkAllocated();
3464   int nbOfComp=getNumberOfComponents();
3465   if(nbOfComp!=2)
3466     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3467   int nbOfTuple=getNumberOfTuples();
3468   DataArrayDouble *ret=DataArrayDouble::New();
3469   ret->alloc(nbOfTuple,2);
3470   double *w=ret->getPointer();
3471   const double *wIn=getConstPointer();
3472   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3473     {
3474       w[0]=wIn[0]*cos(wIn[1]);
3475       w[1]=wIn[0]*sin(wIn[1]);
3476     }
3477   return ret;
3478 }
3479
3480 /*!
3481  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3482  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3483  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3484  * the Cylindrical CS.
3485  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3486  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3487  *          on the third component is copied from \a this array. The caller
3488  *          is to delete this array using decrRef() as it is no more needed. 
3489  *  \throw If \a this->getNumberOfComponents() != 3.
3490  */
3491 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3492 {
3493   checkAllocated();
3494   int nbOfComp=getNumberOfComponents();
3495   if(nbOfComp!=3)
3496     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3497   int nbOfTuple=getNumberOfTuples();
3498   DataArrayDouble *ret=DataArrayDouble::New();
3499   ret->alloc(getNumberOfTuples(),3);
3500   double *w=ret->getPointer();
3501   const double *wIn=getConstPointer();
3502   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3503     {
3504       w[0]=wIn[0]*cos(wIn[1]);
3505       w[1]=wIn[0]*sin(wIn[1]);
3506       w[2]=wIn[2];
3507     }
3508   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3509   return ret;
3510 }
3511
3512 /*!
3513  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3514  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3515  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3516  * point in the Cylindrical CS.
3517  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3518  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3519  *          on the third component is copied from \a this array. The caller
3520  *          is to delete this array using decrRef() as it is no more needed.
3521  *  \throw If \a this->getNumberOfComponents() != 3.
3522  */
3523 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3524 {
3525   checkAllocated();
3526   int nbOfComp=getNumberOfComponents();
3527   if(nbOfComp!=3)
3528     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3529   int nbOfTuple=getNumberOfTuples();
3530   DataArrayDouble *ret=DataArrayDouble::New();
3531   ret->alloc(getNumberOfTuples(),3);
3532   double *w=ret->getPointer();
3533   const double *wIn=getConstPointer();
3534   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3535     {
3536       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3537       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3538       w[2]=wIn[0]*cos(wIn[1]);
3539     }
3540   return ret;
3541 }
3542
3543 /*!
3544  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3545  * array contating 6 components.
3546  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3547  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3548  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3549  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3550  *  \throw If \a this->getNumberOfComponents() != 6.
3551  */
3552 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3553 {
3554   checkAllocated();
3555   int nbOfComp=getNumberOfComponents();
3556   if(nbOfComp!=6)
3557     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3558   DataArrayDouble *ret=DataArrayDouble::New();
3559   int nbOfTuple=getNumberOfTuples();
3560   ret->alloc(nbOfTuple,1);
3561   const double *src=getConstPointer();
3562   double *dest=ret->getPointer();
3563   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3564     *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];
3565   return ret;
3566 }
3567
3568 /*!
3569  * Computes the determinant of every square matrix defined by the tuple of \a this
3570  * array, which contains either 4, 6 or 9 components. The case of 6 components
3571  * corresponds to that of the upper triangular matrix.
3572  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3573  *          is the determinant of matrix of the corresponding tuple of \a this array.
3574  *          The caller is to delete this result array using decrRef() as it is no more
3575  *          needed. 
3576  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3577  */
3578 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3579 {
3580   checkAllocated();
3581   DataArrayDouble *ret=DataArrayDouble::New();
3582   int nbOfTuple=getNumberOfTuples();
3583   ret->alloc(nbOfTuple,1);
3584   const double *src=getConstPointer();
3585   double *dest=ret->getPointer();
3586   switch(getNumberOfComponents())
3587     {
3588     case 6:
3589       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3590         *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];
3591       return ret;
3592     case 4:
3593       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3594         *dest=src[0]*src[3]-src[1]*src[2];
3595       return ret;
3596     case 9:
3597       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3598         *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];
3599       return ret;
3600     default:
3601       ret->decrRef();
3602       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3603     }
3604 }
3605
3606 /*!
3607  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3608  * \a this array, which contains 6 components.
3609  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3610  *          components, whose each tuple contains the eigenvalues of the matrix of
3611  *          corresponding tuple of \a this array. 
3612  *          The caller is to delete this result array using decrRef() as it is no more
3613  *          needed. 
3614  *  \throw If \a this->getNumberOfComponents() != 6.
3615  */
3616 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3617 {
3618   checkAllocated();
3619   int nbOfComp=getNumberOfComponents();
3620   if(nbOfComp!=6)
3621     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3622   DataArrayDouble *ret=DataArrayDouble::New();
3623   int nbOfTuple=getNumberOfTuples();
3624   ret->alloc(nbOfTuple,3);
3625   const double *src=getConstPointer();
3626   double *dest=ret->getPointer();
3627   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3628     INTERP_KERNEL::computeEigenValues6(src,dest);
3629   return ret;
3630 }
3631
3632 /*!
3633  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3634  * \a this array, which contains 6 components.
3635  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3636  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3637  *          corresponding tuple of \a this array.
3638  *          The caller is to delete this result array using decrRef() as it is no more
3639  *          needed.
3640  *  \throw If \a this->getNumberOfComponents() != 6.
3641  */
3642 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3643 {
3644   checkAllocated();
3645   int nbOfComp=getNumberOfComponents();
3646   if(nbOfComp!=6)
3647     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3648   DataArrayDouble *ret=DataArrayDouble::New();
3649   int nbOfTuple=getNumberOfTuples();
3650   ret->alloc(nbOfTuple,9);
3651   const double *src=getConstPointer();
3652   double *dest=ret->getPointer();
3653   for(int i=0;i<nbOfTuple;i++,src+=6)
3654     {
3655       double tmp[3];
3656       INTERP_KERNEL::computeEigenValues6(src,tmp);
3657       for(int j=0;j<3;j++,dest+=3)
3658         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3659     }
3660   return ret;
3661 }
3662
3663 /*!
3664  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3665  * array, which contains either 4, 6 or 9 components. The case of 6 components
3666  * corresponds to that of the upper triangular matrix.
3667  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3668  *          same number of components as \a this one, whose each tuple is the inverse
3669  *          matrix of the matrix of corresponding tuple of \a this array. 
3670  *          The caller is to delete this result array using decrRef() as it is no more
3671  *          needed. 
3672  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3673  */
3674 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3675 {
3676   checkAllocated();
3677   int nbOfComp=getNumberOfComponents();
3678   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3679     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3680   DataArrayDouble *ret=DataArrayDouble::New();
3681   int nbOfTuple=getNumberOfTuples();
3682   ret->alloc(nbOfTuple,nbOfComp);
3683   const double *src=getConstPointer();
3684   double *dest=ret->getPointer();
3685 if(nbOfComp==6)
3686     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3687       {
3688         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];
3689         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3690         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3691         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3692         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3693         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3694         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3695       }
3696   else if(nbOfComp==4)
3697     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3698       {
3699         double det=src[0]*src[3]-src[1]*src[2];
3700         dest[0]=src[3]/det;
3701         dest[1]=-src[1]/det;
3702         dest[2]=-src[2]/det;
3703         dest[3]=src[0]/det;
3704       }
3705   else
3706     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3707       {
3708         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];
3709         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3710         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3711         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3712         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3713         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3714         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3715         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3716         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3717         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3718       }
3719   return ret;
3720 }
3721
3722 /*!
3723  * Computes the trace of every matrix defined by the tuple of \a this
3724  * array, which contains either 4, 6 or 9 components. The case of 6 components
3725  * corresponds to that of the upper triangular matrix.
3726  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3727  *          1 component, whose each tuple is the trace of
3728  *          the matrix of corresponding tuple of \a this array. 
3729  *          The caller is to delete this result array using decrRef() as it is no more
3730  *          needed. 
3731  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3732  */
3733 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3734 {
3735   checkAllocated();
3736   int nbOfComp=getNumberOfComponents();
3737   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3738     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3739   DataArrayDouble *ret=DataArrayDouble::New();
3740   int nbOfTuple=getNumberOfTuples();
3741   ret->alloc(nbOfTuple,1);
3742   const double *src=getConstPointer();
3743   double *dest=ret->getPointer();
3744   if(nbOfComp==6)
3745     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3746       *dest=src[0]+src[1]+src[2];
3747   else if(nbOfComp==4)
3748     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3749       *dest=src[0]+src[3];
3750   else
3751     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3752       *dest=src[0]+src[4]+src[8];
3753   return ret;
3754 }
3755
3756 /*!
3757  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3758  * \a this array, which contains 6 components.
3759  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3760  *          same number of components and tuples as \a this array.
3761  *          The caller is to delete this result array using decrRef() as it is no more
3762  *          needed.
3763  *  \throw If \a this->getNumberOfComponents() != 6.
3764  */
3765 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3766 {
3767   checkAllocated();
3768   int nbOfComp=getNumberOfComponents();
3769   if(nbOfComp!=6)
3770     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3771   DataArrayDouble *ret=DataArrayDouble::New();
3772   int nbOfTuple=getNumberOfTuples();
3773   ret->alloc(nbOfTuple,6);
3774   const double *src=getConstPointer();
3775   double *dest=ret->getPointer();
3776   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3777     {
3778       double tr=(src[0]+src[1]+src[2])/3.;
3779       dest[0]=src[0]-tr;
3780       dest[1]=src[1]-tr;
3781       dest[2]=src[2]-tr;
3782       dest[3]=src[3];
3783       dest[4]=src[4];
3784       dest[5]=src[5];
3785     }
3786   return ret;
3787 }
3788
3789 /*!
3790  * Computes the magnitude of every vector defined by the tuple of
3791  * \a this array.
3792  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3793  *          same number of tuples as \a this array and one component.
3794  *          The caller is to delete this result array using decrRef() as it is no more
3795  *          needed.
3796  *  \throw If \a this is not allocated.
3797  */
3798 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3799 {
3800   checkAllocated();
3801   int nbOfComp=getNumberOfComponents();
3802   DataArrayDouble *ret=DataArrayDouble::New();
3803   int nbOfTuple=getNumberOfTuples();
3804   ret->alloc(nbOfTuple,1);
3805   const double *src=getConstPointer();
3806   double *dest=ret->getPointer();
3807   for(int i=0;i<nbOfTuple;i++,dest++)
3808     {
3809       double sum=0.;
3810       for(int j=0;j<nbOfComp;j++,src++)
3811         sum+=(*src)*(*src);
3812       *dest=sqrt(sum);
3813     }
3814   return ret;
3815 }
3816
3817 /*!
3818  * Computes the maximal value within every tuple of \a this array.
3819  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3820  *          same number of tuples as \a this array and one component.
3821  *          The caller is to delete this result array using decrRef() as it is no more
3822  *          needed.
3823  *  \throw If \a this is not allocated.
3824  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3825  */
3826 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3827 {
3828   checkAllocated();
3829   int nbOfComp=getNumberOfComponents();
3830   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3831   int nbOfTuple=getNumberOfTuples();
3832   ret->alloc(nbOfTuple,1);
3833   const double *src=getConstPointer();
3834   double *dest=ret->getPointer();
3835   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3836     *dest=*std::max_element(src,src+nbOfComp);
3837   return ret.retn();
3838 }
3839
3840 /*!
3841  * Computes the maximal value within every tuple of \a this array and it returns the first component
3842  * id for each tuple that corresponds to the maximal value within the tuple.
3843  * 
3844  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3845  *          same number of tuples and only one component.
3846  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3847  *          same number of tuples as \a this array and one component.
3848  *          The caller is to delete this result array using decrRef() as it is no more
3849  *          needed.
3850  *  \throw If \a this is not allocated.
3851  *  \sa DataArrayDouble::maxPerTuple
3852  */
3853 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3854 {
3855   checkAllocated();
3856   int nbOfComp=getNumberOfComponents();
3857   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3858   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3859   int nbOfTuple=getNumberOfTuples();
3860   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3861   const double *src=getConstPointer();
3862   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3863   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3864     {
3865       const double *loc=std::max_element(src,src+nbOfComp);
3866       *dest=*loc;
3867       *dest1=(int)std::distance(src,loc);
3868     }
3869   compoIdOfMaxPerTuple=ret1.retn();
3870   return ret0.retn();
3871 }
3872
3873 /*!
3874  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3875  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3876  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3877  * \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)
3878  *
3879  * \warning use this method with care because it can leads to big amount of consumed memory !
3880  * 
3881  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3882  *
3883  * \throw If \a this is not allocated.
3884  *
3885  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3886  */
3887 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3888 {
3889   checkAllocated();
3890   int nbOfComp=getNumberOfComponents();
3891   int nbOfTuples=getNumberOfTuples();
3892   const double *inData=getConstPointer();
3893   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3894   ret->alloc(nbOfTuples*nbOfTuples,1);
3895   double *outData=ret->getPointer();
3896   for(int i=0;i<nbOfTuples;i++)
3897     {
3898       outData[i*nbOfTuples+i]=0.;
3899       for(int j=i+1;j<nbOfTuples;j++)
3900         {
3901           double dist=0.;
3902           for(int k=0;k<nbOfComp;k++)
3903             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3904           dist=sqrt(dist);
3905           outData[i*nbOfTuples+j]=dist;
3906           outData[j*nbOfTuples+i]=dist;
3907         }
3908     }
3909   return ret.retn();
3910 }
3911
3912 /*!
3913  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3914  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3915  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3916  * \n Output rectangular matrix is sorted along rows.
3917  * \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)
3918  *
3919  * \warning use this method with care because it can leads to big amount of consumed memory !
3920  * 
3921  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3922  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3923  *
3924  * \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.
3925  *
3926  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3927  */
3928 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3929 {
3930   if(!other)
3931     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3932   checkAllocated();
3933   other->checkAllocated();
3934   int nbOfComp=getNumberOfComponents();
3935   int otherNbOfComp=other->getNumberOfComponents();
3936   if(nbOfComp!=otherNbOfComp)
3937     {
3938       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3939       throw INTERP_KERNEL::Exception(oss.str().c_str());
3940     }
3941   int nbOfTuples=getNumberOfTuples();
3942   int otherNbOfTuples=other->getNumberOfTuples();
3943   const double *inData=getConstPointer();
3944   const double *inDataOther=other->getConstPointer();
3945   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3946   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3947   double *outData=ret->getPointer();
3948   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3949     {
3950       for(int j=0;j<nbOfTuples;j++)
3951         {
3952           double dist=0.;
3953           for(int k=0;k<nbOfComp;k++)
3954             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3955           dist=sqrt(dist);
3956           outData[i*nbOfTuples+j]=dist;
3957         }
3958     }
3959   return ret.retn();
3960 }
3961
3962 /*!
3963  * Sorts value within every tuple of \a this array.
3964  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3965  *              in descending order.
3966  *  \throw If \a this is not allocated.
3967  */
3968 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3969 {
3970   checkAllocated();
3971   double *pt=getPointer();
3972   int nbOfTuple=getNumberOfTuples();
3973   int nbOfComp=getNumberOfComponents();
3974   if(asc)
3975     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3976       std::sort(pt,pt+nbOfComp);
3977   else
3978     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3979       std::sort(pt,pt+nbOfComp,std::greater<double>());
3980   declareAsNew();
3981 }
3982
3983 /*!
3984  * Converts every value of \a this array to its absolute value.
3985  *  \throw If \a this is not allocated.
3986  */
3987 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3988 {
3989   checkAllocated();
3990   double *ptr=getPointer();
3991   std::size_t nbOfElems=getNbOfElems();
3992   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3993   declareAsNew();
3994 }
3995
3996 /*!
3997  * Apply a liner function to a given component of \a this array, so that
3998  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3999  *  \param [in] a - the first coefficient of the function.
4000  *  \param [in] b - the second coefficient of the function.
4001  *  \param [in] compoId - the index of component to modify.
4002  *  \throw If \a this is not allocated.
4003  */
4004 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
4005 {
4006   checkAllocated();
4007   double *ptr=getPointer()+compoId;
4008   int nbOfComp=getNumberOfComponents();
4009   int nbOfTuple=getNumberOfTuples();
4010   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4011     *ptr=a*(*ptr)+b;
4012   declareAsNew();
4013 }
4014
4015 /*!
4016  * Apply a liner function to all elements of \a this array, so that
4017  * an element _x_ becomes \f$ a * x + b \f$.
4018  *  \param [in] a - the first coefficient of the function.
4019  *  \param [in] b - the second coefficient of the function.
4020  *  \throw If \a this is not allocated.
4021  */
4022 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
4023 {
4024   checkAllocated();
4025   double *ptr=getPointer();
4026   std::size_t nbOfElems=getNbOfElems();
4027   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4028     *ptr=a*(*ptr)+b;
4029   declareAsNew();
4030 }
4031
4032 /*!
4033  * Modify all elements of \a this array, so that
4034  * an element _x_ becomes \f$ numerator / x \f$.
4035  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4036  *           array, all elements processed before detection of the zero element remain
4037  *           modified.
4038  *  \param [in] numerator - the numerator used to modify array elements.
4039  *  \throw If \a this is not allocated.
4040  *  \throw If there is an element equal to 0.0 in \a this array.
4041  */
4042 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
4043 {
4044   checkAllocated();
4045   double *ptr=getPointer();
4046   std::size_t nbOfElems=getNbOfElems();
4047   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4048     {
4049       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4050         {
4051           *ptr=numerator/(*ptr);
4052         }
4053       else
4054         {
4055           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4056           oss << " !";
4057           throw INTERP_KERNEL::Exception(oss.str().c_str());
4058         }
4059     }
4060   declareAsNew();
4061 }
4062
4063 /*!
4064  * Returns a full copy of \a this array except that sign of all elements is reversed.
4065  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4066  *          same number of tuples and component as \a this array.
4067  *          The caller is to delete this result array using decrRef() as it is no more
4068  *          needed.
4069  *  \throw If \a this is not allocated.
4070  */
4071 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
4072 {
4073   checkAllocated();
4074   DataArrayDouble *newArr=DataArrayDouble::New();
4075   int nbOfTuples=getNumberOfTuples();
4076   int nbOfComp=getNumberOfComponents();
4077   newArr->alloc(nbOfTuples,nbOfComp);
4078   const double *cptr=getConstPointer();
4079   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4080   newArr->copyStringInfoFrom(*this);
4081   return newArr;
4082 }
4083
4084 /*!
4085  * Modify all elements of \a this array, so that
4086  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4087  * all values in \a this have to be >= 0 if val is \b not integer.
4088  *  \param [in] val - the value used to apply pow on all array elements.
4089  *  \throw If \a this is not allocated.
4090  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4091  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4092  *           modified.
4093  */
4094 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
4095 {
4096   checkAllocated();
4097   double *ptr=getPointer();
4098   std::size_t nbOfElems=getNbOfElems();
4099   int val2=(int)val;
4100   bool isInt=((double)val2)==val;
4101   if(!isInt)
4102     {
4103       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4104         {
4105           if(*ptr>=0)
4106             *ptr=pow(*ptr,val);
4107           else
4108             {
4109               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4110               throw INTERP_KERNEL::Exception(oss.str().c_str());
4111             }
4112         }
4113     }
4114   else
4115     {
4116       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4117         *ptr=pow(*ptr,val2);
4118     }
4119   declareAsNew();
4120 }
4121
4122 /*!
4123  * Modify all elements of \a this array, so that
4124  * an element _x_ becomes \f$ val ^ x \f$.
4125  *  \param [in] val - the value used to apply pow on all array elements.
4126  *  \throw If \a this is not allocated.
4127  *  \throw If \a val < 0.
4128  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4129  *           array, all elements processed before detection of the zero element remain
4130  *           modified.
4131  */
4132 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
4133 {
4134   checkAllocated();
4135   if(val<0.)
4136     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4137   double *ptr=getPointer();
4138   std::size_t nbOfElems=getNbOfElems();
4139   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4140     *ptr=pow(val,*ptr);
4141   declareAsNew();
4142 }
4143
4144 /*!
4145  * Returns a new DataArrayDouble created from \a this one by applying \a
4146  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4147  * For more info see \ref MEDCouplingArrayApplyFunc
4148  *  \param [in] nbOfComp - number of components in the result array.
4149  *  \param [in] func - the \a FunctionToEvaluate declared as 
4150  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4151  *              where \a pos points to the first component of a tuple of \a this array
4152  *              and \a res points to the first component of a tuple of the result array.
4153  *              Note that length (number of components) of \a pos can differ from
4154  *              that of \a res.
4155  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4156  *          same number of tuples as \a this array.
4157  *          The caller is to delete this result array using decrRef() as it is no more
4158  *          needed.
4159  *  \throw If \a this is not allocated.
4160  *  \throw If \a func returns \a false.
4161  */
4162 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
4163 {
4164   checkAllocated();
4165   DataArrayDouble *newArr=DataArrayDouble::New();
4166   int nbOfTuples=getNumberOfTuples();
4167   int oldNbOfComp=getNumberOfComponents();
4168   newArr->alloc(nbOfTuples,nbOfComp);
4169   const double *ptr=getConstPointer();
4170   double *ptrToFill=newArr->getPointer();
4171   for(int i=0;i<nbOfTuples;i++)
4172     {
4173       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4174         {
4175           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4176           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4177           oss << ") : Evaluation of function failed !";
4178           newArr->decrRef();
4179           throw INTERP_KERNEL::Exception(oss.str().c_str());
4180         }
4181     }
4182   return newArr;
4183 }
4184
4185 /*!
4186  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4187  * tuple of \a this array. Textual data is not copied.
4188  * For more info see \ref MEDCouplingArrayApplyFunc1.
4189  *  \param [in] nbOfComp - number of components in the result array.
4190  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4191  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4192  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4193  *          same number of tuples as \a this array and \a nbOfComp components.
4194  *          The caller is to delete this result array using decrRef() as it is no more
4195  *          needed.
4196  *  \throw If \a this is not allocated.
4197  *  \throw If computing \a func fails.
4198  */
4199 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4200 {
4201   checkAllocated();
4202   INTERP_KERNEL::ExprParser expr(func);
4203   expr.parse();
4204   std::set<std::string> vars;
4205   expr.getTrueSetOfVars(vars);
4206   int oldNbOfComp=getNumberOfComponents();
4207   if((int)vars.size()>oldNbOfComp)
4208     {
4209       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4210       oss << vars.size() << " variables : ";
4211       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4212       throw INTERP_KERNEL::Exception(oss.str().c_str());
4213     }
4214   std::vector<std::string> varsV(vars.begin(),vars.end());
4215   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4216   //
4217   DataArrayDouble *newArr=DataArrayDouble::New();
4218   int nbOfTuples=getNumberOfTuples();
4219   newArr->alloc(nbOfTuples,nbOfComp);
4220   const double *ptr=getConstPointer();
4221   double *ptrToFill=newArr->getPointer();
4222   for(int i=0;i<nbOfTuples;i++)
4223     {
4224       try
4225         {
4226           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4227         }
4228       catch(INTERP_KERNEL::Exception& e)
4229         {
4230           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4231           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4232           oss << ") : Evaluation of function failed !" << e.what();
4233           newArr->decrRef();
4234           throw INTERP_KERNEL::Exception(oss.str().c_str());
4235         }
4236     }
4237   return newArr;
4238 }
4239
4240 /*!
4241  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4242  * tuple of \a this array. Textual data is not copied.
4243  * For more info see \ref MEDCouplingArrayApplyFunc0.
4244  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4245  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4246  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4247  *          same number of tuples and components as \a this array.
4248  *          The caller is to delete this result array using decrRef() as it is no more
4249  *          needed.
4250  *  \throw If \a this is not allocated.
4251  *  \throw If computing \a func fails.
4252  */
4253 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4254 {
4255   checkAllocated();
4256   INTERP_KERNEL::ExprParser expr(func);
4257   expr.parse();
4258   expr.prepareExprEvaluationVec();
4259   //
4260   DataArrayDouble *newArr=DataArrayDouble::New();
4261   int nbOfTuples=getNumberOfTuples();
4262   int nbOfComp=getNumberOfComponents();
4263   newArr->alloc(nbOfTuples,nbOfComp);
4264   const double *ptr=getConstPointer();
4265   double *ptrToFill=newArr->getPointer();
4266   for(int i=0;i<nbOfTuples;i++)
4267     {
4268       try
4269         {
4270           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4271         }
4272       catch(INTERP_KERNEL::Exception& e)
4273         {
4274           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4275           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4276           oss << ") : Evaluation of function failed ! " << e.what();
4277           newArr->decrRef();
4278           throw INTERP_KERNEL::Exception(oss.str().c_str());
4279         }
4280     }
4281   return newArr;
4282 }
4283
4284 /*!
4285  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4286  * tuple of \a this array. Textual data is not copied.
4287  * For more info see \ref MEDCouplingArrayApplyFunc2.
4288  *  \param [in] nbOfComp - number of components in the result array.
4289  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4290  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4291  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4292  *          same number of tuples as \a this array.
4293  *          The caller is to delete this result array using decrRef() as it is no more
4294  *          needed.
4295  *  \throw If \a this is not allocated.
4296  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4297  *  \throw If computing \a func fails.
4298  */
4299 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4300 {
4301   checkAllocated();
4302   INTERP_KERNEL::ExprParser expr(func);
4303   expr.parse();
4304   std::set<std::string> vars;
4305   expr.getTrueSetOfVars(vars);
4306   int oldNbOfComp=getNumberOfComponents();
4307   if((int)vars.size()>oldNbOfComp)
4308     {
4309       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4310       oss << vars.size() << " variables : ";
4311       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4312       throw INTERP_KERNEL::Exception(oss.str().c_str());
4313     }
4314   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4315   //
4316   DataArrayDouble *newArr=DataArrayDouble::New();
4317   int nbOfTuples=getNumberOfTuples();
4318   newArr->alloc(nbOfTuples,nbOfComp);
4319   const double *ptr=getConstPointer();
4320   double *ptrToFill=newArr->getPointer();
4321   for(int i=0;i<nbOfTuples;i++)
4322     {
4323       try
4324         {
4325           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4326         }
4327       catch(INTERP_KERNEL::Exception& e)
4328         {
4329           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4330           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4331           oss << ") : Evaluation of function failed !" << e.what();
4332           newArr->decrRef();
4333           throw INTERP_KERNEL::Exception(oss.str().c_str());
4334         }
4335     }
4336   return newArr;
4337 }
4338
4339 /*!
4340  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4341  * tuple of \a this array. Textual data is not copied.
4342  * For more info see \ref MEDCouplingArrayApplyFunc3.
4343  *  \param [in] nbOfComp - number of components in the result array.
4344  *  \param [in] varsOrder - sequence of vars defining their order.
4345  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4346  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4347  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4348  *          same number of tuples as \a this array.
4349  *          The caller is to delete this result array using decrRef() as it is no more
4350  *          needed.
4351  *  \throw If \a this is not allocated.
4352  *  \throw If \a func contains vars not in \a varsOrder.
4353  *  \throw If computing \a func fails.
4354  */
4355 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4356 {
4357   checkAllocated();
4358   INTERP_KERNEL::ExprParser expr(func);
4359   expr.parse();
4360   std::set<std::string> vars;
4361   expr.getTrueSetOfVars(vars);
4362   int oldNbOfComp=getNumberOfComponents();
4363   if((int)vars.size()>oldNbOfComp)
4364     {
4365       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4366       oss << vars.size() << " variables : ";
4367       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4368       throw INTERP_KERNEL::Exception(oss.str().c_str());
4369     }
4370   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4371   //
4372   DataArrayDouble *newArr=DataArrayDouble::New();
4373   int nbOfTuples=getNumberOfTuples();
4374   newArr->alloc(nbOfTuples,nbOfComp);
4375   const double *ptr=getConstPointer();
4376   double *ptrToFill=newArr->getPointer();
4377   for(int i=0;i<nbOfTuples;i++)
4378     {
4379       try
4380         {
4381           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4382         }
4383       catch(INTERP_KERNEL::Exception& e)
4384         {
4385           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4386           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4387           oss << ") : Evaluation of function failed !" << e.what();
4388           newArr->decrRef();
4389           throw INTERP_KERNEL::Exception(oss.str().c_str());
4390         }
4391     }
4392   return newArr;
4393 }
4394
4395 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4396 {
4397   checkAllocated();
4398   INTERP_KERNEL::ExprParser expr(func);
4399   expr.parse();
4400   char *funcStr=expr.compileX86();
4401   MYFUNCPTR funcPtr;
4402   *((void **)&funcPtr)=funcStr;//he he...
4403   //
4404   double *ptr=getPointer();
4405   int nbOfComp=getNumberOfComponents();
4406   int nbOfTuples=getNumberOfTuples();
4407   int nbOfElems=nbOfTuples*nbOfComp;
4408   for(int i=0;i<nbOfElems;i++,ptr++)
4409     *ptr=funcPtr(*ptr);
4410   declareAsNew();
4411 }
4412
4413 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4414 {
4415   checkAllocated();
4416   INTERP_KERNEL::ExprParser expr(func);
4417   expr.parse();
4418   char *funcStr=expr.compileX86_64();
4419   MYFUNCPTR funcPtr;
4420   *((void **)&funcPtr)=funcStr;//he he...
4421   //
4422   double *ptr=getPointer();
4423   int nbOfComp=getNumberOfComponents();
4424   int nbOfTuples=getNumberOfTuples();
4425   int nbOfElems=nbOfTuples*nbOfComp;
4426   for(int i=0;i<nbOfElems;i++,ptr++)
4427     *ptr=funcPtr(*ptr);
4428   declareAsNew();
4429 }
4430
4431 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4432 {
4433   return new DataArrayDoubleIterator(this);
4434 }
4435
4436 /*!
4437  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4438  * array whose values are within a given range. Textual data is not copied.
4439  *  \param [in] vmin - a lowest acceptable value (included).
4440  *  \param [in] vmax - a greatest acceptable value (included).
4441  *  \return DataArrayInt * - the new instance of DataArrayInt.
4442  *          The caller is to delete this result array using decrRef() as it is no more
4443  *          needed.
4444  *  \throw If \a this->getNumberOfComponents() != 1.
4445  *
4446  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4447  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4448  */
4449 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4450 {
4451   checkAllocated();
4452   if(getNumberOfComponents()!=1)
4453     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4454   const double *cptr=getConstPointer();
4455   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4456   int nbOfTuples=getNumberOfTuples();
4457   for(int i=0;i<nbOfTuples;i++,cptr++)
4458     if(*cptr>=vmin && *cptr<=vmax)
4459       ret->pushBackSilent(i);
4460   return ret.retn();
4461 }
4462
4463 /*!
4464  * Returns a new DataArrayDouble by concatenating two 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] a1 - an array to include in the result array.
4470  *  \param [in] a2 - another array to include in the result array.
4471  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4472  *          The caller is to delete this result array using decrRef() as it is no more
4473  *          needed.
4474  *  \throw If both \a a1 and \a a2 are NULL.
4475  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4476  */
4477 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4478 {
4479   std::vector<const DataArrayDouble *> tmp(2);
4480   tmp[0]=a1; tmp[1]=a2;
4481   return Aggregate(tmp);
4482 }
4483
4484 /*!
4485  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4486  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4487  * the number of component in the result array is same as that of each of given arrays.
4488  * Info on components is copied from the first of the given arrays. Number of components
4489  * in the given arrays must be  the same.
4490  *  \param [in] arr - a sequence of arrays to include in the result array.
4491  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4492  *          The caller is to delete this result array using decrRef() as it is no more
4493  *          needed.
4494  *  \throw If all arrays within \a arr are NULL.
4495  *  \throw If getNumberOfComponents() of arrays within \a arr.
4496  */
4497 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4498 {
4499   std::vector<const DataArrayDouble *> a;
4500   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4501     if(*it4)
4502       a.push_back(*it4);
4503   if(a.empty())
4504     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4505   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4506   int nbOfComp=(*it)->getNumberOfComponents();
4507   int nbt=(*it++)->getNumberOfTuples();
4508   for(int i=1;it!=a.end();it++,i++)
4509     {
4510       if((*it)->getNumberOfComponents()!=nbOfComp)
4511         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4512       nbt+=(*it)->getNumberOfTuples();
4513     }
4514   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4515   ret->alloc(nbt,nbOfComp);
4516   double *pt=ret->getPointer();
4517   for(it=a.begin();it!=a.end();it++)
4518     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4519   ret->copyStringInfoFrom(*(a[0]));
4520   return ret.retn();
4521 }
4522
4523 /*!
4524  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4525  * of components in the result array is a sum of the number of components of given arrays
4526  * and (2) the number of tuples in the result array is same as that of each of given
4527  * arrays. In other words the i-th tuple of result array includes all components of
4528  * i-th tuples of all given arrays.
4529  * Number of tuples in the given arrays must be  the same.
4530  *  \param [in] a1 - an array to include in the result array.
4531  *  \param [in] a2 - another array to include in the result array.
4532  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4533  *          The caller is to delete this result array using decrRef() as it is no more
4534  *          needed.
4535  *  \throw If both \a a1 and \a a2 are NULL.
4536  *  \throw If any given array is not allocated.
4537  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4538  */
4539 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4540 {
4541   std::vector<const DataArrayDouble *> arr(2);
4542   arr[0]=a1; arr[1]=a2;
4543   return Meld(arr);
4544 }
4545
4546 /*!
4547  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4548  * of components in the result array is a sum of the number of components of given arrays
4549  * and (2) the number of tuples in the result array is same as that of each of given
4550  * arrays. In other words the i-th tuple of result array includes all components of
4551  * i-th tuples of all given arrays.
4552  * Number of tuples in the given arrays must be  the same.
4553  *  \param [in] arr - a sequence of arrays to include in the result array.
4554  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4555  *          The caller is to delete this result array using decrRef() as it is no more
4556  *          needed.
4557  *  \throw If all arrays within \a arr are NULL.
4558  *  \throw If any given array is not allocated.
4559  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4560  */
4561 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4562 {
4563   std::vector<const DataArrayDouble *> a;
4564   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4565     if(*it4)
4566       a.push_back(*it4);
4567   if(a.empty())
4568     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4569   std::vector<const DataArrayDouble *>::const_iterator it;
4570   for(it=a.begin();it!=a.end();it++)
4571     (*it)->checkAllocated();
4572   it=a.begin();
4573   int nbOfTuples=(*it)->getNumberOfTuples();
4574   std::vector<int> nbc(a.size());
4575   std::vector<const double *> pts(a.size());
4576   nbc[0]=(*it)->getNumberOfComponents();
4577   pts[0]=(*it++)->getConstPointer();
4578   for(int i=1;it!=a.end();it++,i++)
4579     {
4580       if(nbOfTuples!=(*it)->getNumberOfTuples())
4581         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4582       nbc[i]=(*it)->getNumberOfComponents();
4583       pts[i]=(*it)->getConstPointer();
4584     }
4585   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4586   DataArrayDouble *ret=DataArrayDouble::New();
4587   ret->alloc(nbOfTuples,totalNbOfComp);
4588   double *retPtr=ret->getPointer();
4589   for(int i=0;i<nbOfTuples;i++)
4590     for(int j=0;j<(int)a.size();j++)
4591       {
4592         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4593         pts[j]+=nbc[j];
4594       }
4595   int k=0;
4596   for(int i=0;i<(int)a.size();i++)
4597     for(int j=0;j<nbc[i];j++,k++)
4598       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4599   return ret;
4600 }
4601
4602 /*!
4603  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4604  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4605  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4606  * Info on components and name is copied from the first of the given arrays.
4607  * Number of tuples and components in the given arrays must be the same.
4608  *  \param [in] a1 - a given array.
4609  *  \param [in] a2 - another given array.
4610  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4611  *          The caller is to delete this result array using decrRef() as it is no more
4612  *          needed.
4613  *  \throw If either \a a1 or \a a2 is NULL.
4614  *  \throw If any given array is not allocated.
4615  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4616  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4617  */
4618 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4619 {
4620   if(!a1 || !a2)
4621     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4622   a1->checkAllocated();
4623   a2->checkAllocated();
4624   int nbOfComp=a1->getNumberOfComponents();
4625   if(nbOfComp!=a2->getNumberOfComponents())
4626     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4627   int nbOfTuple=a1->getNumberOfTuples();
4628   if(nbOfTuple!=a2->getNumberOfTuples())
4629     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4630   DataArrayDouble *ret=DataArrayDouble::New();
4631   ret->alloc(nbOfTuple,1);
4632   double *retPtr=ret->getPointer();
4633   const double *a1Ptr=a1->getConstPointer();
4634   const double *a2Ptr=a2->getConstPointer();
4635   for(int i=0;i<nbOfTuple;i++)
4636     {
4637       double sum=0.;
4638       for(int j=0;j<nbOfComp;j++)
4639         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4640       retPtr[i]=sum;
4641     }
4642   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4643   ret->setName(a1->getName().c_str());
4644   return ret;
4645 }
4646
4647 /*!
4648  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4649  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4650  * product of two vectors defined by the i-th tuples of given arrays.
4651  * Info on components is copied from the first of the given arrays.
4652  * Number of tuples in the given arrays must be the same.
4653  * Number of components in the given arrays must be 3.
4654  *  \param [in] a1 - a given array.
4655  *  \param [in] a2 - another given array.
4656  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4657  *          The caller is to delete this result array using decrRef() as it is no more
4658  *          needed.
4659  *  \throw If either \a a1 or \a a2 is NULL.
4660  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4661  *  \throw If \a a1->getNumberOfComponents() != 3
4662  *  \throw If \a a2->getNumberOfComponents() != 3
4663  */
4664 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4665 {
4666   if(!a1 || !a2)
4667     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4668   int nbOfComp=a1->getNumberOfComponents();
4669   if(nbOfComp!=a2->getNumberOfComponents())
4670     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4671   if(nbOfComp!=3)
4672     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4673   int nbOfTuple=a1->getNumberOfTuples();
4674   if(nbOfTuple!=a2->getNumberOfTuples())
4675     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4676   DataArrayDouble *ret=DataArrayDouble::New();
4677   ret->alloc(nbOfTuple,3);
4678   double *retPtr=ret->getPointer();
4679   const double *a1Ptr=a1->getConstPointer();
4680   const double *a2Ptr=a2->getConstPointer();
4681   for(int i=0;i<nbOfTuple;i++)
4682     {
4683       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4684       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4685       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4686     }
4687   ret->copyStringInfoFrom(*a1);
4688   return ret;
4689 }
4690
4691 /*!
4692  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4693  * Info on components is copied from the first of the given arrays.
4694  * Number of tuples and components in the given arrays must be the same.
4695  *  \param [in] a1 - an array to compare values with another one.
4696  *  \param [in] a2 - another array to compare values with the first one.
4697  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4698  *          The caller is to delete this result array using decrRef() as it is no more
4699  *          needed.
4700  *  \throw If either \a a1 or \a a2 is NULL.
4701  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4702  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4703  */
4704 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4705 {
4706   if(!a1 || !a2)
4707     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4708   int nbOfComp=a1->getNumberOfComponents();
4709   if(nbOfComp!=a2->getNumberOfComponents())
4710     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4711   int nbOfTuple=a1->getNumberOfTuples();
4712   if(nbOfTuple!=a2->getNumberOfTuples())
4713     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4714   DataArrayDouble *ret=DataArrayDouble::New();
4715   ret->alloc(nbOfTuple,nbOfComp);
4716   double *retPtr=ret->getPointer();
4717   const double *a1Ptr=a1->getConstPointer();
4718   const double *a2Ptr=a2->getConstPointer();
4719   int nbElem=nbOfTuple*nbOfComp;
4720   for(int i=0;i<nbElem;i++)
4721     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4722   ret->copyStringInfoFrom(*a1);
4723   return ret;
4724 }
4725
4726 /*!
4727  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4728  * Info on components is copied from the first of the given arrays.
4729  * Number of tuples and components in the given arrays must be the same.
4730  *  \param [in] a1 - an array to compare values with another one.
4731  *  \param [in] a2 - another array to compare values with the first one.
4732  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4733  *          The caller is to delete this result array using decrRef() as it is no more
4734  *          needed.
4735  *  \throw If either \a a1 or \a a2 is NULL.
4736  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4737  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4738  */
4739 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4740 {
4741   if(!a1 || !a2)
4742     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4743   int nbOfComp=a1->getNumberOfComponents();
4744   if(nbOfComp!=a2->getNumberOfComponents())
4745     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4746   int nbOfTuple=a1->getNumberOfTuples();
4747   if(nbOfTuple!=a2->getNumberOfTuples())
4748     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4749   DataArrayDouble *ret=DataArrayDouble::New();
4750   ret->alloc(nbOfTuple,nbOfComp);
4751   double *retPtr=ret->getPointer();
4752   const double *a1Ptr=a1->getConstPointer();
4753   const double *a2Ptr=a2->getConstPointer();
4754   int nbElem=nbOfTuple*nbOfComp;
4755   for(int i=0;i<nbElem;i++)
4756     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4757   ret->copyStringInfoFrom(*a1);
4758   return ret;
4759 }
4760
4761 /*!
4762  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4763  * valid cases.
4764  * 1.  The arrays have same number of tuples and components. Then each value of
4765  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4766  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4767  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4768  *   component. Then
4769  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4770  * 3.  The arrays have same number of components and one array, say _a2_, has one
4771  *   tuple. Then
4772  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4773  *
4774  * Info on components is copied either from the first array (in the first case) or from
4775  * the array with maximal number of elements (getNbOfElems()).
4776  *  \param [in] a1 - an array to sum up.
4777  *  \param [in] a2 - another array to sum up.
4778  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4779  *          The caller is to delete this result array using decrRef() as it is no more
4780  *          needed.
4781  *  \throw If either \a a1 or \a a2 is NULL.
4782  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4783  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4784  *         none of them has number of tuples or components equal to 1.
4785  */
4786 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4787 {
4788   if(!a1 || !a2)
4789     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4790   int nbOfTuple=a1->getNumberOfTuples();
4791   int nbOfTuple2=a2->getNumberOfTuples();
4792   int nbOfComp=a1->getNumberOfComponents();
4793   int nbOfComp2=a2->getNumberOfComponents();
4794   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4795   if(nbOfTuple==nbOfTuple2)
4796     {
4797       if(nbOfComp==nbOfComp2)
4798         {
4799           ret=DataArrayDouble::New();
4800           ret->alloc(nbOfTuple,nbOfComp);
4801           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4802           ret->copyStringInfoFrom(*a1);
4803         }
4804       else
4805         {
4806           int nbOfCompMin,nbOfCompMax;
4807           const DataArrayDouble *aMin, *aMax;
4808           if(nbOfComp>nbOfComp2)
4809             {
4810               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4811               aMin=a2; aMax=a1;
4812             }
4813           else
4814             {
4815               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4816               aMin=a1; aMax=a2;
4817             }
4818           if(nbOfCompMin==1)
4819             {
4820               ret=DataArrayDouble::New();
4821               ret->alloc(nbOfTuple,nbOfCompMax);
4822               const double *aMinPtr=aMin->getConstPointer();
4823               const double *aMaxPtr=aMax->getConstPointer();
4824               double *res=ret->getPointer();
4825               for(int i=0;i<nbOfTuple;i++)
4826                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4827               ret->copyStringInfoFrom(*aMax);
4828             }
4829           else
4830             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4831         }
4832     }
4833   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4834     {
4835       if(nbOfComp==nbOfComp2)
4836         {
4837           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4838           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4839           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4840           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4841           ret=DataArrayDouble::New();
4842           ret->alloc(nbOfTupleMax,nbOfComp);
4843           double *res=ret->getPointer();
4844           for(int i=0;i<nbOfTupleMax;i++)
4845             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4846           ret->copyStringInfoFrom(*aMax);
4847         }
4848       else
4849         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4850     }
4851   else
4852     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4853   return ret.retn();
4854 }
4855
4856 /*!
4857  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4858  * valid cases.
4859  * 1.  The arrays have same number of tuples and components. Then each value of
4860  *   \a other array is added to the corresponding value of \a this array, i.e.:
4861  *   _a_ [ i, j ] += _other_ [ i, j ].
4862  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4863  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4864  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4865  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4866  *
4867  *  \param [in] other - an array to add to \a this one.
4868  *  \throw If \a other is NULL.
4869  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4870  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4871  *         \a other has number of both tuples and components not equal to 1.
4872  */
4873 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4874 {
4875   if(!other)
4876     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4877   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4878   checkAllocated();
4879   other->checkAllocated();
4880   int nbOfTuple=getNumberOfTuples();
4881   int nbOfTuple2=other->getNumberOfTuples();
4882   int nbOfComp=getNumberOfComponents();
4883   int nbOfComp2=other->getNumberOfComponents();
4884   if(nbOfTuple==nbOfTuple2)
4885     {
4886       if(nbOfComp==nbOfComp2)
4887         {
4888           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4889         }
4890       else if(nbOfComp2==1)
4891         {
4892           double *ptr=getPointer();
4893           const double *ptrc=other->getConstPointer();
4894           for(int i=0;i<nbOfTuple;i++)
4895             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4896         }
4897       else
4898         throw INTERP_KERNEL::Exception(msg);
4899     }
4900   else if(nbOfTuple2==1)
4901     {
4902       if(nbOfComp2==nbOfComp)
4903         {
4904           double *ptr=getPointer();
4905           const double *ptrc=other->getConstPointer();
4906           for(int i=0;i<nbOfTuple;i++)
4907             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4908         }
4909       else
4910         throw INTERP_KERNEL::Exception(msg);
4911     }
4912   else
4913     throw INTERP_KERNEL::Exception(msg);
4914   declareAsNew();
4915 }
4916
4917 /*!
4918  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4919  * valid cases.
4920  * 1.  The arrays have same number of tuples and components. Then each value of
4921  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4922  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4923  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4924  *   component. Then
4925  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4926  * 3.  The arrays have same number of components and one array, say _a2_, has one
4927  *   tuple. Then
4928  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4929  *
4930  * Info on components is copied either from the first array (in the first case) or from
4931  * the array with maximal number of elements (getNbOfElems()).
4932  *  \param [in] a1 - an array to subtract from.
4933  *  \param [in] a2 - an array to subtract.
4934  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4935  *          The caller is to delete this result array using decrRef() as it is no more
4936  *          needed.
4937  *  \throw If either \a a1 or \a a2 is NULL.
4938  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4939  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4940  *         none of them has number of tuples or components equal to 1.
4941  */
4942 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4943 {
4944   if(!a1 || !a2)
4945     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4946   int nbOfTuple1=a1->getNumberOfTuples();
4947   int nbOfTuple2=a2->getNumberOfTuples();
4948   int nbOfComp1=a1->getNumberOfComponents();
4949   int nbOfComp2=a2->getNumberOfComponents();
4950   if(nbOfTuple2==nbOfTuple1)
4951     {
4952       if(nbOfComp1==nbOfComp2)
4953         {
4954           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4955           ret->alloc(nbOfTuple2,nbOfComp1);
4956           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4957           ret->copyStringInfoFrom(*a1);
4958           return ret.retn();
4959         }
4960       else if(nbOfComp2==1)
4961         {
4962           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4963           ret->alloc(nbOfTuple1,nbOfComp1);
4964           const double *a2Ptr=a2->getConstPointer();
4965           const double *a1Ptr=a1->getConstPointer();
4966           double *res=ret->getPointer();
4967           for(int i=0;i<nbOfTuple1;i++)
4968             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4969           ret->copyStringInfoFrom(*a1);
4970           return ret.retn();
4971         }
4972       else
4973         {
4974           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4975           return 0;
4976         }
4977     }
4978   else if(nbOfTuple2==1)
4979     {
4980       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4981       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4982       ret->alloc(nbOfTuple1,nbOfComp1);
4983       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4984       double *pt=ret->getPointer();
4985       for(int i=0;i<nbOfTuple1;i++)
4986         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4987       ret->copyStringInfoFrom(*a1);
4988       return ret.retn();
4989     }
4990   else
4991     {
4992       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4993       return 0;
4994     }
4995 }
4996
4997 /*!
4998  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4999  * valid cases.
5000  * 1.  The arrays have same number of tuples and components. Then each value of
5001  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5002  *   _a_ [ i, j ] -= _other_ [ i, j ].
5003  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5004  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5005  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5006  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5007  *
5008  *  \param [in] other - an array to subtract from \a this one.
5009  *  \throw If \a other is NULL.
5010  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5011  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5012  *         \a other has number of both tuples and components not equal to 1.
5013  */
5014 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5015 {
5016   if(!other)
5017     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5018   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5019   checkAllocated();
5020   other->checkAllocated();
5021   int nbOfTuple=getNumberOfTuples();
5022   int nbOfTuple2=other->getNumberOfTuples();
5023   int nbOfComp=getNumberOfComponents();
5024   int nbOfComp2=other->getNumberOfComponents();
5025   if(nbOfTuple==nbOfTuple2)
5026     {
5027       if(nbOfComp==nbOfComp2)
5028         {
5029           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5030         }
5031       else if(nbOfComp2==1)
5032         {
5033           double *ptr=getPointer();
5034           const double *ptrc=other->getConstPointer();
5035           for(int i=0;i<nbOfTuple;i++)
5036             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5037         }
5038       else
5039         throw INTERP_KERNEL::Exception(msg);
5040     }
5041   else if(nbOfTuple2==1)
5042     {
5043       if(nbOfComp2==nbOfComp)
5044         {
5045           double *ptr=getPointer();
5046           const double *ptrc=other->getConstPointer();
5047           for(int i=0;i<nbOfTuple;i++)
5048             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5049         }
5050       else
5051         throw INTERP_KERNEL::Exception(msg);
5052     }
5053   else
5054     throw INTERP_KERNEL::Exception(msg);
5055   declareAsNew();
5056 }
5057
5058 /*!
5059  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5060  * valid cases.
5061  * 1.  The arrays have same number of tuples and components. Then each value of
5062  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5063  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5064  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5065  *   component. Then
5066  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5067  * 3.  The arrays have same number of components and one array, say _a2_, has one
5068  *   tuple. Then
5069  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5070  *
5071  * Info on components is copied either from the first array (in the first case) or from
5072  * the array with maximal number of elements (getNbOfElems()).
5073  *  \param [in] a1 - a factor array.
5074  *  \param [in] a2 - another factor array.
5075  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5076  *          The caller is to delete this result array using decrRef() as it is no more
5077  *          needed.
5078  *  \throw If either \a a1 or \a a2 is NULL.
5079  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5080  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5081  *         none of them has number of tuples or components equal to 1.
5082  */
5083 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5084 {
5085   if(!a1 || !a2)
5086     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5087   int nbOfTuple=a1->getNumberOfTuples();
5088   int nbOfTuple2=a2->getNumberOfTuples();
5089   int nbOfComp=a1->getNumberOfComponents();
5090   int nbOfComp2=a2->getNumberOfComponents();
5091   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5092   if(nbOfTuple==nbOfTuple2)
5093     {
5094       if(nbOfComp==nbOfComp2)
5095         {
5096           ret=DataArrayDouble::New();
5097           ret->alloc(nbOfTuple,nbOfComp);
5098           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5099           ret->copyStringInfoFrom(*a1);
5100         }
5101       else
5102         {
5103           int nbOfCompMin,nbOfCompMax;
5104           const DataArrayDouble *aMin, *aMax;
5105           if(nbOfComp>nbOfComp2)
5106             {
5107               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5108               aMin=a2; aMax=a1;
5109             }
5110           else
5111             {
5112               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5113               aMin=a1; aMax=a2;
5114             }
5115           if(nbOfCompMin==1)
5116             {
5117               ret=DataArrayDouble::New();
5118               ret->alloc(nbOfTuple,nbOfCompMax);
5119               const double *aMinPtr=aMin->getConstPointer();
5120               const double *aMaxPtr=aMax->getConstPointer();
5121               double *res=ret->getPointer();
5122               for(int i=0;i<nbOfTuple;i++)
5123                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5124               ret->copyStringInfoFrom(*aMax);
5125             }
5126           else
5127             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5128         }
5129     }
5130   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5131     {
5132       if(nbOfComp==nbOfComp2)
5133         {
5134           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5135           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5136           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5137           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5138           ret=DataArrayDouble::New();
5139           ret->alloc(nbOfTupleMax,nbOfComp);
5140           double *res=ret->getPointer();
5141           for(int i=0;i<nbOfTupleMax;i++)
5142             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5143           ret->copyStringInfoFrom(*aMax);
5144         }
5145       else
5146         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5147     }
5148   else
5149     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5150   return ret.retn();
5151 }
5152
5153 /*!
5154  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5155  * valid cases.
5156  * 1.  The arrays have same number of tuples and components. Then each value of
5157  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5158  *   _this_ [ i, j ] *= _other_ [ i, j ].
5159  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5160  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5161  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5162  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5163  *
5164  *  \param [in] other - an array to multiply to \a this one.
5165  *  \throw If \a other is NULL.
5166  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5167  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5168  *         \a other has number of both tuples and components not equal to 1.
5169  */
5170 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5171 {
5172   if(!other)
5173     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5174   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5175   checkAllocated();
5176   other->checkAllocated();
5177   int nbOfTuple=getNumberOfTuples();
5178   int nbOfTuple2=other->getNumberOfTuples();
5179   int nbOfComp=getNumberOfComponents();
5180   int nbOfComp2=other->getNumberOfComponents();
5181   if(nbOfTuple==nbOfTuple2)
5182     {
5183       if(nbOfComp==nbOfComp2)
5184         {
5185           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5186         }
5187       else if(nbOfComp2==1)
5188         {
5189           double *ptr=getPointer();
5190           const double *ptrc=other->getConstPointer();
5191           for(int i=0;i<nbOfTuple;i++)
5192             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5193         }
5194       else
5195         throw INTERP_KERNEL::Exception(msg);
5196     }
5197   else if(nbOfTuple2==1)
5198     {
5199       if(nbOfComp2==nbOfComp)
5200         {
5201           double *ptr=getPointer();
5202           const double *ptrc=other->getConstPointer();
5203           for(int i=0;i<nbOfTuple;i++)
5204             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5205         }
5206       else
5207         throw INTERP_KERNEL::Exception(msg);
5208     }
5209   else
5210     throw INTERP_KERNEL::Exception(msg);
5211   declareAsNew();
5212 }
5213
5214 /*!
5215  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5216  * valid cases.
5217  * 1.  The arrays have same number of tuples and components. Then each value of
5218  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5219  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5220  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5221  *   component. Then
5222  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5223  * 3.  The arrays have same number of components and one array, say _a2_, has one
5224  *   tuple. Then
5225  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5226  *
5227  * Info on components is copied either from the first array (in the first case) or from
5228  * the array with maximal number of elements (getNbOfElems()).
5229  *  \warning No check of division by zero is performed!
5230  *  \param [in] a1 - a numerator array.
5231  *  \param [in] a2 - a denominator array.
5232  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5233  *          The caller is to delete this result array using decrRef() as it is no more
5234  *          needed.
5235  *  \throw If either \a a1 or \a a2 is NULL.
5236  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5237  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5238  *         none of them has number of tuples or components equal to 1.
5239  */
5240 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5241 {
5242   if(!a1 || !a2)
5243     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5244   int nbOfTuple1=a1->getNumberOfTuples();
5245   int nbOfTuple2=a2->getNumberOfTuples();
5246   int nbOfComp1=a1->getNumberOfComponents();
5247   int nbOfComp2=a2->getNumberOfComponents();
5248   if(nbOfTuple2==nbOfTuple1)
5249     {
5250       if(nbOfComp1==nbOfComp2)
5251         {
5252           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5253           ret->alloc(nbOfTuple2,nbOfComp1);
5254           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5255           ret->copyStringInfoFrom(*a1);
5256           return ret.retn();
5257         }
5258       else if(nbOfComp2==1)
5259         {
5260           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5261           ret->alloc(nbOfTuple1,nbOfComp1);
5262           const double *a2Ptr=a2->getConstPointer();
5263           const double *a1Ptr=a1->getConstPointer();
5264           double *res=ret->getPointer();
5265           for(int i=0;i<nbOfTuple1;i++)
5266             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5267           ret->copyStringInfoFrom(*a1);
5268           return ret.retn();
5269         }
5270       else
5271         {
5272           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5273           return 0;
5274         }
5275     }
5276   else if(nbOfTuple2==1)
5277     {
5278       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5279       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5280       ret->alloc(nbOfTuple1,nbOfComp1);
5281       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5282       double *pt=ret->getPointer();
5283       for(int i=0;i<nbOfTuple1;i++)
5284         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5285       ret->copyStringInfoFrom(*a1);
5286       return ret.retn();
5287     }
5288   else
5289     {
5290       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5291       return 0;
5292     }
5293 }
5294
5295 /*!
5296  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5297  * valid cases.
5298  * 1.  The arrays have same number of tuples and components. Then each value of
5299  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5300  *   _a_ [ i, j ] /= _other_ [ i, j ].
5301  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5302  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5303  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5304  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5305  *
5306  *  \warning No check of division by zero is performed!
5307  *  \param [in] other - an array to divide \a this one by.
5308  *  \throw If \a other is NULL.
5309  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5310  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5311  *         \a other has number of both tuples and components not equal to 1.
5312  */
5313 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5314 {
5315   if(!other)
5316     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5317   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5318   checkAllocated();
5319   other->checkAllocated();
5320   int nbOfTuple=getNumberOfTuples();
5321   int nbOfTuple2=other->getNumberOfTuples();
5322   int nbOfComp=getNumberOfComponents();
5323   int nbOfComp2=other->getNumberOfComponents();
5324   if(nbOfTuple==nbOfTuple2)
5325     {
5326       if(nbOfComp==nbOfComp2)
5327         {
5328           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5329         }
5330       else if(nbOfComp2==1)
5331         {
5332           double *ptr=getPointer();
5333           const double *ptrc=other->getConstPointer();
5334           for(int i=0;i<nbOfTuple;i++)
5335             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5336         }
5337       else
5338         throw INTERP_KERNEL::Exception(msg);
5339     }
5340   else if(nbOfTuple2==1)
5341     {
5342       if(nbOfComp2==nbOfComp)
5343         {
5344           double *ptr=getPointer();
5345           const double *ptrc=other->getConstPointer();
5346           for(int i=0;i<nbOfTuple;i++)
5347             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5348         }
5349       else
5350         throw INTERP_KERNEL::Exception(msg);
5351     }
5352   else
5353     throw INTERP_KERNEL::Exception(msg);
5354   declareAsNew();
5355 }
5356
5357 /*!
5358  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5359  * valid cases.
5360  *
5361  *  \param [in] a1 - an array to pow up.
5362  *  \param [in] a2 - another array to sum up.
5363  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5364  *          The caller is to delete this result array using decrRef() as it is no more
5365  *          needed.
5366  *  \throw If either \a a1 or \a a2 is NULL.
5367  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5368  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5369  *  \throw If there is a negative value in \a a1.
5370  */
5371 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5372 {
5373   if(!a1 || !a2)
5374     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5375   int nbOfTuple=a1->getNumberOfTuples();
5376   int nbOfTuple2=a2->getNumberOfTuples();
5377   int nbOfComp=a1->getNumberOfComponents();
5378   int nbOfComp2=a2->getNumberOfComponents();
5379   if(nbOfTuple!=nbOfTuple2)
5380     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5381   if(nbOfComp!=1 || nbOfComp2!=1)
5382     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5383   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5384   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5385   double *ptr=ret->getPointer();
5386   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5387     {
5388       if(*ptr1>=0)
5389         {
5390           *ptr=pow(*ptr1,*ptr2);
5391         }
5392       else
5393         {
5394           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5395           throw INTERP_KERNEL::Exception(oss.str().c_str());
5396         }
5397     }
5398   return ret.retn();
5399 }
5400
5401 /*!
5402  * Apply pow on values of another DataArrayDouble to values of \a this one.
5403  *
5404  *  \param [in] other - an array to pow to \a this one.
5405  *  \throw If \a other is NULL.
5406  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5407  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5408  *  \throw If there is a negative value in \a this.
5409  */
5410 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5411 {
5412   if(!other)
5413     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5414   int nbOfTuple=getNumberOfTuples();
5415   int nbOfTuple2=other->getNumberOfTuples();
5416   int nbOfComp=getNumberOfComponents();
5417   int nbOfComp2=other->getNumberOfComponents();
5418   if(nbOfTuple!=nbOfTuple2)
5419     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5420   if(nbOfComp!=1 || nbOfComp2!=1)
5421     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5422   double *ptr=getPointer();
5423   const double *ptrc=other->begin();
5424   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5425     {
5426       if(*ptr>=0)
5427         *ptr=pow(*ptr,*ptrc);
5428       else
5429         {
5430           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5431           throw INTERP_KERNEL::Exception(oss.str().c_str());
5432         }
5433     }
5434   declareAsNew();
5435 }
5436
5437 /*!
5438  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5439  * Server side.
5440  */
5441 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5442 {
5443   tinyInfo.resize(2);
5444   if(isAllocated())
5445     {
5446       tinyInfo[0]=getNumberOfTuples();
5447       tinyInfo[1]=getNumberOfComponents();
5448     }
5449   else
5450     {
5451       tinyInfo[0]=-1;
5452       tinyInfo[1]=-1;
5453     }
5454 }
5455
5456 /*!
5457  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5458  * Server side.
5459  */
5460 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5461 {
5462   if(isAllocated())
5463     {
5464       int nbOfCompo=getNumberOfComponents();
5465       tinyInfo.resize(nbOfCompo+1);
5466       tinyInfo[0]=getName();
5467       for(int i=0;i<nbOfCompo;i++)
5468         tinyInfo[i+1]=getInfoOnComponent(i);
5469     }
5470   else
5471     {
5472       tinyInfo.resize(1);
5473       tinyInfo[0]=getName();
5474     }
5475 }
5476
5477 /*!
5478  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5479  * This method returns if a feeding is needed.
5480  */
5481 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5482 {
5483   int nbOfTuple=tinyInfoI[0];
5484   int nbOfComp=tinyInfoI[1];
5485   if(nbOfTuple!=-1 || nbOfComp!=-1)
5486     {
5487       alloc(nbOfTuple,nbOfComp);
5488       return true;
5489     }
5490   return false;
5491 }
5492
5493 /*!
5494  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5495  */
5496 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5497 {
5498   setName(tinyInfoS[0].c_str());
5499   if(isAllocated())
5500     {
5501       int nbOfCompo=getNumberOfComponents();
5502       for(int i=0;i<nbOfCompo;i++)
5503         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5504     }
5505 }
5506
5507 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5508 {
5509   if(_da)
5510     {
5511       _da->incrRef();
5512       if(_da->isAllocated())
5513         {
5514           _nb_comp=da->getNumberOfComponents();
5515           _nb_tuple=da->getNumberOfTuples();
5516           _pt=da->getPointer();
5517         }
5518     }
5519 }
5520
5521 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5522 {
5523   if(_da)
5524     _da->decrRef();
5525 }
5526
5527 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5528 {
5529   if(_tuple_id<_nb_tuple)
5530     {
5531       _tuple_id++;
5532       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5533       _pt+=_nb_comp;
5534       return ret;
5535     }
5536   else
5537     return 0;
5538 }
5539
5540 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5541 {
5542 }
5543
5544
5545 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5546 {
5547   std::ostringstream oss; oss.precision(17); oss << "(";
5548   for(int i=0;i<_nb_of_compo-1;i++)
5549     oss << _pt[i] << ", ";
5550   oss << _pt[_nb_of_compo-1] << ")";
5551   return oss.str();
5552 }
5553
5554 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5555 {
5556   if(_nb_of_compo==1)
5557     return *_pt;
5558   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5559 }
5560
5561 /*!
5562  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5563  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5564  * 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
5565  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5566  */
5567 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5568 {
5569   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5570     {
5571       DataArrayDouble *ret=DataArrayDouble::New();
5572       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5573       return ret;
5574     }
5575   else
5576     {
5577       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5578       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5579       throw INTERP_KERNEL::Exception(oss.str().c_str());
5580     }
5581 }
5582
5583 /*!
5584  * Returns a new instance of DataArrayInt. The caller is to delete this array
5585  * using decrRef() as it is no more needed. 
5586  */
5587 DataArrayInt *DataArrayInt::New()
5588 {
5589   return new DataArrayInt;
5590 }
5591
5592 /*!
5593  * Checks if raw data is allocated. Read more on the raw data
5594  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5595  *  \return bool - \a true if the raw data is allocated, \a false else.
5596  */
5597 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5598 {
5599   return getConstPointer()!=0;
5600 }
5601
5602 /*!
5603  * Checks if raw data is allocated and throws an exception if it is not the case.
5604  *  \throw If the raw data is not allocated.
5605  */
5606 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5607 {
5608   if(!isAllocated())
5609     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5610 }
5611
5612 /*!
5613  * This method desallocated \a this without modification of informations relative to the components.
5614  * After call of this method, DataArrayInt::isAllocated will return false.
5615  * If \a this is already not allocated, \a this is let unchanged.
5616  */
5617 void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
5618 {
5619   _mem.destroy();
5620 }
5621
5622 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5623 {
5624   std::size_t sz(_mem.getNbOfElemAllocated());
5625   sz*=sizeof(int);
5626   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5627 }
5628
5629 /*!
5630  * Returns the only one value in \a this, if and only if number of elements
5631  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5632  *  \return double - the sole value stored in \a this array.
5633  *  \throw If at least one of conditions stated above is not fulfilled.
5634  */
5635 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5636 {
5637   if(isAllocated())
5638     {
5639       if(getNbOfElems()==1)
5640         {
5641           return *getConstPointer();
5642         }
5643       else
5644         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5645     }
5646   else
5647     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5648 }
5649
5650 /*!
5651  * Returns an integer value characterizing \a this array, which is useful for a quick
5652  * comparison of many instances of DataArrayInt.
5653  *  \return int - the hash value.
5654  *  \throw If \a this is not allocated.
5655  */
5656 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5657 {
5658   checkAllocated();
5659   std::size_t nbOfElems=getNbOfElems();
5660   int ret=nbOfElems*65536;
5661   int delta=3;
5662   if(nbOfElems>48)
5663     delta=nbOfElems/8;
5664   int ret0=0;
5665   const int *pt=begin();
5666   for(std::size_t i=0;i<nbOfElems;i+=delta)
5667     ret0+=pt[i] & 0x1FFF;
5668   return ret+ret0;
5669 }
5670
5671 /*!
5672  * Checks the number of tuples.
5673  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5674  *  \throw If \a this is not allocated.
5675  */
5676 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5677 {
5678   checkAllocated();
5679   return getNumberOfTuples()==0;
5680 }
5681
5682 /*!
5683  * Returns a full copy of \a this. For more info on copying data arrays see
5684  * \ref MEDCouplingArrayBasicsCopyDeep.
5685  *  \return DataArrayInt * - a new instance of DataArrayInt.
5686  */
5687 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5688 {
5689   return new DataArrayInt(*this);
5690 }
5691
5692 /*!
5693  * Returns either a \a deep or \a shallow copy of this array. For more info see
5694  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5695  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5696  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5697  *          == \a true) or \a this instance (if \a dCpy == \a false).
5698  */
5699 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5700 {
5701   if(dCpy)
5702     return deepCpy();
5703   else
5704     {
5705       incrRef();
5706       return const_cast<DataArrayInt *>(this);
5707     }
5708 }
5709
5710 /*!
5711  * Copies all the data from another DataArrayInt. For more info see
5712  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5713  *  \param [in] other - another instance of DataArrayInt to copy data from.
5714  *  \throw If the \a other is not allocated.
5715  */
5716 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5717 {
5718   other.checkAllocated();
5719   int nbOfTuples=other.getNumberOfTuples();
5720   int nbOfComp=other.getNumberOfComponents();
5721   allocIfNecessary(nbOfTuples,nbOfComp);
5722   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5723   int *pt=getPointer();
5724   const int *ptI=other.getConstPointer();
5725   for(std::size_t i=0;i<nbOfElems;i++)
5726     pt[i]=ptI[i];
5727   copyStringInfoFrom(other);
5728 }
5729
5730 /*!
5731  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5732  * 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.
5733  * If \a this has not already been allocated, number of components is set to one.
5734  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5735  * 
5736  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5737  */
5738 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5739 {
5740   int nbCompo=getNumberOfComponents();
5741   if(nbCompo==1)
5742     {
5743       _mem.reserve(nbOfElems);
5744     }
5745   else if(nbCompo==0)
5746     {
5747       _mem.reserve(nbOfElems);
5748       _info_on_compo.resize(1);
5749     }
5750   else
5751     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5752 }
5753
5754 /*!
5755  * 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
5756  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5757  *
5758  * \param [in] val the value to be added in \a this
5759  * \throw If \a this has already been allocated with number of components different from one.
5760  * \sa DataArrayInt::pushBackValsSilent
5761  */
5762 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5763 {
5764   int nbCompo=getNumberOfComponents();
5765   if(nbCompo==1)
5766     _mem.pushBack(val);
5767   else if(nbCompo==0)
5768     {
5769       _info_on_compo.resize(1);
5770       _mem.pushBack(val);
5771     }
5772   else
5773     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5774 }
5775
5776 /*!
5777  * 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
5778  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5779  *
5780  *  \param [in] valsBg - an array of values to push at the end of \this.
5781  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5782  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5783  * \throw If \a this has already been allocated with number of components different from one.
5784  * \sa DataArrayInt::pushBackSilent
5785  */
5786 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5787 {
5788   int nbCompo=getNumberOfComponents();
5789   if(nbCompo==1)
5790     _mem.insertAtTheEnd(valsBg,valsEnd);
5791   else if(nbCompo==0)
5792     {
5793       _info_on_compo.resize(1);
5794       _mem.insertAtTheEnd(valsBg,valsEnd);
5795     }
5796   else
5797     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5798 }
5799
5800 /*!
5801  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5802  * \throw If \a this is already empty.
5803  * \throw If \a this has number of components different from one.
5804  */
5805 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5806 {
5807   if(getNumberOfComponents()==1)
5808     return _mem.popBack();
5809   else
5810     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5811 }
5812
5813 /*!
5814  * 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.
5815  *
5816  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5817  */
5818 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5819 {
5820   _mem.pack();
5821 }
5822
5823 /*!
5824  * Allocates the raw data in memory. If exactly as same memory as needed already
5825  * allocated, it is not re-allocated.
5826  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5827  *  \param [in] nbOfCompo - number of components of data to allocate.
5828  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5829  */
5830 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5831 {
5832   if(isAllocated())
5833     {
5834       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5835         alloc(nbOfTuple,nbOfCompo);
5836     }
5837   else
5838     alloc(nbOfTuple,nbOfCompo);
5839 }
5840
5841 /*!
5842  * Allocates the raw data in memory. If the memory was already allocated, then it is
5843  * freed and re-allocated. See an example of this method use
5844  * \ref MEDCouplingArraySteps1WC "here".
5845  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5846  *  \param [in] nbOfCompo - number of components of data to allocate.
5847  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5848  */
5849 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5850 {
5851   if(nbOfTuple<0 || nbOfCompo<0)
5852     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5853   _info_on_compo.resize(nbOfCompo);
5854   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5855   declareAsNew();
5856 }
5857
5858 /*!
5859  * Assign zero to all values in \a this array. To know more on filling arrays see
5860  * \ref MEDCouplingArrayFill.
5861  * \throw If \a this is not allocated.
5862  */
5863 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5864 {
5865   checkAllocated();
5866   _mem.fillWithValue(0);
5867   declareAsNew();
5868 }
5869
5870 /*!
5871  * Assign \a val to all values in \a this array. To know more on filling arrays see
5872  * \ref MEDCouplingArrayFill.
5873  *  \param [in] val - the value to fill with.
5874  *  \throw If \a this is not allocated.
5875  */
5876 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5877 {
5878   checkAllocated();
5879   _mem.fillWithValue(val);
5880   declareAsNew();
5881 }
5882
5883 /*!
5884  * Set all values in \a this array so that the i-th element equals to \a init + i
5885  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5886  *  \param [in] init - value to assign to the first element of array.
5887  *  \throw If \a this->getNumberOfComponents() != 1
5888  *  \throw If \a this is not allocated.
5889  */
5890 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5891 {
5892   checkAllocated();
5893   if(getNumberOfComponents()!=1)
5894     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5895   int *ptr=getPointer();
5896   int ntuples=getNumberOfTuples();
5897   for(int i=0;i<ntuples;i++)
5898     ptr[i]=init+i;
5899   declareAsNew();
5900 }
5901
5902 /*!
5903  * Returns a textual and human readable representation of \a this instance of
5904  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5905  *  \return std::string - text describing \a this DataArrayInt.
5906  */
5907 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5908 {
5909   std::ostringstream ret;
5910   reprStream(ret);
5911   return ret.str();
5912 }
5913
5914 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5915 {
5916   std::ostringstream ret;
5917   reprZipStream(ret);
5918   return ret.str();
5919 }
5920
5921 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const throw(INTERP_KERNEL::Exception)
5922 {
5923   static const char SPACE[4]={' ',' ',' ',' '};
5924   checkAllocated();
5925   std::string idt(indent,' ');
5926   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5927   if(byteArr)
5928     {
5929       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5930       if(std::string(type)=="Int32")
5931         {
5932           const char *data(reinterpret_cast<const char *>(begin()));
5933           std::size_t sz(getNbOfElems()*sizeof(int));
5934           byteArr->insertAtTheEnd(data,data+sz);
5935           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5936         }
5937       else if(std::string(type)=="Int8")
5938         {
5939           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5940           std::copy(begin(),end(),(char *)tmp);
5941           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5942           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5943         }
5944       else if(std::string(type)=="UInt8")
5945         {
5946           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
5947           std::copy(begin(),end(),(unsigned char *)tmp);
5948           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
5949           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5950         }
5951       else
5952         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
5953     }
5954   else
5955     {
5956       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
5957       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5958     }
5959   ofs << std::endl << idt << "</DataArray>\n";
5960 }
5961
5962 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5963 {
5964   stream << "Name of int array : \"" << _name << "\"\n";
5965   reprWithoutNameStream(stream);
5966 }
5967
5968 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5969 {
5970   stream << "Name of int array : \"" << _name << "\"\n";
5971   reprZipWithoutNameStream(stream);
5972 }
5973
5974 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5975 {
5976   DataArray::reprWithoutNameStream(stream);
5977   _mem.repr(getNumberOfComponents(),stream);
5978 }
5979
5980 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5981 {
5982   DataArray::reprWithoutNameStream(stream);
5983   _mem.reprZip(getNumberOfComponents(),stream);
5984 }
5985
5986 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5987 {
5988   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5989   const int *data=getConstPointer();
5990   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5991   if(nbTuples*nbComp>=1)
5992     {
5993       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5994       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5995       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5996       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5997     }
5998   else
5999     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6000   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6001 }
6002
6003 /*!
6004  * Method that gives a quick overvien of \a this for python.
6005  */
6006 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
6007 {
6008   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6009   stream << "DataArrayInt C++ instance at " << this << ". ";
6010   if(isAllocated())
6011     {
6012       int nbOfCompo=(int)_info_on_compo.size();
6013       if(nbOfCompo>=1)
6014         {
6015           int nbOfTuples=getNumberOfTuples();
6016           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6017           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6018         }
6019       else
6020         stream << "Number of components : 0.";
6021     }
6022   else
6023     stream << "*** No data allocated ****";
6024 }
6025
6026 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
6027 {
6028   const int *data=begin();
6029   int nbOfTuples=getNumberOfTuples();
6030   int nbOfCompo=(int)_info_on_compo.size();
6031   std::ostringstream oss2; oss2 << "[";
6032   std::string oss2Str(oss2.str());
6033   bool isFinished=true;
6034   for(int i=0;i<nbOfTuples && isFinished;i++)
6035     {
6036       if(nbOfCompo>1)
6037         {
6038           oss2 << "(";
6039           for(int j=0;j<nbOfCompo;j++,data++)
6040             {
6041               oss2 << *data;
6042               if(j!=nbOfCompo-1) oss2 << ", ";
6043             }
6044           oss2 << ")";
6045         }
6046       else
6047         oss2 << *data++;
6048       if(i!=nbOfTuples-1) oss2 << ", ";
6049       std::string oss3Str(oss2.str());
6050       if(oss3Str.length()<maxNbOfByteInRepr)
6051         oss2Str=oss3Str;
6052       else
6053         isFinished=false;
6054     }
6055   stream << oss2Str;
6056   if(!isFinished)
6057     stream << "... ";
6058   stream << "]";
6059 }
6060
6061 /*!
6062  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6063  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6064  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6065  *         to \a this array.
6066  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6067  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6068  *  \throw If \a this->getNumberOfComponents() != 1
6069  *  \throw If any value of \a this can't be used as a valid index for 
6070  *         [\a indArrBg, \a indArrEnd).
6071  */
6072 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
6073 {
6074   checkAllocated();
6075   if(getNumberOfComponents()!=1)
6076     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6077   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6078   int nbOfTuples=getNumberOfTuples();
6079   int *pt=getPointer();
6080   for(int i=0;i<nbOfTuples;i++,pt++)
6081     {
6082       if(*pt>=0 && *pt<nbElemsIn)
6083         *pt=indArrBg[*pt];
6084       else
6085         {
6086           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6087           throw INTERP_KERNEL::Exception(oss.str().c_str());
6088         }
6089     }
6090   declareAsNew();
6091 }
6092
6093 /*!
6094  * Computes distribution of values of \a this one-dimensional array between given value
6095  * ranges (casts). This method is typically useful for entity number spliting by types,
6096  * for example. 
6097  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6098  *           check of this is be done. If not, the result is not warranted. 
6099  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6100  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6101  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6102  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6103  *         should be more than every value in \a this array.
6104  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6105  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6106  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6107  *         (same number of tuples and components), the caller is to delete 
6108  *         using decrRef() as it is no more needed.
6109  *         This array contains indices of ranges for every value of \a this array. I.e.
6110  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6111  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6112  *         this in which cast it holds.
6113  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6114  *         array, the caller is to delete using decrRef() as it is no more needed.
6115  *         This array contains ranks of values of \a this array within ranges
6116  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6117  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6118  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6119  *         for each tuple its rank inside its cast. The rank is computed as difference
6120  *         between the value and the lowest value of range.
6121  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6122  *         ranges (casts) to which at least one value of \a this array belongs.
6123  *         Or, in other words, this param contains the casts that \a this contains.
6124  *         The caller is to delete this array using decrRef() as it is no more needed.
6125  *
6126  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6127  *            the output of this method will be : 
6128  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6129  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6130  * - \a castsPresent  : [0,1]
6131  *
6132  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6133  * range #1 and its rank within this range is 2; etc.
6134  *
6135  *  \throw If \a this->getNumberOfComponents() != 1.
6136  *  \throw If \a arrEnd - arrBg < 2.
6137  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6138  */
6139 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6140                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6141 {
6142   checkAllocated();
6143   if(getNumberOfComponents()!=1)
6144     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6145   int nbOfTuples=getNumberOfTuples();
6146   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6147   if(nbOfCast<2)
6148     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6149   nbOfCast--;
6150   const int *work=getConstPointer();
6151   typedef std::reverse_iterator<const int *> rintstart;
6152   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6153   rintstart end2(arrBg);
6154   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6155   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6156   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6157   ret1->alloc(nbOfTuples,1);
6158   ret2->alloc(nbOfTuples,1);
6159   int *ret1Ptr=ret1->getPointer();
6160   int *ret2Ptr=ret2->getPointer();
6161   std::set<std::size_t> castsDetected;
6162   for(int i=0;i<nbOfTuples;i++)
6163     {
6164       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6165       std::size_t pos=std::distance(bg,res);
6166       std::size_t pos2=nbOfCast-pos;
6167       if(pos2<nbOfCast)
6168         {
6169           ret1Ptr[i]=(int)pos2;
6170           ret2Ptr[i]=work[i]-arrBg[pos2];
6171           castsDetected.insert(pos2);
6172         }
6173       else
6174         {
6175           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6176           throw INTERP_KERNEL::Exception(oss.str().c_str());
6177         }
6178     }
6179   ret3->alloc((int)castsDetected.size(),1);
6180   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6181   castArr=ret1.retn();
6182   rankInsideCast=ret2.retn();
6183   castsPresent=ret3.retn();
6184 }
6185
6186 /*!
6187  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6188  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6189  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6190  * new value in place \a indArr[ \a v ] is i.
6191  *  \param [in] indArrBg - the array holding indices within the result array to assign
6192  *         indices of values of \a this array pointing to values of \a indArrBg.
6193  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6194  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6195  *  \return DataArrayInt * - the new instance of DataArrayInt.
6196  *          The caller is to delete this result array using decrRef() as it is no more
6197  *          needed.
6198  *  \throw If \a this->getNumberOfComponents() != 1.
6199  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6200  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6201  */
6202 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
6203 {
6204   checkAllocated();
6205   if(getNumberOfComponents()!=1)
6206     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6207   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6208   int nbOfTuples=getNumberOfTuples();
6209   const int *pt=getConstPointer();
6210   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6211   ret->alloc(nbOfTuples,1);
6212   ret->fillWithValue(-1);
6213   int *tmp=ret->getPointer();
6214   for(int i=0;i<nbOfTuples;i++,pt++)
6215     {
6216       if(*pt>=0 && *pt<nbElemsIn)
6217         {
6218           int pos=indArrBg[*pt];
6219           if(pos>=0 && pos<nbOfTuples)
6220             tmp[pos]=i;
6221           else
6222             {
6223               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6224               throw INTERP_KERNEL::Exception(oss.str().c_str());
6225             }
6226         }
6227       else
6228         {
6229           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6230           throw INTERP_KERNEL::Exception(oss.str().c_str());
6231         }
6232     }
6233   return ret.retn();
6234 }
6235
6236 /*!
6237  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6238  * from values of \a this array, which is supposed to contain a renumbering map in 
6239  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6240  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6241  *  \param [in] newNbOfElem - the number of tuples in the result array.
6242  *  \return DataArrayInt * - the new instance of DataArrayInt.
6243  *          The caller is to delete this result array using decrRef() as it is no more
6244  *          needed.
6245  * 
6246  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6247  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6248  */
6249 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6250 {
6251   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6252   ret->alloc(newNbOfElem,1);
6253   int nbOfOldNodes=getNumberOfTuples();
6254   const int *old2New=getConstPointer();
6255   int *pt=ret->getPointer();
6256   for(int i=0;i!=nbOfOldNodes;i++)
6257     {
6258       int newp(old2New[i]);
6259       if(newp!=-1)
6260         {
6261           if(newp>=0 && newp<newNbOfElem)
6262             pt[newp]=i;
6263           else
6264             {
6265               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6266               throw INTERP_KERNEL::Exception(oss.str().c_str());
6267             }
6268         }
6269     }
6270   return ret.retn();
6271 }
6272
6273 /*!
6274  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6275  * 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]
6276  */
6277 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6278 {
6279   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6280   ret->alloc(newNbOfElem,1);
6281   int nbOfOldNodes=getNumberOfTuples();
6282   const int *old2New=getConstPointer();
6283   int *pt=ret->getPointer();
6284   for(int i=nbOfOldNodes-1;i>=0;i--)
6285     {
6286       int newp(old2New[i]);
6287       if(newp!=-1)
6288         {
6289           if(newp>=0 && newp<newNbOfElem)
6290             pt[newp]=i;
6291           else
6292             {
6293               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6294               throw INTERP_KERNEL::Exception(oss.str().c_str());
6295             }
6296         }
6297     }
6298   return ret.retn();
6299 }
6300
6301 /*!
6302  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6303  * from values of \a this array, which is supposed to contain a renumbering map in 
6304  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6305  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6306  *  \param [in] newNbOfElem - the number of tuples in the result array.
6307  *  \return DataArrayInt * - the new instance of DataArrayInt.
6308  *          The caller is to delete this result array using decrRef() as it is no more
6309  *          needed.
6310  * 
6311  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6312  *
6313  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6314  */
6315 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6316 {
6317   checkAllocated();
6318   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6319   ret->alloc(oldNbOfElem,1);
6320   const int *new2Old=getConstPointer();
6321   int *pt=ret->getPointer();
6322   std::fill(pt,pt+oldNbOfElem,-1);
6323   int nbOfNewElems=getNumberOfTuples();
6324   for(int i=0;i<nbOfNewElems;i++)
6325     {
6326       int v(new2Old[i]);
6327       if(v>=0 && v<oldNbOfElem)
6328          pt[v]=i;
6329       else
6330         {
6331           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6332           throw INTERP_KERNEL::Exception(oss.str().c_str());
6333         }
6334     }
6335   return ret.retn();
6336 }
6337
6338 /*!
6339  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6340  * mismatch is given.
6341  * 
6342  * \param [in] other the instance to be compared with \a this
6343  * \param [out] reason In case of inequality returns the reason.
6344  * \sa DataArrayInt::isEqual
6345  */
6346 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6347 {
6348   if(!areInfoEqualsIfNotWhy(other,reason))
6349     return false;
6350   return _mem.isEqual(other._mem,0,reason);
6351 }
6352
6353 /*!
6354  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6355  * \ref MEDCouplingArrayBasicsCompare.
6356  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6357  *  \return bool - \a true if the two arrays are equal, \a false else.
6358  */
6359 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6360 {
6361   std::string tmp;
6362   return isEqualIfNotWhy(other,tmp);
6363 }
6364
6365 /*!
6366  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6367  * \ref MEDCouplingArrayBasicsCompare.
6368  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6369  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6370  */
6371 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6372 {
6373   std::string tmp;
6374   return _mem.isEqual(other._mem,0,tmp);
6375 }
6376
6377 /*!
6378  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6379  * performed on sorted value sequences.
6380  * For more info see\ref MEDCouplingArrayBasicsCompare.
6381  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6382  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6383  */
6384 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6385 {
6386   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6387   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6388   a->sort();
6389   b->sort();
6390   return a->isEqualWithoutConsideringStr(*b);
6391 }
6392
6393 /*!
6394  * This method compares content of input vector \a v and \a this.
6395  * 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.
6396  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6397  *
6398  * \param [in] v - the vector of 'flags' to be compared with \a this.
6399  *
6400  * \throw If \a this is not sorted ascendingly.
6401  * \throw If \a this has not exactly one component.
6402  * \throw If \a this is not allocated.
6403  */
6404 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception)
6405 {
6406   checkAllocated();
6407   if(getNumberOfComponents()!=1)
6408     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6409   int nbOfTuples(getNumberOfTuples());
6410   const int *w(begin()),*end2(end());
6411   int refVal=-std::numeric_limits<int>::max();
6412   int i=0;
6413   std::vector<bool>::const_iterator it(v.begin());
6414   for(;it!=v.end();it++,i++)
6415     {
6416       if(*it)
6417         {
6418           if(w!=end2)
6419             {
6420               if(*w++==i)
6421                 {
6422                   if(i>refVal)
6423                     refVal=i;
6424                   else
6425                     {
6426                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6427                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6428                     }
6429                 }
6430               else
6431                 return false;
6432             }
6433           else
6434             return false;
6435         }
6436     }
6437   return w==end2;
6438 }
6439
6440 /*!
6441  * Sorts values of the array.
6442  *  \param [in] asc - \a true means ascending order, \a false, descending.
6443  *  \throw If \a this is not allocated.
6444  *  \throw If \a this->getNumberOfComponents() != 1.
6445  */
6446 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6447 {
6448   checkAllocated();
6449   if(getNumberOfComponents()!=1)
6450     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6451   _mem.sort(asc);
6452   declareAsNew();
6453 }
6454
6455 /*!
6456  * Reverse the array values.
6457  *  \throw If \a this->getNumberOfComponents() < 1.
6458  *  \throw If \a this is not allocated.
6459  */
6460 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6461 {
6462   checkAllocated();
6463   _mem.reverse(getNumberOfComponents());
6464   declareAsNew();
6465 }
6466
6467 /*!
6468  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6469  * If not an exception is thrown.
6470  *  \param [in] increasing - if \a true, the array values should be increasing.
6471  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6472  *         increasing arg.
6473  *  \throw If \a this->getNumberOfComponents() != 1.
6474  *  \throw If \a this is not allocated.
6475  */
6476 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6477 {
6478   if(!isMonotonic(increasing))
6479     {
6480       if (increasing)
6481         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6482       else
6483         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6484     }
6485 }
6486
6487 /*!
6488  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6489  *  \param [in] increasing - if \a true, array values should be increasing.
6490  *  \return bool - \a true if values change in accordance with \a increasing arg.
6491  *  \throw If \a this->getNumberOfComponents() != 1.
6492  *  \throw If \a this is not allocated.
6493  */
6494 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6495 {
6496   checkAllocated();
6497   if(getNumberOfComponents()!=1)
6498     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6499   int nbOfElements=getNumberOfTuples();
6500   const int *ptr=getConstPointer();
6501   if(nbOfElements==0)
6502     return true;
6503   int ref=ptr[0];
6504   if(increasing)
6505     {
6506       for(int i=1;i<nbOfElements;i++)
6507         {
6508           if(ptr[i]>=ref)
6509             ref=ptr[i];
6510           else
6511             return false;
6512         }
6513     }
6514   else
6515     {
6516       for(int i=1;i<nbOfElements;i++)
6517         {
6518           if(ptr[i]<=ref)
6519             ref=ptr[i];
6520           else
6521             return false;
6522         }
6523     }
6524   return true;
6525 }
6526
6527 /*!
6528  * This method check that array consistently INCREASING or DECREASING in value.
6529  */
6530 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6531 {
6532   checkAllocated();
6533   if(getNumberOfComponents()!=1)
6534     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6535   int nbOfElements=getNumberOfTuples();
6536   const int *ptr=getConstPointer();
6537   if(nbOfElements==0)
6538     return true;
6539   int ref=ptr[0];
6540   if(increasing)
6541     {
6542       for(int i=1;i<nbOfElements;i++)
6543         {
6544           if(ptr[i]>ref)
6545             ref=ptr[i];
6546           else
6547             return false;
6548         }
6549     }
6550   else
6551     {
6552       for(int i=1;i<nbOfElements;i++)
6553         {
6554           if(ptr[i]<ref)
6555             ref=ptr[i];
6556           else
6557             return false;
6558         }
6559     }
6560   return true;
6561 }
6562
6563 /*!
6564  * This method check that array consistently INCREASING or DECREASING in value.
6565  */
6566 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6567 {
6568   if(!isStrictlyMonotonic(increasing))
6569     {
6570       if (increasing)
6571         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6572       else
6573         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6574     }
6575 }
6576
6577 /*!
6578  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6579  * one-dimensional arrays that must be of the same length. The result array describes
6580  * correspondence between \a this and \a other arrays, so that 
6581  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6582  * not possible because some element in \a other is not in \a this, an exception is thrown.
6583  *  \param [in] other - an array to compute permutation to.
6584  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6585  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6586  * no more needed.
6587  *  \throw If \a this->getNumberOfComponents() != 1.
6588  *  \throw If \a other->getNumberOfComponents() != 1.
6589  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6590  *  \throw If \a other includes a value which is not in \a this array.
6591  * 
6592  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6593  *
6594  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6595  */
6596 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6597 {
6598   checkAllocated();
6599   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6600     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6601   int nbTuple=getNumberOfTuples();
6602   other.checkAllocated();
6603   if(nbTuple!=other.getNumberOfTuples())
6604     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6605   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6606   ret->alloc(nbTuple,1);
6607   ret->fillWithValue(-1);
6608   const int *pt=getConstPointer();
6609   std::map<int,int> mm;
6610   for(int i=0;i<nbTuple;i++)
6611     mm[pt[i]]=i;
6612   pt=other.getConstPointer();
6613   int *retToFill=ret->getPointer();
6614   for(int i=0;i<nbTuple;i++)
6615     {
6616       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6617       if(it==mm.end())
6618         {
6619           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6620           throw INTERP_KERNEL::Exception(oss.str().c_str());
6621         }
6622       retToFill[i]=(*it).second;
6623     }
6624   return ret.retn();
6625 }
6626
6627 /*!
6628  * Sets a C array to be used as raw data of \a this. The previously set info
6629  *  of components is retained and re-sized. 
6630  * For more info see \ref MEDCouplingArraySteps1.
6631  *  \param [in] array - the C array to be used as raw data of \a this.
6632  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6633  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6634  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6635  *                     \c free(\c array ) will be called.
6636  *  \param [in] nbOfTuple - new number of tuples in \a this.
6637  *  \param [in] nbOfCompo - new number of components in \a this.
6638  */
6639 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6640 {
6641   _info_on_compo.resize(nbOfCompo);
6642   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6643   declareAsNew();
6644 }
6645
6646 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6647 {
6648   _info_on_compo.resize(nbOfCompo);
6649   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6650   declareAsNew();
6651 }
6652
6653 /*!
6654  * Returns a new DataArrayInt holding the same values as \a this array but differently
6655  * arranged in memory. If \a this array holds 2 components of 3 values:
6656  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6657  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6658  *  \warning Do not confuse this method with transpose()!
6659  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6660  *          is to delete using decrRef() as it is no more needed.
6661  *  \throw If \a this is not allocated.
6662  */
6663 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6664 {
6665   checkAllocated();
6666   if(_mem.isNull())
6667     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6668   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6669   DataArrayInt *ret=DataArrayInt::New();
6670   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6671   return ret;
6672 }
6673
6674 /*!
6675  * Returns a new DataArrayInt holding the same values as \a this array but differently
6676  * arranged in memory. If \a this array holds 2 components of 3 values:
6677  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6678  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6679  *  \warning Do not confuse this method with transpose()!
6680  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6681  *          is to delete using decrRef() as it is no more needed.
6682  *  \throw If \a this is not allocated.
6683  */
6684 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6685 {
6686   checkAllocated();
6687   if(_mem.isNull())
6688     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6689   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6690   DataArrayInt *ret=DataArrayInt::New();
6691   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6692   return ret;
6693 }
6694
6695 /*!
6696  * Permutes values of \a this array as required by \a old2New array. The values are
6697  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6698  * the same as in \this one.
6699  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6700  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6701  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6702  *     giving a new position for i-th old value.
6703  */
6704 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6705 {
6706   checkAllocated();
6707   int nbTuples=getNumberOfTuples();
6708   int nbOfCompo=getNumberOfComponents();
6709   int *tmp=new int[nbTuples*nbOfCompo];
6710   const int *iptr=getConstPointer();
6711   for(int i=0;i<nbTuples;i++)
6712     {
6713       int v=old2New[i];
6714       if(v>=0 && v<nbTuples)
6715         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6716       else
6717         {
6718           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6719           throw INTERP_KERNEL::Exception(oss.str().c_str());
6720         }
6721     }
6722   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6723   delete [] tmp;
6724   declareAsNew();
6725 }
6726
6727 /*!
6728  * Permutes values of \a this array as required by \a new2Old array. The values are
6729  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6730  * the same as in \this one.
6731  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6732  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6733  *     giving a previous position of i-th new value.
6734  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6735  *          is to delete using decrRef() as it is no more needed.
6736  */
6737 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6738 {
6739   checkAllocated();
6740   int nbTuples=getNumberOfTuples();
6741   int nbOfCompo=getNumberOfComponents();
6742   int *tmp=new int[nbTuples*nbOfCompo];
6743   const int *iptr=getConstPointer();
6744   for(int i=0;i<nbTuples;i++)
6745     {
6746       int v=new2Old[i];
6747       if(v>=0 && v<nbTuples)
6748         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6749       else
6750         {
6751           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6752           throw INTERP_KERNEL::Exception(oss.str().c_str());
6753         }
6754     }
6755   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6756   delete [] tmp;
6757   declareAsNew();
6758 }
6759
6760 /*!
6761  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6762  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6763  * Number of tuples in the result array remains the same as in \this one.
6764  * If a permutation reduction is needed, renumberAndReduce() should be used.
6765  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6766  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6767  *          giving a new position for i-th old value.
6768  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6769  *          is to delete using decrRef() as it is no more needed.
6770  *  \throw If \a this is not allocated.
6771  */
6772 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6773 {
6774   checkAllocated();
6775   int nbTuples=getNumberOfTuples();
6776   int nbOfCompo=getNumberOfComponents();
6777   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6778   ret->alloc(nbTuples,nbOfCompo);
6779   ret->copyStringInfoFrom(*this);
6780   const int *iptr=getConstPointer();
6781   int *optr=ret->getPointer();
6782   for(int i=0;i<nbTuples;i++)
6783     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6784   ret->copyStringInfoFrom(*this);
6785   return ret.retn();
6786 }
6787
6788 /*!
6789  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6790  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6791  * tuples in the result array remains the same as in \this one.
6792  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6793  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6794  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6795  *     giving a previous position of i-th new value.
6796  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6797  *          is to delete using decrRef() as it is no more needed.
6798  */
6799 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6800 {
6801   checkAllocated();
6802   int nbTuples=getNumberOfTuples();
6803   int nbOfCompo=getNumberOfComponents();
6804   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6805   ret->alloc(nbTuples,nbOfCompo);
6806   ret->copyStringInfoFrom(*this);
6807   const int *iptr=getConstPointer();
6808   int *optr=ret->getPointer();
6809   for(int i=0;i<nbTuples;i++)
6810     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6811   ret->copyStringInfoFrom(*this);
6812   return ret.retn();
6813 }
6814
6815 /*!
6816  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6817  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6818  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6819  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6820  * \a old2New[ i ] is negative, is missing from the result array.
6821  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6822  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6823  *     giving a new position for i-th old tuple and giving negative position for
6824  *     for i-th old tuple that should be omitted.
6825  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6826  *          is to delete using decrRef() as it is no more needed.
6827  */
6828 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6829 {
6830   checkAllocated();
6831   int nbTuples=getNumberOfTuples();
6832   int nbOfCompo=getNumberOfComponents();
6833   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6834   ret->alloc(newNbOfTuple,nbOfCompo);
6835   const int *iptr=getConstPointer();
6836   int *optr=ret->getPointer();
6837   for(int i=0;i<nbTuples;i++)
6838     {
6839       int w=old2New[i];
6840       if(w>=0)
6841         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6842     }
6843   ret->copyStringInfoFrom(*this);
6844   return ret.retn();
6845 }
6846
6847 /*!
6848  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6849  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6850  * \a new2OldBg array.
6851  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6852  * This method is equivalent to renumberAndReduce() except that convention in input is
6853  * \c new2old and \b not \c old2new.
6854  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6855  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6856  *              tuple index in \a this array to fill the i-th tuple in the new array.
6857  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6858  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6859  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6860  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6861  *          is to delete using decrRef() as it is no more needed.
6862  */
6863 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6864 {
6865   checkAllocated();
6866   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6867   int nbComp=getNumberOfComponents();
6868   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6869   ret->copyStringInfoFrom(*this);
6870   int *pt=ret->getPointer();
6871   const int *srcPt=getConstPointer();
6872   int i=0;
6873   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6874     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6875   ret->copyStringInfoFrom(*this);
6876   return ret.retn();
6877 }
6878
6879 /*!
6880  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6881  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6882  * \a new2OldBg array.
6883  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6884  * This method is equivalent to renumberAndReduce() except that convention in input is
6885  * \c new2old and \b not \c old2new.
6886  * This method is equivalent to selectByTupleId() except that it prevents coping data
6887  * from behind the end of \a this array.
6888  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6889  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6890  *              tuple index in \a this array to fill the i-th tuple in the new array.
6891  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6892  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6893  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6894  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6895  *          is to delete using decrRef() as it is no more needed.
6896  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6897  */
6898 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6899 {
6900   checkAllocated();
6901   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6902   int nbComp=getNumberOfComponents();
6903   int oldNbOfTuples=getNumberOfTuples();
6904   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6905   ret->copyStringInfoFrom(*this);
6906   int *pt=ret->getPointer();
6907   const int *srcPt=getConstPointer();
6908   int i=0;
6909   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6910     if(*w>=0 && *w<oldNbOfTuples)
6911       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6912     else
6913       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6914   ret->copyStringInfoFrom(*this);
6915   return ret.retn();
6916 }
6917
6918 /*!
6919  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6920  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6921  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6922  * command \c range( \a bg, \a end2, \a step ).
6923  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6924  * not constructed explicitly.
6925  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6926  *  \param [in] bg - index of the first tuple to copy from \a this array.
6927  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6928  *  \param [in] step - index increment to get index of the next tuple to copy.
6929  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6930  *          is to delete using decrRef() as it is no more needed.
6931  *  \sa DataArrayInt::substr.
6932  */
6933 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6934 {
6935   checkAllocated();
6936   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6937   int nbComp=getNumberOfComponents();
6938   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6939   ret->alloc(newNbOfTuples,nbComp);
6940   int *pt=ret->getPointer();
6941   const int *srcPt=getConstPointer()+bg*nbComp;
6942   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6943     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6944   ret->copyStringInfoFrom(*this);
6945   return ret.retn();
6946 }
6947
6948 /*!
6949  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6950  * of tuples specified by \a ranges parameter.
6951  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6952  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6953  *              of tuples in [\c begin,\c end) format.
6954  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6955  *          is to delete using decrRef() as it is no more needed.
6956  *  \throw If \a end < \a begin.
6957  *  \throw If \a end > \a this->getNumberOfTuples().
6958  *  \throw If \a this is not allocated.
6959  */
6960 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6961 {
6962   checkAllocated();
6963   int nbOfComp=getNumberOfComponents();
6964   int nbOfTuplesThis=getNumberOfTuples();
6965   if(ranges.empty())
6966     {
6967       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6968       ret->alloc(0,nbOfComp);
6969       ret->copyStringInfoFrom(*this);
6970       return ret.retn();
6971     }
6972   int ref=ranges.front().first;
6973   int nbOfTuples=0;
6974   bool isIncreasing=true;
6975   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6976     {
6977       if((*it).first<=(*it).second)
6978         {
6979           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6980             {
6981               nbOfTuples+=(*it).second-(*it).first;
6982               if(isIncreasing)
6983                 isIncreasing=ref<=(*it).first;
6984               ref=(*it).second;
6985             }
6986           else
6987             {
6988               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6989               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6990               throw INTERP_KERNEL::Exception(oss.str().c_str());
6991             }
6992         }
6993       else
6994         {
6995           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6996           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6997           throw INTERP_KERNEL::Exception(oss.str().c_str());
6998         }
6999     }
7000   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7001     return deepCpy();
7002   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7003   ret->alloc(nbOfTuples,nbOfComp);
7004   ret->copyStringInfoFrom(*this);
7005   const int *src=getConstPointer();
7006   int *work=ret->getPointer();
7007   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7008     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7009   return ret.retn();
7010 }
7011
7012 /*!
7013  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7014  * This map, if applied to \a this array, would make it sorted. For example, if
7015  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7016  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7017  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7018  * This method is useful for renumbering (in MED file for example). For more info
7019  * on renumbering see \ref MEDCouplingArrayRenumbering.
7020  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7021  *          array using decrRef() as it is no more needed.
7022  *  \throw If \a this is not allocated.
7023  *  \throw If \a this->getNumberOfComponents() != 1.
7024  *  \throw If there are equal values in \a this array.
7025  */
7026 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
7027 {
7028   checkAllocated();
7029   if(getNumberOfComponents()!=1)
7030     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7031   int nbTuples=getNumberOfTuples();
7032   const int *pt=getConstPointer();
7033   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7034   DataArrayInt *ret=DataArrayInt::New();
7035   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7036   return ret;
7037 }
7038
7039 /*!
7040  * 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
7041  * input array \a ids2.
7042  * \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.
7043  * 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
7044  * inversely.
7045  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7046  *
7047  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7048  *          array using decrRef() as it is no more needed.
7049  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7050  * 
7051  */
7052 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception)
7053 {
7054   if(!ids1 || !ids2)
7055     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7056   if(!ids1->isAllocated() || !ids2->isAllocated())
7057     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7058   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7059     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7060   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7061     {
7062       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 !";
7063       throw INTERP_KERNEL::Exception(oss.str().c_str());
7064     }
7065   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7066   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7067   p1->sort(true); p2->sort(true);
7068   if(!p1->isEqualWithoutConsideringStr(*p2))
7069     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7070   p1=ids1->checkAndPreparePermutation();
7071   p2=ids2->checkAndPreparePermutation();
7072   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7073   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7074   return p2.retn();
7075 }
7076
7077 /*!
7078  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7079  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7080  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7081  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7082  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7083  * The first of out arrays returns indices of elements of \a this array, grouped by their
7084  * place in the set \a B. The second out array is the index of the first one; it shows how
7085  * many elements of \a A are mapped into each element of \a B. <br>
7086  * For more info on
7087  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7088  * \b Example:
7089  * - \a this: [0,3,2,3,2,2,1,2]
7090  * - \a targetNb: 4
7091  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7092  * - \a arrI: [0,1,2,6,8]
7093  *
7094  * This result means: <br>
7095  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7096  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7097  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7098  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7099  * \a arrI[ 2+1 ]]); <br> etc.
7100  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7101  *         than the maximal value of \a A.
7102  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7103  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7104  *         this array using decrRef() as it is no more needed.
7105  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7106  *         elements of \a this. The caller is to delete this array using decrRef() as it
7107  *         is no more needed.
7108  *  \throw If \a this is not allocated.
7109  *  \throw If \a this->getNumberOfComponents() != 1.
7110  *  \throw If any value in \a this is more or equal to \a targetNb.
7111  */
7112 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
7113 {
7114   checkAllocated();
7115   if(getNumberOfComponents()!=1)
7116     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7117   int nbOfTuples=getNumberOfTuples();
7118   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7119   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7120   retI->alloc(targetNb+1,1);
7121   const int *input=getConstPointer();
7122   std::vector< std::vector<int> > tmp(targetNb);
7123   for(int i=0;i<nbOfTuples;i++)
7124     {
7125       int tmp2=input[i];
7126       if(tmp2>=0 && tmp2<targetNb)
7127         tmp[tmp2].push_back(i);
7128       else
7129         {
7130           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7131           throw INTERP_KERNEL::Exception(oss.str().c_str());
7132         }
7133     }
7134   int *retIPtr=retI->getPointer();
7135   *retIPtr=0;
7136   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7137     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7138   if(nbOfTuples!=retI->getIJ(targetNb,0))
7139     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7140   ret->alloc(nbOfTuples,1);
7141   int *retPtr=ret->getPointer();
7142   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7143     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7144   arr=ret.retn();
7145   arrI=retI.retn();
7146 }
7147
7148
7149 /*!
7150  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7151  * from a zip representation of a surjective format (returned e.g. by
7152  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7153  * for example). The result array minimizes the permutation. <br>
7154  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7155  * \b Example: <br>
7156  * - \a nbOfOldTuples: 10 
7157  * - \a arr          : [0,3, 5,7,9]
7158  * - \a arrIBg       : [0,2,5]
7159  * - \a newNbOfTuples: 7
7160  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7161  *
7162  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7163  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7164  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7165  *         (indices of) equal values. Its every element (except the last one) points to
7166  *         the first element of a group of equal values.
7167  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7168  *          arrIBg is \a arrIEnd[ -1 ].
7169  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7170  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7171  *          array using decrRef() as it is no more needed.
7172  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7173  */
7174 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
7175 {
7176   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7177   ret->alloc(nbOfOldTuples,1);
7178   int *pt=ret->getPointer();
7179   std::fill(pt,pt+nbOfOldTuples,-1);
7180   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7181   const int *cIPtr=arrIBg;
7182   for(int i=0;i<nbOfGrps;i++)
7183     pt[arr[cIPtr[i]]]=-(i+2);
7184   int newNb=0;
7185   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7186     {
7187       if(pt[iNode]<0)
7188         {
7189           if(pt[iNode]==-1)
7190             pt[iNode]=newNb++;
7191           else
7192             {
7193               int grpId=-(pt[iNode]+2);
7194               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7195                 {
7196                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7197                     pt[arr[j]]=newNb;
7198                   else
7199                     {
7200                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7201                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7202                     }
7203                 }
7204               newNb++;
7205             }
7206         }
7207     }
7208   newNbOfTuples=newNb;
7209   return ret.retn();
7210 }
7211
7212 /*!
7213  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7214  * which if applied to \a this array would make it sorted ascendingly.
7215  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7216  * \b Example: <br>
7217  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7218  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7219  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7220  *
7221  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7222  *          array using decrRef() as it is no more needed.
7223  *  \throw If \a this is not allocated.
7224  *  \throw If \a this->getNumberOfComponents() != 1.
7225  */
7226 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
7227 {
7228   checkAllocated();
7229   if(getNumberOfComponents()!=1)
7230     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7231   int nbOfTuples=getNumberOfTuples();
7232   const int *pt=getConstPointer();
7233   std::map<int,int> m;
7234   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7235   ret->alloc(nbOfTuples,1);
7236   int *opt=ret->getPointer();
7237   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7238     {
7239       int val=*pt;
7240       std::map<int,int>::iterator it=m.find(val);
7241       if(it!=m.end())
7242         {
7243           *opt=(*it).second;
7244           (*it).second++;
7245         }
7246       else
7247         {
7248           *opt=0;
7249           m.insert(std::pair<int,int>(val,1));
7250         }
7251     }
7252   int sum=0;
7253   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7254     {
7255       int vt=(*it).second;
7256       (*it).second=sum;
7257       sum+=vt;
7258     }
7259   pt=getConstPointer();
7260   opt=ret->getPointer();
7261   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7262     *opt+=m[*pt];
7263   //
7264   return ret.retn();
7265 }
7266
7267 /*!
7268  * Checks if contents of \a this array are equal to that of an array filled with
7269  * iota(). This method is particularly useful for DataArrayInt instances that represent
7270  * a renumbering array to check the real need in renumbering. 
7271  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7272  *  \throw If \a this is not allocated.
7273  *  \throw If \a this->getNumberOfComponents() != 1.
7274  */
7275 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
7276 {
7277   checkAllocated();
7278   if(getNumberOfComponents()!=1)
7279     return false;
7280   int nbOfTuples=getNumberOfTuples();
7281   const int *pt=getConstPointer();
7282   for(int i=0;i<nbOfTuples;i++,pt++)
7283     if(*pt!=i)
7284       return false;
7285   return true;
7286 }
7287
7288 /*!
7289  * Checks if all values in \a this array are equal to \a val.
7290  *  \param [in] val - value to check equality of array values to.
7291  *  \return bool - \a true if all values are \a val.
7292  *  \throw If \a this is not allocated.
7293  *  \throw If \a this->getNumberOfComponents() != 1
7294  */
7295 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
7296 {
7297   checkAllocated();
7298   if(getNumberOfComponents()!=1)
7299     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7300   int nbOfTuples=getNumberOfTuples();
7301   const int *w=getConstPointer();
7302   const int *end2=w+nbOfTuples;
7303   for(;w!=end2;w++)
7304     if(*w!=val)
7305       return false;
7306   return true;
7307 }
7308
7309 /*!
7310  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7311  * array to the new one.
7312  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7313  */
7314 DataArrayDouble *DataArrayInt::convertToDblArr() const
7315 {
7316   checkAllocated();
7317   DataArrayDouble *ret=DataArrayDouble::New();
7318   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7319   std::size_t nbOfVals=getNbOfElems();
7320   const int *src=getConstPointer();
7321   double *dest=ret->getPointer();
7322   std::copy(src,src+nbOfVals,dest);
7323   ret->copyStringInfoFrom(*this);
7324   return ret;
7325 }
7326
7327 /*!
7328  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7329  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7330  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7331  * This method is a specialization of selectByTupleId2().
7332  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7333  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7334  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7335  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7336  *          is to delete using decrRef() as it is no more needed.
7337  *  \throw If \a tupleIdBg < 0.
7338  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7339     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7340  *  \sa DataArrayInt::selectByTupleId2
7341  */
7342 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7343 {
7344   checkAllocated();
7345   int nbt=getNumberOfTuples();
7346   if(tupleIdBg<0)
7347     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7348   if(tupleIdBg>nbt)
7349     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7350   int trueEnd=tupleIdEnd;
7351   if(tupleIdEnd!=-1)
7352     {
7353       if(tupleIdEnd>nbt)
7354         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7355     }
7356   else
7357     trueEnd=nbt;
7358   int nbComp=getNumberOfComponents();
7359   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7360   ret->alloc(trueEnd-tupleIdBg,nbComp);
7361   ret->copyStringInfoFrom(*this);
7362   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7363   return ret.retn();
7364 }
7365
7366 /*!
7367  * Changes the number of components within \a this array so that its raw data **does
7368  * not** change, instead splitting this data into tuples changes.
7369  *  \warning This method erases all (name and unit) component info set before!
7370  *  \param [in] newNbOfComp - number of components for \a this array to have.
7371  *  \throw If \a this is not allocated
7372  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7373  *  \throw If \a newNbOfCompo is lower than 1.
7374  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7375  *  \warning This method erases all (name and unit) component info set before!
7376  */
7377 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7378 {
7379   checkAllocated();
7380   if(newNbOfCompo<1)
7381     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7382   std::size_t nbOfElems=getNbOfElems();
7383   if(nbOfElems%newNbOfCompo!=0)
7384     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7385   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7386     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7387   _info_on_compo.clear();
7388   _info_on_compo.resize(newNbOfCompo);
7389   declareAsNew();
7390 }
7391
7392 /*!
7393  * Changes the number of components within \a this array to be equal to its number
7394  * of tuples, and inversely its number of tuples to become equal to its number of 
7395  * components. So that its raw data **does not** change, instead splitting this
7396  * data into tuples changes.
7397  *  \warning This method erases all (name and unit) component info set before!
7398  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7399  *  \throw If \a this is not allocated.
7400  *  \sa rearrange()
7401  */
7402 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7403 {
7404   checkAllocated();
7405   int nbOfTuples=getNumberOfTuples();
7406   rearrange(nbOfTuples);
7407 }
7408
7409 /*!
7410  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7411  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7412  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7413  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7414  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7415  * components.  
7416  *  \param [in] newNbOfComp - number of components for the new array to have.
7417  *  \param [in] dftValue - value assigned to new values added to the new array.
7418  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7419  *          is to delete using decrRef() as it is no more needed.
7420  *  \throw If \a this is not allocated.
7421  */
7422 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7423 {
7424   checkAllocated();
7425   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7426   ret->alloc(getNumberOfTuples(),newNbOfComp);
7427   const int *oldc=getConstPointer();
7428   int *nc=ret->getPointer();
7429   int nbOfTuples=getNumberOfTuples();
7430   int oldNbOfComp=getNumberOfComponents();
7431   int dim=std::min(oldNbOfComp,newNbOfComp);
7432   for(int i=0;i<nbOfTuples;i++)
7433     {
7434       int j=0;
7435       for(;j<dim;j++)
7436         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7437       for(;j<newNbOfComp;j++)
7438         nc[newNbOfComp*i+j]=dftValue;
7439     }
7440   ret->setName(getName().c_str());
7441   for(int i=0;i<dim;i++)
7442     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7443   ret->setName(getName().c_str());
7444   return ret.retn();
7445 }
7446
7447 /*!
7448  * Changes number of tuples in the array. If the new number of tuples is smaller
7449  * than the current number the array is truncated, otherwise the array is extended.
7450  *  \param [in] nbOfTuples - new number of tuples. 
7451  *  \throw If \a this is not allocated.
7452  *  \throw If \a nbOfTuples is negative.
7453  */
7454 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7455 {
7456   if(nbOfTuples<0)
7457     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7458   checkAllocated();
7459   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7460   declareAsNew();
7461 }
7462
7463
7464 /*!
7465  * Returns a copy of \a this array composed of selected components.
7466  * The new DataArrayInt has the same number of tuples but includes components
7467  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7468  * can be either less, same or more than \a this->getNbOfElems().
7469  *  \param [in] compoIds - sequence of zero based indices of components to include
7470  *              into the new array.
7471  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7472  *          is to delete using decrRef() as it is no more needed.
7473  *  \throw If \a this is not allocated.
7474  *  \throw If a component index (\a i) is not valid: 
7475  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7476  *
7477  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7478  */
7479 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7480 {
7481   checkAllocated();
7482   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7483   int newNbOfCompo=(int)compoIds.size();
7484   int oldNbOfCompo=getNumberOfComponents();
7485   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7486     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7487   int nbOfTuples=getNumberOfTuples();
7488   ret->alloc(nbOfTuples,newNbOfCompo);
7489   ret->copyPartOfStringInfoFrom(*this,compoIds);
7490   const int *oldc=getConstPointer();
7491   int *nc=ret->getPointer();
7492   for(int i=0;i<nbOfTuples;i++)
7493     for(int j=0;j<newNbOfCompo;j++,nc++)
7494       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7495   return ret.retn();
7496 }
7497
7498 /*!
7499  * Appends components of another array to components of \a this one, tuple by tuple.
7500  * So that the number of tuples of \a this array remains the same and the number of 
7501  * components increases.
7502  *  \param [in] other - the DataArrayInt to append to \a this one.
7503  *  \throw If \a this is not allocated.
7504  *  \throw If \a this and \a other arrays have different number of tuples.
7505  *
7506  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7507  *
7508  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7509  */
7510 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7511 {
7512   if(!other)
7513     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7514   checkAllocated();
7515   other->checkAllocated();
7516   int nbOfTuples=getNumberOfTuples();
7517   if(nbOfTuples!=other->getNumberOfTuples())
7518     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7519   int nbOfComp1=getNumberOfComponents();
7520   int nbOfComp2=other->getNumberOfComponents();
7521   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7522   int *w=newArr;
7523   const int *inp1=getConstPointer();
7524   const int *inp2=other->getConstPointer();
7525   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7526     {
7527       w=std::copy(inp1,inp1+nbOfComp1,w);
7528       w=std::copy(inp2,inp2+nbOfComp2,w);
7529     }
7530   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7531   std::vector<int> compIds(nbOfComp2);
7532   for(int i=0;i<nbOfComp2;i++)
7533     compIds[i]=nbOfComp1+i;
7534   copyPartOfStringInfoFrom2(compIds,*other);
7535 }
7536
7537 /*!
7538  * Copy all components in a specified order from another DataArrayInt.
7539  * The specified components become the first ones in \a this array.
7540  * Both numerical and textual data is copied. The number of tuples in \a this and
7541  * the other array can be different.
7542  *  \param [in] a - the array to copy data from.
7543  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7544  *              to be copied.
7545  *  \throw If \a a is NULL.
7546  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7547  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7548  *
7549  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7550  */
7551 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7552 {
7553   if(!a)
7554     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7555   checkAllocated();
7556   a->checkAllocated();
7557   copyPartOfStringInfoFrom2(compoIds,*a);
7558   std::size_t partOfCompoSz=compoIds.size();
7559   int nbOfCompo=getNumberOfComponents();
7560   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7561   const int *ac=a->getConstPointer();
7562   int *nc=getPointer();
7563   for(int i=0;i<nbOfTuples;i++)
7564     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7565       nc[nbOfCompo*i+compoIds[j]]=*ac;
7566 }
7567
7568 /*!
7569  * Copy all values from another DataArrayInt into specified tuples and components
7570  * of \a this array. Textual data is not copied.
7571  * The tree parameters defining set of indices of tuples and components are similar to
7572  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7573  *  \param [in] a - the array to copy values from.
7574  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7575  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7576  *              are located.
7577  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7578  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7579  *  \param [in] endComp - index of the component before which the components to assign
7580  *              to are located.
7581  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7582  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7583  *              must be equal to the number of columns to assign to, else an
7584  *              exception is thrown; if \a false, then it is only required that \a
7585  *              a->getNbOfElems() equals to number of values to assign to (this condition
7586  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7587  *              values to assign to is given by following Python expression:
7588  *              \a nbTargetValues = 
7589  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7590  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7591  *  \throw If \a a is NULL.
7592  *  \throw If \a a is not allocated.
7593  *  \throw If \a this is not allocated.
7594  *  \throw If parameters specifying tuples and components to assign to do not give a
7595  *            non-empty range of increasing indices.
7596  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7597  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7598  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7599  *
7600  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7601  */
7602 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7603 {
7604   if(!a)
7605     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7606   const char msg[]="DataArrayInt::setPartOfValues1";
7607   checkAllocated();
7608   a->checkAllocated();
7609   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7610   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7611   int nbComp=getNumberOfComponents();
7612   int nbOfTuples=getNumberOfTuples();
7613   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7614   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7615   bool assignTech=true;
7616   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7617     {
7618       if(strictCompoCompare)
7619         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7620     }
7621   else
7622     {
7623       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7624       assignTech=false;
7625     }
7626   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7627   const int *srcPt=a->getConstPointer();
7628   if(assignTech)
7629     {
7630       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7631         for(int j=0;j<newNbOfComp;j++,srcPt++)
7632           pt[j*stepComp]=*srcPt;
7633     }
7634   else
7635     {
7636       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7637         {
7638           const int *srcPt2=srcPt;
7639           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7640             pt[j*stepComp]=*srcPt2;
7641         }
7642     }
7643 }
7644
7645 /*!
7646  * Assign a given value to values at specified tuples and components of \a this array.
7647  * The tree parameters defining set of indices of tuples and components are similar to
7648  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7649  *  \param [in] a - the value to assign.
7650  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7651  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7652  *              are located.
7653  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7654  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7655  *  \param [in] endComp - index of the component before which the components to assign
7656  *              to are located.
7657  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7658  *  \throw If \a this is not allocated.
7659  *  \throw If parameters specifying tuples and components to assign to, do not give a
7660  *            non-empty range of increasing indices or indices are out of a valid range
7661  *            for \this array.
7662  *
7663  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7664  */
7665 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7666 {
7667   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7668   checkAllocated();
7669   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7670   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7671   int nbComp=getNumberOfComponents();
7672   int nbOfTuples=getNumberOfTuples();
7673   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7674   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7675   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7676   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7677     for(int j=0;j<newNbOfComp;j++)
7678       pt[j*stepComp]=a;
7679 }
7680
7681
7682 /*!
7683  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7684  * components of \a this array. Textual data is not copied.
7685  * The tuples and components to assign to are defined by C arrays of indices.
7686  * There are two *modes of usage*:
7687  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7688  *   of \a a is assigned to its own location within \a this array. 
7689  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7690  *   components of every specified tuple of \a this array. In this mode it is required
7691  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7692  * 
7693  *  \param [in] a - the array to copy values from.
7694  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7695  *              assign values of \a a to.
7696  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7697  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7698  *              \a bgTuples <= \a pi < \a endTuples.
7699  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7700  *              assign values of \a a to.
7701  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7702  *              pointer to a component index <em>(pi)</em> varies as this: 
7703  *              \a bgComp <= \a pi < \a endComp.
7704  *  \param [in] strictCompoCompare - this parameter is checked only if the
7705  *               *mode of usage* is the first; if it is \a true (default), 
7706  *               then \a a->getNumberOfComponents() must be equal 
7707  *               to the number of specified columns, else this is not required.
7708  *  \throw If \a a is NULL.
7709  *  \throw If \a a is not allocated.
7710  *  \throw If \a this is not allocated.
7711  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7712  *         out of a valid range for \a this array.
7713  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7714  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7715  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7716  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7717  *
7718  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7719  */
7720 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7721 {
7722   if(!a)
7723     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7724   const char msg[]="DataArrayInt::setPartOfValues2";
7725   checkAllocated();
7726   a->checkAllocated();
7727   int nbComp=getNumberOfComponents();
7728   int nbOfTuples=getNumberOfTuples();
7729   for(const int *z=bgComp;z!=endComp;z++)
7730     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7731   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7732   int newNbOfComp=(int)std::distance(bgComp,endComp);
7733   bool assignTech=true;
7734   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7735     {
7736       if(strictCompoCompare)
7737         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7738     }
7739   else
7740     {
7741       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7742       assignTech=false;
7743     }
7744   int *pt=getPointer();
7745   const int *srcPt=a->getConstPointer();
7746   if(assignTech)
7747     {    
7748       for(const int *w=bgTuples;w!=endTuples;w++)
7749         {
7750           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7751           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7752             {    
7753               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7754             }
7755         }
7756     }
7757   else
7758     {
7759       for(const int *w=bgTuples;w!=endTuples;w++)
7760         {
7761           const int *srcPt2=srcPt;
7762           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7763           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7764             {    
7765               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7766             }
7767         }
7768     }
7769 }
7770
7771 /*!
7772  * Assign a given value to values at specified tuples and components of \a this array.
7773  * The tuples and components to assign to are defined by C arrays of indices.
7774  *  \param [in] a - the value to assign.
7775  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7776  *              assign \a a to.
7777  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7778  *              pointer to a tuple index (\a pi) varies as this: 
7779  *              \a bgTuples <= \a pi < \a endTuples.
7780  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7781  *              assign \a a to.
7782  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7783  *              pointer to a component index (\a pi) varies as this: 
7784  *              \a bgComp <= \a pi < \a endComp.
7785  *  \throw If \a this is not allocated.
7786  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7787  *         out of a valid range for \a this array.
7788  *
7789  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7790  */
7791 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7792 {
7793   checkAllocated();
7794   int nbComp=getNumberOfComponents();
7795   int nbOfTuples=getNumberOfTuples();
7796   for(const int *z=bgComp;z!=endComp;z++)
7797     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7798   int *pt=getPointer();
7799   for(const int *w=bgTuples;w!=endTuples;w++)
7800     for(const int *z=bgComp;z!=endComp;z++)
7801       {
7802         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7803         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7804       }
7805 }
7806
7807 /*!
7808  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7809  * components of \a this array. Textual data is not copied.
7810  * The tuples to assign to are defined by a C array of indices.
7811  * The components to assign to are defined by three values similar to parameters of
7812  * the Python function \c range(\c start,\c stop,\c step).
7813  * There are two *modes of usage*:
7814  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7815  *   of \a a is assigned to its own location within \a this array. 
7816  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7817  *   components of every specified tuple of \a this array. In this mode it is required
7818  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7819  *
7820  *  \param [in] a - the array to copy values from.
7821  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7822  *              assign values of \a a to.
7823  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7824  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7825  *              \a bgTuples <= \a pi < \a endTuples.
7826  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7827  *  \param [in] endComp - index of the component before which the components to assign
7828  *              to are located.
7829  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7830  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7831  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7832  *               then \a a->getNumberOfComponents() must be equal 
7833  *               to the number of specified columns, else this is not required.
7834  *  \throw If \a a is NULL.
7835  *  \throw If \a a is not allocated.
7836  *  \throw If \a this is not allocated.
7837  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7838  *         \a this array.
7839  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7840  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7841  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7842  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7843  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7844  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7845  *  \throw If parameters specifying components to assign to, do not give a
7846  *            non-empty range of increasing indices or indices are out of a valid range
7847  *            for \this array.
7848  *
7849  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7850  */
7851 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7852 {
7853   if(!a)
7854     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7855   const char msg[]="DataArrayInt::setPartOfValues3";
7856   checkAllocated();
7857   a->checkAllocated();
7858   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7859   int nbComp=getNumberOfComponents();
7860   int nbOfTuples=getNumberOfTuples();
7861   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7862   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7863   bool assignTech=true;
7864   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7865     {
7866       if(strictCompoCompare)
7867         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7868     }
7869   else
7870     {
7871       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7872       assignTech=false;
7873     }
7874   int *pt=getPointer()+bgComp;
7875   const int *srcPt=a->getConstPointer();
7876   if(assignTech)
7877     {
7878       for(const int *w=bgTuples;w!=endTuples;w++)
7879         for(int j=0;j<newNbOfComp;j++,srcPt++)
7880           {
7881             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7882             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7883           }
7884     }
7885   else
7886     {
7887       for(const int *w=bgTuples;w!=endTuples;w++)
7888         {
7889           const int *srcPt2=srcPt;
7890           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7891             {
7892               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7893               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7894             }
7895         }
7896     }
7897 }
7898
7899 /*!
7900  * Assign a given value to values at specified tuples and components of \a this array.
7901  * The tuples to assign to are defined by a C array of indices.
7902  * The components to assign to are defined by three values similar to parameters of
7903  * the Python function \c range(\c start,\c stop,\c step).
7904  *  \param [in] a - the value to assign.
7905  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7906  *              assign \a a to.
7907  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7908  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7909  *              \a bgTuples <= \a pi < \a endTuples.
7910  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7911  *  \param [in] endComp - index of the component before which the components to assign
7912  *              to are located.
7913  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7914  *  \throw If \a this is not allocated.
7915  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7916  *         \a this array.
7917  *  \throw If parameters specifying components to assign to, do not give a
7918  *            non-empty range of increasing indices or indices are out of a valid range
7919  *            for \this array.
7920  *
7921  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7922  */
7923 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7924 {
7925   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7926   checkAllocated();
7927   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7928   int nbComp=getNumberOfComponents();
7929   int nbOfTuples=getNumberOfTuples();
7930   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7931   int *pt=getPointer()+bgComp;
7932   for(const int *w=bgTuples;w!=endTuples;w++)
7933     for(int j=0;j<newNbOfComp;j++)
7934       {
7935         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7936         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7937       }
7938 }
7939
7940 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7941 {
7942   if(!a)
7943     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7944   const char msg[]="DataArrayInt::setPartOfValues4";
7945   checkAllocated();
7946   a->checkAllocated();
7947   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7948   int newNbOfComp=(int)std::distance(bgComp,endComp);
7949   int nbComp=getNumberOfComponents();
7950   for(const int *z=bgComp;z!=endComp;z++)
7951     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7952   int nbOfTuples=getNumberOfTuples();
7953   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7954   bool assignTech=true;
7955   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7956     {
7957       if(strictCompoCompare)
7958         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7959     }
7960   else
7961     {
7962       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7963       assignTech=false;
7964     }
7965   const int *srcPt=a->getConstPointer();
7966   int *pt=getPointer()+bgTuples*nbComp;
7967   if(assignTech)
7968     {
7969       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7970         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7971           pt[*z]=*srcPt;
7972     }
7973   else
7974     {
7975       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7976         {
7977           const int *srcPt2=srcPt;
7978           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7979             pt[*z]=*srcPt2;
7980         }
7981     }
7982 }
7983
7984 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7985 {
7986   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7987   checkAllocated();
7988   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7989   int nbComp=getNumberOfComponents();
7990   for(const int *z=bgComp;z!=endComp;z++)
7991     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7992   int nbOfTuples=getNumberOfTuples();
7993   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7994   int *pt=getPointer()+bgTuples*nbComp;
7995   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7996     for(const int *z=bgComp;z!=endComp;z++)
7997       pt[*z]=a;
7998 }
7999
8000 /*!
8001  * Copy some tuples from another DataArrayInt into specified tuples
8002  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8003  * components.
8004  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8005  * All components of selected tuples are copied.
8006  *  \param [in] a - the array to copy values from.
8007  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8008  *              target tuples of \a this. \a tuplesSelec has two components, and the
8009  *              first component specifies index of the source tuple and the second
8010  *              one specifies index of the target tuple.
8011  *  \throw If \a this is not allocated.
8012  *  \throw If \a a is NULL.
8013  *  \throw If \a a is not allocated.
8014  *  \throw If \a tuplesSelec is NULL.
8015  *  \throw If \a tuplesSelec is not allocated.
8016  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8017  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8018  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8019  *         the corresponding (\a this or \a a) array.
8020  */
8021 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
8022 {
8023   if(!a || !tuplesSelec)
8024     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8025   checkAllocated();
8026   a->checkAllocated();
8027   tuplesSelec->checkAllocated();
8028   int nbOfComp=getNumberOfComponents();
8029   if(nbOfComp!=a->getNumberOfComponents())
8030     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8031   if(tuplesSelec->getNumberOfComponents()!=2)
8032     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8033   int thisNt=getNumberOfTuples();
8034   int aNt=a->getNumberOfTuples();
8035   int *valsToSet=getPointer();
8036   const int *valsSrc=a->getConstPointer();
8037   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8038     {
8039       if(tuple[1]>=0 && tuple[1]<aNt)
8040         {
8041           if(tuple[0]>=0 && tuple[0]<thisNt)
8042             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8043           else
8044             {
8045               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8046               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8047               throw INTERP_KERNEL::Exception(oss.str().c_str());
8048             }
8049         }
8050       else
8051         {
8052           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8053           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8054           throw INTERP_KERNEL::Exception(oss.str().c_str());
8055         }
8056     }
8057 }
8058
8059 /*!
8060  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8061  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8062  * components.
8063  * The tuples to assign to are defined by index of the first tuple, and
8064  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8065  * The tuples to copy are defined by values of a DataArrayInt.
8066  * All components of selected tuples are copied.
8067  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8068  *              values to.
8069  *  \param [in] aBase - the array to copy values from.
8070  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8071  *  \throw If \a this is not allocated.
8072  *  \throw If \a aBase is NULL.
8073  *  \throw If \a aBase is not allocated.
8074  *  \throw If \a tuplesSelec is NULL.
8075  *  \throw If \a tuplesSelec is not allocated.
8076  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8077  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8078  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8079  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8080  *         \a aBase array.
8081  */
8082 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
8083 {
8084   if(!aBase || !tuplesSelec)
8085     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8086   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8087   if(!a)
8088     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8089   checkAllocated();
8090   a->checkAllocated();
8091   tuplesSelec->checkAllocated();
8092   int nbOfComp=getNumberOfComponents();
8093   if(nbOfComp!=a->getNumberOfComponents())
8094     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8095   if(tuplesSelec->getNumberOfComponents()!=1)
8096     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8097   int thisNt=getNumberOfTuples();
8098   int aNt=a->getNumberOfTuples();
8099   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8100   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8101   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8102     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8103   const int *valsSrc=a->getConstPointer();
8104   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8105     {
8106       if(*tuple>=0 && *tuple<aNt)
8107         {
8108           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8109         }
8110       else
8111         {
8112           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8113           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8114           throw INTERP_KERNEL::Exception(oss.str().c_str());
8115         }
8116     }
8117 }
8118
8119 /*!
8120  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8121  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8122  * components.
8123  * The tuples to copy are defined by three values similar to parameters of
8124  * the Python function \c range(\c start,\c stop,\c step).
8125  * The tuples to assign to are defined by index of the first tuple, and
8126  * their number is defined by number of tuples to copy.
8127  * All components of selected tuples are copied.
8128  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8129  *              values to.
8130  *  \param [in] aBase - the array to copy values from.
8131  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8132  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8133  *              are located.
8134  *  \param [in] step - index increment to get index of the next tuple to copy.
8135  *  \throw If \a this is not allocated.
8136  *  \throw If \a aBase is NULL.
8137  *  \throw If \a aBase is not allocated.
8138  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8139  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8140  *  \throw If parameters specifying tuples to copy, do not give a
8141  *            non-empty range of increasing indices or indices are out of a valid range
8142  *            for the array \a aBase.
8143  */
8144 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
8145 {
8146   if(!aBase)
8147     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8148   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8149   if(!a)
8150     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8151   checkAllocated();
8152   a->checkAllocated();
8153   int nbOfComp=getNumberOfComponents();
8154   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8155   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8156   if(nbOfComp!=a->getNumberOfComponents())
8157     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8158   int thisNt=getNumberOfTuples();
8159   int aNt=a->getNumberOfTuples();
8160   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8161   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8162     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8163   if(end2>aNt)
8164     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8165   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8166   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8167     {
8168       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8169     }
8170 }
8171
8172 /*!
8173  * Returns a value located at specified tuple and component.
8174  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8175  * parameters is checked. So this method is safe but expensive if used to go through
8176  * all values of \a this.
8177  *  \param [in] tupleId - index of tuple of interest.
8178  *  \param [in] compoId - index of component of interest.
8179  *  \return double - value located by \a tupleId and \a compoId.
8180  *  \throw If \a this is not allocated.
8181  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8182  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8183  */
8184 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
8185 {
8186   checkAllocated();
8187   if(tupleId<0 || tupleId>=getNumberOfTuples())
8188     {
8189       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8190       throw INTERP_KERNEL::Exception(oss.str().c_str());
8191     }
8192   if(compoId<0 || compoId>=getNumberOfComponents())
8193     {
8194       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8195       throw INTERP_KERNEL::Exception(oss.str().c_str());
8196     }
8197   return _mem[tupleId*_info_on_compo.size()+compoId];
8198 }
8199
8200 /*!
8201  * Returns the first value of \a this. 
8202  *  \return int - the last value of \a this array.
8203  *  \throw If \a this is not allocated.
8204  *  \throw If \a this->getNumberOfComponents() != 1.
8205  *  \throw If \a this->getNumberOfTuples() < 1.
8206  */
8207 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
8208 {
8209   checkAllocated();
8210   if(getNumberOfComponents()!=1)
8211     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8212   int nbOfTuples=getNumberOfTuples();
8213   if(nbOfTuples<1)
8214     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8215   return *(getConstPointer());
8216 }
8217
8218 /*!
8219  * Returns the last value of \a this. 
8220  *  \return int - the last value of \a this array.
8221  *  \throw If \a this is not allocated.
8222  *  \throw If \a this->getNumberOfComponents() != 1.
8223  *  \throw If \a this->getNumberOfTuples() < 1.
8224  */
8225 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
8226 {
8227   checkAllocated();
8228   if(getNumberOfComponents()!=1)
8229     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8230   int nbOfTuples=getNumberOfTuples();
8231   if(nbOfTuples<1)
8232     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8233   return *(getConstPointer()+nbOfTuples-1);
8234 }
8235
8236 /*!
8237  * Assign pointer to one array to a pointer to another appay. Reference counter of
8238  * \a arrayToSet is incremented / decremented.
8239  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8240  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8241  */
8242 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8243 {
8244   if(newArray!=arrayToSet)
8245     {
8246       if(arrayToSet)
8247         arrayToSet->decrRef();
8248       arrayToSet=newArray;
8249       if(arrayToSet)
8250         arrayToSet->incrRef();
8251     }
8252 }
8253
8254 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
8255 {
8256   return new DataArrayIntIterator(this);
8257 }
8258
8259 /*!
8260  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8261  * given one.
8262  *  \param [in] val - the value to find within \a this.
8263  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8264  *          array using decrRef() as it is no more needed.
8265  *  \throw If \a this is not allocated.
8266  *  \throw If \a this->getNumberOfComponents() != 1.
8267  */
8268 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
8269 {
8270   checkAllocated();
8271   if(getNumberOfComponents()!=1)
8272     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8273   const int *cptr=getConstPointer();
8274   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8275   int nbOfTuples=getNumberOfTuples();
8276   for(int i=0;i<nbOfTuples;i++,cptr++)
8277     if(*cptr==val)
8278       ret->pushBackSilent(i);
8279   return ret.retn();
8280 }
8281
8282 /*!
8283  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8284  * equal to a given one. 
8285  *  \param [in] val - the value to ignore within \a this.
8286  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8287  *          array using decrRef() as it is no more needed.
8288  *  \throw If \a this is not allocated.
8289  *  \throw If \a this->getNumberOfComponents() != 1.
8290  */
8291 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
8292 {
8293   checkAllocated();
8294   if(getNumberOfComponents()!=1)
8295     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8296   const int *cptr=getConstPointer();
8297   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8298   int nbOfTuples=getNumberOfTuples();
8299   for(int i=0;i<nbOfTuples;i++,cptr++)
8300     if(*cptr!=val)
8301       ret->pushBackSilent(i);
8302   return ret.retn();
8303 }
8304
8305
8306 /*!
8307  * Assigns \a newValue to all elements holding \a oldValue within \a this
8308  * one-dimensional array.
8309  *  \param [in] oldValue - the value to replace.
8310  *  \param [in] newValue - the value to assign.
8311  *  \return int - number of replacements performed.
8312  *  \throw If \a this is not allocated.
8313  *  \throw If \a this->getNumberOfComponents() != 1.
8314  */
8315 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
8316 {
8317   checkAllocated();
8318   if(getNumberOfComponents()!=1)
8319     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8320   int *start=getPointer();
8321   int *end2=start+getNbOfElems();
8322   int ret=0;
8323   for(int *val=start;val!=end2;val++)
8324     {
8325       if(*val==oldValue)
8326         {
8327           *val=newValue;
8328           ret++;
8329         }
8330     }
8331   return ret;
8332 }
8333
8334 /*!
8335  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8336  * one of given values.
8337  *  \param [in] valsBg - an array of values to find within \a this array.
8338  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8339  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8340  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8341  *          array using decrRef() as it is no more needed.
8342  *  \throw If \a this->getNumberOfComponents() != 1.
8343  */
8344 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8345 {
8346   if(getNumberOfComponents()!=1)
8347     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8348   std::set<int> vals2(valsBg,valsEnd);
8349   const int *cptr=getConstPointer();
8350   std::vector<int> res;
8351   int nbOfTuples=getNumberOfTuples();
8352   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8353   for(int i=0;i<nbOfTuples;i++,cptr++)
8354     if(vals2.find(*cptr)!=vals2.end())
8355       ret->pushBackSilent(i);
8356   return ret.retn();
8357 }
8358
8359 /*!
8360  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8361  * equal to any of given values.
8362  *  \param [in] valsBg - an array of values to ignore within \a this array.
8363  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8364  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8365  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8366  *          array using decrRef() as it is no more needed.
8367  *  \throw If \a this->getNumberOfComponents() != 1.
8368  */
8369 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8370 {
8371   if(getNumberOfComponents()!=1)
8372     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8373   std::set<int> vals2(valsBg,valsEnd);
8374   const int *cptr=getConstPointer();
8375   std::vector<int> res;
8376   int nbOfTuples=getNumberOfTuples();
8377   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8378   for(int i=0;i<nbOfTuples;i++,cptr++)
8379     if(vals2.find(*cptr)==vals2.end())
8380       ret->pushBackSilent(i);
8381   return ret.retn();
8382 }
8383
8384 /*!
8385  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8386  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8387  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8388  * If any the tuple id is returned. If not -1 is returned.
8389  * 
8390  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8391  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8392  *
8393  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8394  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8395  */
8396 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8397 {
8398   checkAllocated();
8399   int nbOfCompo=getNumberOfComponents();
8400   if(nbOfCompo==0)
8401     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8402   if(nbOfCompo!=(int)tupl.size())
8403     {
8404       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8405       throw INTERP_KERNEL::Exception(oss.str().c_str());
8406     }
8407   const int *cptr=getConstPointer();
8408   std::size_t nbOfVals=getNbOfElems();
8409   for(const int *work=cptr;work!=cptr+nbOfVals;)
8410     {
8411       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8412       if(work!=cptr+nbOfVals)
8413         {
8414           if(std::distance(cptr,work)%nbOfCompo!=0)
8415             work++;
8416           else
8417             return std::distance(cptr,work)/nbOfCompo;
8418         }
8419     }
8420   return -1;
8421 }
8422
8423 /*!
8424  * This method searches the sequence specified in input parameter \b vals in \b this.
8425  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8426  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8427  * \sa DataArrayInt::locateTuple
8428  */
8429 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8430 {
8431   checkAllocated();
8432   int nbOfCompo=getNumberOfComponents();
8433   if(nbOfCompo!=1)
8434     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8435   const int *cptr=getConstPointer();
8436   std::size_t nbOfVals=getNbOfElems();
8437   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8438   if(loc!=cptr+nbOfVals)
8439     return std::distance(cptr,loc);
8440   return -1;
8441 }
8442
8443 /*!
8444  * This method expects to be called when number of components of this is equal to one.
8445  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8446  * If not any tuple contains \b value -1 is returned.
8447  * \sa DataArrayInt::presenceOfValue
8448  */
8449 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8450 {
8451   checkAllocated();
8452   if(getNumberOfComponents()!=1)
8453     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8454   const int *cptr=getConstPointer();
8455   int nbOfTuples=getNumberOfTuples();
8456   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8457   if(ret!=cptr+nbOfTuples)
8458     return std::distance(cptr,ret);
8459   return -1;
8460 }
8461
8462 /*!
8463  * This method expects to be called when number of components of this is equal to one.
8464  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8465  * If not any tuple contains one of the values contained in 'vals' false is returned.
8466  * \sa DataArrayInt::presenceOfValue
8467  */
8468 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8469 {
8470   checkAllocated();
8471   if(getNumberOfComponents()!=1)
8472     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8473   std::set<int> vals2(vals.begin(),vals.end());
8474   const int *cptr=getConstPointer();
8475   int nbOfTuples=getNumberOfTuples();
8476   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8477     if(vals2.find(*w)!=vals2.end())
8478       return std::distance(cptr,w);
8479   return -1;
8480 }
8481
8482 /*!
8483  * This method returns the number of values in \a this that are equals to input parameter \a value.
8484  * This method only works for single component array.
8485  *
8486  * \return a value in [ 0, \c this->getNumberOfTuples() )
8487  *
8488  * \throw If \a this is not allocated
8489  *
8490  */
8491 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8492 {
8493   int ret=0;
8494   checkAllocated();
8495   if(getNumberOfComponents()!=1)
8496     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8497   const int *vals=begin();
8498   int nbOfTuples=getNumberOfTuples();
8499   for(int i=0;i<nbOfTuples;i++,vals++)
8500     if(*vals==value)
8501       ret++;
8502   return ret;
8503 }
8504
8505 /*!
8506  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8507  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8508  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8509  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8510  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8511  * \sa DataArrayInt::locateTuple
8512  */
8513 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8514 {
8515   return locateTuple(tupl)!=-1;
8516 }
8517
8518
8519 /*!
8520  * Returns \a true if a given value is present within \a this one-dimensional array.
8521  *  \param [in] value - the value to find within \a this array.
8522  *  \return bool - \a true in case if \a value is present within \a this array.
8523  *  \throw If \a this is not allocated.
8524  *  \throw If \a this->getNumberOfComponents() != 1.
8525  *  \sa locateValue()
8526  */
8527 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8528 {
8529   return locateValue(value)!=-1;
8530 }
8531
8532 /*!
8533  * This method expects to be called when number of components of this is equal to one.
8534  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8535  * If not any tuple contains one of the values contained in 'vals' false is returned.
8536  * \sa DataArrayInt::locateValue
8537  */
8538 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8539 {
8540   return locateValue(vals)!=-1;
8541 }
8542
8543 /*!
8544  * Accumulates values of each component of \a this array.
8545  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8546  *         by the caller, that is filled by this method with sum value for each
8547  *         component.
8548  *  \throw If \a this is not allocated.
8549  */
8550 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8551 {
8552   checkAllocated();
8553   const int *ptr=getConstPointer();
8554   int nbTuple=getNumberOfTuples();
8555   int nbComps=getNumberOfComponents();
8556   std::fill(res,res+nbComps,0);
8557   for(int i=0;i<nbTuple;i++)
8558     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8559 }
8560
8561 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8562 {
8563   checkAllocated();
8564   const int *ptr=getConstPointer();
8565   int nbTuple=getNumberOfTuples();
8566   int nbComps=getNumberOfComponents();
8567   if(compId<0 || compId>=nbComps)
8568     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8569   int ret=0;
8570   for(int i=0;i<nbTuple;i++)
8571     ret+=ptr[i*nbComps+compId];
8572   return ret;
8573 }
8574
8575 /*!
8576  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8577  * The returned array will have same number of components than \a this and number of tuples equal to
8578  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8579  *
8580  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8581  *
8582  * \param [in] bgOfIndex - begin (included) of the input index array.
8583  * \param [in] endOfIndex - end (excluded) of the input index array.
8584  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8585  * 
8586  * \throw If bgOfIndex or end is NULL.
8587  * \throw If input index array is not ascendingly sorted.
8588  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8589  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8590  */
8591 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8592 {
8593   if(!bgOfIndex || !endOfIndex)
8594     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8595   checkAllocated();
8596   int nbCompo=getNumberOfComponents();
8597   int nbOfTuples=getNumberOfTuples();
8598   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8599   if(sz<1)
8600     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8601   sz--;
8602   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8603   const int *w=bgOfIndex;
8604   if(*w<0 || *w>=nbOfTuples)
8605     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8606   const int *srcPt=begin()+(*w)*nbCompo;
8607   int *tmp=ret->getPointer();
8608   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8609     {
8610       std::fill(tmp,tmp+nbCompo,0.);
8611       if(w[1]>=w[0])
8612         {
8613           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8614             {
8615               if(j>=0 && j<nbOfTuples)
8616                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8617               else
8618                 {
8619                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8620                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8621                 }
8622             }
8623         }
8624       else
8625         {
8626           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8627           throw INTERP_KERNEL::Exception(oss.str().c_str());
8628         }
8629     }
8630   ret->copyStringInfoFrom(*this);
8631   return ret.retn();
8632 }
8633
8634 /*!
8635  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8636  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8637  * offsetA2</em> and (2)
8638  * the number of component in the result array is same as that of each of given arrays.
8639  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8640  * Info on components is copied from the first of the given arrays. Number of components
8641  * in the given arrays must be the same.
8642  *  \param [in] a1 - an array to include in the result array.
8643  *  \param [in] a2 - another array to include in the result array.
8644  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8645  *  \return DataArrayInt * - the new instance of DataArrayInt.
8646  *          The caller is to delete this result array using decrRef() as it is no more
8647  *          needed.
8648  *  \throw If either \a a1 or \a a2 is NULL.
8649  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8650  */
8651 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8652 {
8653   if(!a1 || !a2)
8654     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8655   int nbOfComp=a1->getNumberOfComponents();
8656   if(nbOfComp!=a2->getNumberOfComponents())
8657     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8658   int nbOfTuple1=a1->getNumberOfTuples();
8659   int nbOfTuple2=a2->getNumberOfTuples();
8660   DataArrayInt *ret=DataArrayInt::New();
8661   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8662   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8663   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8664   ret->copyStringInfoFrom(*a1);
8665   return ret;
8666 }
8667
8668 /*!
8669  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8670  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8671  * the number of component in the result array is same as that of each of given arrays.
8672  * Info on components is copied from the first of the given arrays. Number of components
8673  * in the given arrays must be  the same.
8674  *  \param [in] arr - a sequence of arrays to include in the result array.
8675  *  \return DataArrayInt * - the new instance of DataArrayInt.
8676  *          The caller is to delete this result array using decrRef() as it is no more
8677  *          needed.
8678  *  \throw If all arrays within \a arr are NULL.
8679  *  \throw If getNumberOfComponents() of arrays within \a arr.
8680  */
8681 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8682 {
8683   std::vector<const DataArrayInt *> a;
8684   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8685     if(*it4)
8686       a.push_back(*it4);
8687   if(a.empty())
8688     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8689   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8690   int nbOfComp=(*it)->getNumberOfComponents();
8691   int nbt=(*it++)->getNumberOfTuples();
8692   for(int i=1;it!=a.end();it++,i++)
8693     {
8694       if((*it)->getNumberOfComponents()!=nbOfComp)
8695         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8696       nbt+=(*it)->getNumberOfTuples();
8697     }
8698   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8699   ret->alloc(nbt,nbOfComp);
8700   int *pt=ret->getPointer();
8701   for(it=a.begin();it!=a.end();it++)
8702     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8703   ret->copyStringInfoFrom(*(a[0]));
8704   return ret.retn();
8705 }
8706
8707 /*!
8708  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8709  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8710  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8711  * 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.
8712  * 
8713  * \return DataArrayInt * - a new object to be managed by the caller.
8714  */
8715 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8716 {
8717   int retSz=1;
8718   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8719     {
8720       if(*it4)
8721         {
8722           (*it4)->checkAllocated();
8723           if((*it4)->getNumberOfComponents()!=1)
8724             {
8725               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8726               throw INTERP_KERNEL::Exception(oss.str().c_str());
8727             }
8728           int nbTupl=(*it4)->getNumberOfTuples();
8729           if(nbTupl<1)
8730             {
8731               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8732               throw INTERP_KERNEL::Exception(oss.str().c_str());
8733             }
8734           if((*it4)->front()!=0)
8735             {
8736               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8737               throw INTERP_KERNEL::Exception(oss.str().c_str());
8738             }
8739           retSz+=nbTupl-1;
8740         }
8741       else
8742         {
8743           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8744           throw INTERP_KERNEL::Exception(oss.str().c_str());
8745         }
8746     }
8747   if(arrs.empty())
8748     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8749   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8750   ret->alloc(retSz,1);
8751   int *pt=ret->getPointer(); *pt++=0;
8752   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8753     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8754   ret->copyStringInfoFrom(*(arrs[0]));
8755   return ret.retn();
8756 }
8757
8758 /*!
8759  * Returns the maximal value and its location within \a this one-dimensional array.
8760  *  \param [out] tupleId - index of the tuple holding the maximal value.
8761  *  \return int - the maximal value among all values of \a this array.
8762  *  \throw If \a this->getNumberOfComponents() != 1
8763  *  \throw If \a this->getNumberOfTuples() < 1
8764  */
8765 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8766 {
8767   checkAllocated();
8768   if(getNumberOfComponents()!=1)
8769     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8770   int nbOfTuples=getNumberOfTuples();
8771   if(nbOfTuples<=0)
8772     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8773   const int *vals=getConstPointer();
8774   const int *loc=std::max_element(vals,vals+nbOfTuples);
8775   tupleId=(int)std::distance(vals,loc);
8776   return *loc;
8777 }
8778
8779 /*!
8780  * Returns the maximal value within \a this array that is allowed to have more than
8781  *  one component.
8782  *  \return int - the maximal value among all values of \a this array.
8783  *  \throw If \a this is not allocated.
8784  */
8785 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8786 {
8787   checkAllocated();
8788   const int *loc=std::max_element(begin(),end());
8789   return *loc;
8790 }
8791
8792 /*!
8793  * Returns the minimal value and its location within \a this one-dimensional array.
8794  *  \param [out] tupleId - index of the tuple holding the minimal value.
8795  *  \return int - the minimal value among all values of \a this array.
8796  *  \throw If \a this->getNumberOfComponents() != 1
8797  *  \throw If \a this->getNumberOfTuples() < 1
8798  */
8799 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8800 {
8801   checkAllocated();
8802   if(getNumberOfComponents()!=1)
8803     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8804   int nbOfTuples=getNumberOfTuples();
8805   if(nbOfTuples<=0)
8806     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8807   const int *vals=getConstPointer();
8808   const int *loc=std::min_element(vals,vals+nbOfTuples);
8809   tupleId=(int)std::distance(vals,loc);
8810   return *loc;
8811 }
8812
8813 /*!
8814  * Returns the minimal value within \a this array that is allowed to have more than
8815  *  one component.
8816  *  \return int - the minimal value among all values of \a this array.
8817  *  \throw If \a this is not allocated.
8818  */
8819 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8820 {
8821   checkAllocated();
8822   const int *loc=std::min_element(begin(),end());
8823   return *loc;
8824 }
8825
8826 /*!
8827  * Converts every value of \a this array to its absolute value.
8828  *  \throw If \a this is not allocated.
8829  */
8830 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8831 {
8832   checkAllocated();
8833   int *ptr=getPointer();
8834   std::size_t nbOfElems=getNbOfElems();
8835   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8836   declareAsNew();
8837 }
8838
8839 /*!
8840  * Apply a liner function to a given component of \a this array, so that
8841  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8842  *  \param [in] a - the first coefficient of the function.
8843  *  \param [in] b - the second coefficient of the function.
8844  *  \param [in] compoId - the index of component to modify.
8845  *  \throw If \a this is not allocated.
8846  */
8847 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8848 {
8849   checkAllocated();
8850   int *ptr=getPointer()+compoId;
8851   int nbOfComp=getNumberOfComponents();
8852   int nbOfTuple=getNumberOfTuples();
8853   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8854     *ptr=a*(*ptr)+b;
8855   declareAsNew();
8856 }
8857
8858 /*!
8859  * Apply a liner function to all elements of \a this array, so that
8860  * an element _x_ becomes \f$ a * x + b \f$.
8861  *  \param [in] a - the first coefficient of the function.
8862  *  \param [in] b - the second coefficient of the function.
8863  *  \throw If \a this is not allocated.
8864  */
8865 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8866 {
8867   checkAllocated();
8868   int *ptr=getPointer();
8869   std::size_t nbOfElems=getNbOfElems();
8870   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8871     *ptr=a*(*ptr)+b;
8872   declareAsNew();
8873 }
8874
8875 /*!
8876  * Returns a full copy of \a this array except that sign of all elements is reversed.
8877  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8878  *          same number of tuples and component as \a this array.
8879  *          The caller is to delete this result array using decrRef() as it is no more
8880  *          needed.
8881  *  \throw If \a this is not allocated.
8882  */
8883 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8884 {
8885   checkAllocated();
8886   DataArrayInt *newArr=DataArrayInt::New();
8887   int nbOfTuples=getNumberOfTuples();
8888   int nbOfComp=getNumberOfComponents();
8889   newArr->alloc(nbOfTuples,nbOfComp);
8890   const int *cptr=getConstPointer();
8891   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8892   newArr->copyStringInfoFrom(*this);
8893   return newArr;
8894 }
8895
8896 /*!
8897  * Modify all elements of \a this array, so that
8898  * an element _x_ becomes \f$ numerator / x \f$.
8899  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8900  *           array, all elements processed before detection of the zero element remain
8901  *           modified.
8902  *  \param [in] numerator - the numerator used to modify array elements.
8903  *  \throw If \a this is not allocated.
8904  *  \throw If there is an element equal to 0 in \a this array.
8905  */
8906 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8907 {
8908   checkAllocated();
8909   int *ptr=getPointer();
8910   std::size_t nbOfElems=getNbOfElems();
8911   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8912     {
8913       if(*ptr!=0)
8914         {
8915           *ptr=numerator/(*ptr);
8916         }
8917       else
8918         {
8919           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8920           oss << " !";
8921           throw INTERP_KERNEL::Exception(oss.str().c_str());
8922         }
8923     }
8924   declareAsNew();
8925 }
8926
8927 /*!
8928  * Modify all elements of \a this array, so that
8929  * an element _x_ becomes \f$ x / val \f$.
8930  *  \param [in] val - the denominator used to modify array elements.
8931  *  \throw If \a this is not allocated.
8932  *  \throw If \a val == 0.
8933  */
8934 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8935 {
8936   if(val==0)
8937     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8938   checkAllocated();
8939   int *ptr=getPointer();
8940   std::size_t nbOfElems=getNbOfElems();
8941   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8942   declareAsNew();
8943 }
8944
8945 /*!
8946  * Modify all elements of \a this array, so that
8947  * an element _x_ becomes  <em> x % val </em>.
8948  *  \param [in] val - the divisor used to modify array elements.
8949  *  \throw If \a this is not allocated.
8950  *  \throw If \a val <= 0.
8951  */
8952 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8953 {
8954   if(val<=0)
8955     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8956   checkAllocated();
8957   int *ptr=getPointer();
8958   std::size_t nbOfElems=getNbOfElems();
8959   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8960   declareAsNew();
8961 }
8962
8963 /*!
8964  * This method works only on data array with one component.
8965  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8966  * this[*id] in [\b vmin,\b vmax)
8967  * 
8968  * \param [in] vmin begin of range. This value is included in range (included).
8969  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8970  * \return a newly allocated data array that the caller should deal with.
8971  */
8972 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8973 {
8974   checkAllocated();
8975   if(getNumberOfComponents()!=1)
8976     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8977   const int *cptr=getConstPointer();
8978   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8979   int nbOfTuples=getNumberOfTuples();
8980   for(int i=0;i<nbOfTuples;i++,cptr++)
8981     if(*cptr>=vmin && *cptr<vmax)
8982       ret->pushBackSilent(i);
8983   return ret.retn();
8984 }
8985
8986 /*!
8987  * This method works only on data array with one component.
8988  * 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.
8989  * 
8990  * \param [in] vmin begin of range. This value is included in range (included).
8991  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8992  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8993  */
8994 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8995 {
8996   checkAllocated();
8997   if(getNumberOfComponents()!=1)
8998     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8999   int nbOfTuples=getNumberOfTuples();
9000   bool ret=true;
9001   const int *cptr=getConstPointer();
9002   for(int i=0;i<nbOfTuples;i++,cptr++)
9003     {
9004       if(*cptr>=vmin && *cptr<vmax)
9005         { ret=ret && *cptr==i; }
9006       else
9007         {
9008           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9009           throw INTERP_KERNEL::Exception(oss.str().c_str());
9010         }
9011     }
9012   return ret;
9013 }
9014
9015 /*!
9016  * Modify all elements of \a this array, so that
9017  * an element _x_ becomes <em> val % x </em>.
9018  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9019  *           array, all elements processed before detection of the zero element remain
9020  *           modified.
9021  *  \param [in] val - the divident used to modify array elements.
9022  *  \throw If \a this is not allocated.
9023  *  \throw If there is an element equal to or less than 0 in \a this array.
9024  */
9025 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
9026 {
9027   checkAllocated();
9028   int *ptr=getPointer();
9029   std::size_t nbOfElems=getNbOfElems();
9030   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9031     {
9032       if(*ptr>0)
9033         {
9034           *ptr=val%(*ptr);
9035         }
9036       else
9037         {
9038           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9039           oss << " !";
9040           throw INTERP_KERNEL::Exception(oss.str().c_str());
9041         }
9042     }
9043   declareAsNew();
9044 }
9045
9046 /*!
9047  * Modify all elements of \a this array, so that
9048  * an element _x_ becomes <em> val ^ x </em>.
9049  *  \param [in] val - the value used to apply pow on all array elements.
9050  *  \throw If \a this is not allocated.
9051  *  \throw If \a val < 0.
9052  */
9053 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
9054 {
9055   checkAllocated();
9056   if(val<0)
9057     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9058   int *ptr=getPointer();
9059   std::size_t nbOfElems=getNbOfElems();
9060   if(val==0)
9061     {
9062       std::fill(ptr,ptr+nbOfElems,1.);
9063       return ;
9064     }
9065   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9066     {
9067       int tmp=1;
9068       for(int j=0;j<val;j++)
9069         tmp*=*ptr;
9070       *ptr=tmp;
9071     }
9072   declareAsNew();
9073 }
9074
9075 /*!
9076  * Modify all elements of \a this array, so that
9077  * an element _x_ becomes \f$ val ^ x \f$.
9078  *  \param [in] val - the value used to apply pow on all array elements.
9079  *  \throw If \a this is not allocated.
9080  *  \throw If there is an element < 0 in \a this array.
9081  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9082  *           array, all elements processed before detection of the zero element remain
9083  *           modified.
9084  */
9085 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
9086 {
9087   checkAllocated();
9088   int *ptr=getPointer();
9089   std::size_t nbOfElems=getNbOfElems();
9090   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9091     {
9092       if(*ptr>=0)
9093         {
9094           int tmp=1;
9095           for(int j=0;j<*ptr;j++)
9096             tmp*=val;
9097           *ptr=tmp;
9098         }
9099       else
9100         {
9101           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9102           oss << " !";
9103           throw INTERP_KERNEL::Exception(oss.str().c_str());
9104         }
9105     }
9106   declareAsNew();
9107 }
9108
9109 /*!
9110  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9111  * of components in the result array is a sum of the number of components of given arrays
9112  * and (2) the number of tuples in the result array is same as that of each of given
9113  * arrays. In other words the i-th tuple of result array includes all components of
9114  * i-th tuples of all given arrays.
9115  * Number of tuples in the given arrays must be the same.
9116  *  \param [in] a1 - an array to include in the result array.
9117  *  \param [in] a2 - another array to include in the result array.
9118  *  \return DataArrayInt * - the new instance of DataArrayInt.
9119  *          The caller is to delete this result array using decrRef() as it is no more
9120  *          needed.
9121  *  \throw If both \a a1 and \a a2 are NULL.
9122  *  \throw If any given array is not allocated.
9123  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9124  */
9125 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9126 {
9127   std::vector<const DataArrayInt *> arr(2);
9128   arr[0]=a1; arr[1]=a2;
9129   return Meld(arr);
9130 }
9131
9132 /*!
9133  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9134  * of components in the result array is a sum of the number of components of given arrays
9135  * and (2) the number of tuples in the result array is same as that of each of given
9136  * arrays. In other words the i-th tuple of result array includes all components of
9137  * i-th tuples of all given arrays.
9138  * Number of tuples in the given arrays must be  the same.
9139  *  \param [in] arr - a sequence of arrays to include in the result array.
9140  *  \return DataArrayInt * - the new instance of DataArrayInt.
9141  *          The caller is to delete this result array using decrRef() as it is no more
9142  *          needed.
9143  *  \throw If all arrays within \a arr are NULL.
9144  *  \throw If any given array is not allocated.
9145  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9146  */
9147 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9148 {
9149   std::vector<const DataArrayInt *> a;
9150   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9151     if(*it4)
9152       a.push_back(*it4);
9153   if(a.empty())
9154     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9155   std::vector<const DataArrayInt *>::const_iterator it;
9156   for(it=a.begin();it!=a.end();it++)
9157     (*it)->checkAllocated();
9158   it=a.begin();
9159   int nbOfTuples=(*it)->getNumberOfTuples();
9160   std::vector<int> nbc(a.size());
9161   std::vector<const int *> pts(a.size());
9162   nbc[0]=(*it)->getNumberOfComponents();
9163   pts[0]=(*it++)->getConstPointer();
9164   for(int i=1;it!=a.end();it++,i++)
9165     {
9166       if(nbOfTuples!=(*it)->getNumberOfTuples())
9167         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9168       nbc[i]=(*it)->getNumberOfComponents();
9169       pts[i]=(*it)->getConstPointer();
9170     }
9171   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9172   DataArrayInt *ret=DataArrayInt::New();
9173   ret->alloc(nbOfTuples,totalNbOfComp);
9174   int *retPtr=ret->getPointer();
9175   for(int i=0;i<nbOfTuples;i++)
9176     for(int j=0;j<(int)a.size();j++)
9177       {
9178         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9179         pts[j]+=nbc[j];
9180       }
9181   int k=0;
9182   for(int i=0;i<(int)a.size();i++)
9183     for(int j=0;j<nbc[i];j++,k++)
9184       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9185   return ret;
9186 }
9187
9188 /*!
9189  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9190  * The i-th item of the result array is an ID of a set of elements belonging to a
9191  * unique set of groups, which the i-th element is a part of. This set of elements
9192  * belonging to a unique set of groups is called \a family, so the result array contains
9193  * IDs of families each element belongs to.
9194  *
9195  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9196  * then there are 3 families:
9197  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9198  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9199  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9200  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9201  * stands for the element #3 which is in none of groups.
9202  *
9203  *  \param [in] groups - sequence of groups of element IDs.
9204  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9205  *         in \a groups.
9206  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9207  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9208  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9209  *         delete this array using decrRef() as it is no more needed.
9210  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9211  */
9212 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
9213 {
9214   std::vector<const DataArrayInt *> groups2;
9215   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9216     if(*it4)
9217       groups2.push_back(*it4);
9218   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9219   ret->alloc(newNb,1);
9220   int *retPtr=ret->getPointer();
9221   std::fill(retPtr,retPtr+newNb,0);
9222   int fid=1;
9223   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9224     {
9225       const int *ptr=(*iter)->getConstPointer();
9226       std::size_t nbOfElem=(*iter)->getNbOfElems();
9227       int sfid=fid;
9228       for(int j=0;j<sfid;j++)
9229         {
9230           bool found=false;
9231           for(std::size_t i=0;i<nbOfElem;i++)
9232             {
9233               if(ptr[i]>=0 && ptr[i]<newNb)
9234                 {
9235                   if(retPtr[ptr[i]]==j)
9236                     {
9237                       retPtr[ptr[i]]=fid;
9238                       found=true;
9239                     }
9240                 }
9241               else
9242                 {
9243                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9244                   oss << ") !";
9245                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9246                 }
9247             }
9248           if(found)
9249             fid++;
9250         }
9251     }
9252   fidsOfGroups.clear();
9253   fidsOfGroups.resize(groups2.size());
9254   int grId=0;
9255   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9256     {
9257       std::set<int> tmp;
9258       const int *ptr=(*iter)->getConstPointer();
9259       std::size_t nbOfElem=(*iter)->getNbOfElems();
9260       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9261         tmp.insert(retPtr[*p]);
9262       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9263     }
9264   return ret.retn();
9265 }
9266
9267 /*!
9268  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9269  * arrays. The result array does not contain any duplicates and its values
9270  * are sorted in ascending order.
9271  *  \param [in] arr - sequence of DataArrayInt's to unite.
9272  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9273  *         array using decrRef() as it is no more needed.
9274  *  \throw If any \a arr[i] is not allocated.
9275  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9276  */
9277 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9278 {
9279   std::vector<const DataArrayInt *> a;
9280   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9281     if(*it4)
9282       a.push_back(*it4);
9283   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9284     {
9285       (*it)->checkAllocated();
9286       if((*it)->getNumberOfComponents()!=1)
9287         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9288     }
9289   //
9290   std::set<int> r;
9291   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9292     {
9293       const int *pt=(*it)->getConstPointer();
9294       int nbOfTuples=(*it)->getNumberOfTuples();
9295       r.insert(pt,pt+nbOfTuples);
9296     }
9297   DataArrayInt *ret=DataArrayInt::New();
9298   ret->alloc((int)r.size(),1);
9299   std::copy(r.begin(),r.end(),ret->getPointer());
9300   return ret;
9301 }
9302
9303 /*!
9304  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9305  * arrays. The result array does not contain any duplicates and its values
9306  * are sorted in ascending order.
9307  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9308  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9309  *         array using decrRef() as it is no more needed.
9310  *  \throw If any \a arr[i] is not allocated.
9311  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9312  */
9313 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9314 {
9315   std::vector<const DataArrayInt *> a;
9316   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9317     if(*it4)
9318       a.push_back(*it4);
9319   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9320     {
9321       (*it)->checkAllocated();
9322       if((*it)->getNumberOfComponents()!=1)
9323         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9324     }
9325   //
9326   std::set<int> r;
9327   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9328     {
9329       const int *pt=(*it)->getConstPointer();
9330       int nbOfTuples=(*it)->getNumberOfTuples();
9331       std::set<int> s1(pt,pt+nbOfTuples);
9332       if(it!=a.begin())
9333         {
9334           std::set<int> r2;
9335           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9336           r=r2;
9337         }
9338       else
9339         r=s1;
9340     }
9341   DataArrayInt *ret=DataArrayInt::New();
9342   ret->alloc((int)r.size(),1);
9343   std::copy(r.begin(),r.end(),ret->getPointer());
9344   return ret;
9345 }
9346
9347 /*!
9348  * Returns a new DataArrayInt which contains a complement of elements of \a this
9349  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9350  * \a nbOfElement) not present in \a this array.
9351  *  \param [in] nbOfElement - maximal size of the result array.
9352  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9353  *         array using decrRef() as it is no more needed.
9354  *  \throw If \a this is not allocated.
9355  *  \throw If \a this->getNumberOfComponents() != 1.
9356  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9357  *         nbOfElement ).
9358  */
9359 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9360 {
9361    checkAllocated();
9362    if(getNumberOfComponents()!=1)
9363      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9364    std::vector<bool> tmp(nbOfElement);
9365    const int *pt=getConstPointer();
9366    int nbOfTuples=getNumberOfTuples();
9367    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9368      if(*w>=0 && *w<nbOfElement)
9369        tmp[*w]=true;
9370      else
9371        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9372    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9373    DataArrayInt *ret=DataArrayInt::New();
9374    ret->alloc(nbOfRetVal,1);
9375    int j=0;
9376    int *retPtr=ret->getPointer();
9377    for(int i=0;i<nbOfElement;i++)
9378      if(!tmp[i])
9379        retPtr[j++]=i;
9380    return ret;
9381 }
9382
9383 /*!
9384  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9385  * from an \a other one-dimensional array.
9386  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9387  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9388  *         caller is to delete this array using decrRef() as it is no more needed.
9389  *  \throw If \a other is NULL.
9390  *  \throw If \a other is not allocated.
9391  *  \throw If \a other->getNumberOfComponents() != 1.
9392  *  \throw If \a this is not allocated.
9393  *  \throw If \a this->getNumberOfComponents() != 1.
9394  *  \sa DataArrayInt::buildSubstractionOptimized()
9395  */
9396 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9397 {
9398   if(!other)
9399     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9400   checkAllocated();
9401   other->checkAllocated();
9402   if(getNumberOfComponents()!=1)
9403      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9404   if(other->getNumberOfComponents()!=1)
9405      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9406   const int *pt=getConstPointer();
9407   int nbOfTuples=getNumberOfTuples();
9408   std::set<int> s1(pt,pt+nbOfTuples);
9409   pt=other->getConstPointer();
9410   nbOfTuples=other->getNumberOfTuples();
9411   std::set<int> s2(pt,pt+nbOfTuples);
9412   std::vector<int> r;
9413   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9414   DataArrayInt *ret=DataArrayInt::New();
9415   ret->alloc((int)r.size(),1);
9416   std::copy(r.begin(),r.end(),ret->getPointer());
9417   return ret;
9418 }
9419
9420 /*!
9421  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9422  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9423  * 
9424  * \param [in] other an array with one component and expected to be sorted ascendingly.
9425  * \ret list of ids in \a this but not in \a other.
9426  * \sa DataArrayInt::buildSubstraction
9427  */
9428 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9429 {
9430   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9431   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9432   checkAllocated(); other->checkAllocated();
9433   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9434   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9435   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9436   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9437   for(;work1!=pt1End;work1++)
9438     {
9439       if(work2!=pt2End && *work1==*work2)
9440         work2++;
9441       else
9442         ret->pushBackSilent(*work1);
9443     }
9444   return ret.retn();
9445 }
9446
9447
9448 /*!
9449  * Returns a new DataArrayInt which contains all elements of \a this and a given
9450  * one-dimensional arrays. The result array does not contain any duplicates
9451  * and its values are sorted in ascending order.
9452  *  \param [in] other - an array to unite with \a this one.
9453  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9454  *         array using decrRef() as it is no more needed.
9455  *  \throw If \a this or \a other is not allocated.
9456  *  \throw If \a this->getNumberOfComponents() != 1.
9457  *  \throw If \a other->getNumberOfComponents() != 1.
9458  */
9459 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9460 {
9461   std::vector<const DataArrayInt *>arrs(2);
9462   arrs[0]=this; arrs[1]=other;
9463   return BuildUnion(arrs);
9464 }
9465
9466
9467 /*!
9468  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9469  * one-dimensional arrays. The result array does not contain any duplicates
9470  * and its values are sorted in ascending order.
9471  *  \param [in] other - an array to intersect with \a this one.
9472  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9473  *         array using decrRef() as it is no more needed.
9474  *  \throw If \a this or \a other is not allocated.
9475  *  \throw If \a this->getNumberOfComponents() != 1.
9476  *  \throw If \a other->getNumberOfComponents() != 1.
9477  */
9478 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9479 {
9480   std::vector<const DataArrayInt *>arrs(2);
9481   arrs[0]=this; arrs[1]=other;
9482   return BuildIntersection(arrs);
9483 }
9484
9485 /*!
9486  * This method can be applied on allocated with one component DataArrayInt instance.
9487  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9488  * 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]
9489  * 
9490  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9491  * \throw if \a this is not allocated or if \a this has not exactly one component.
9492  */
9493 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9494 {
9495   checkAllocated();
9496   if(getNumberOfComponents()!=1)
9497      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9498   int nbOfTuples=getNumberOfTuples();
9499   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9500   int *data=tmp->getPointer();
9501   int *last=std::unique(data,data+nbOfTuples);
9502   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9503   ret->alloc(std::distance(data,last),1);
9504   std::copy(data,last,ret->getPointer());
9505   return ret.retn();
9506 }
9507
9508 /*!
9509  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9510  * "index" array. Such "index" array is returned for example by 
9511  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9512  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9513  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9514  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9515  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9516  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9517  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9518  *          The caller is to delete this array using decrRef() as it is no more needed. 
9519  *  \throw If \a this is not allocated.
9520  *  \throw If \a this->getNumberOfComponents() != 1.
9521  *  \throw If \a this->getNumberOfTuples() < 2.
9522  *
9523  *  \b Example: <br> 
9524  *         - this contains [1,3,6,7,7,9,15]
9525  *         - result array contains [2,3,1,0,2,6],
9526  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9527  *
9528  * \sa DataArrayInt::computeOffsets2
9529  */
9530 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9531 {
9532   checkAllocated();
9533   if(getNumberOfComponents()!=1)
9534      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9535   int nbOfTuples=getNumberOfTuples();
9536   if(nbOfTuples<2)
9537     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9538   const int *ptr=getConstPointer();
9539   DataArrayInt *ret=DataArrayInt::New();
9540   ret->alloc(nbOfTuples-1,1);
9541   int *out=ret->getPointer();
9542   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9543   return ret;
9544 }
9545
9546 /*!
9547  * Modifies \a this one-dimensional array so that value of each element \a x
9548  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9549  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9550  * and components remains the same.<br>
9551  * This method is useful for allToAllV in MPI with contiguous policy. This method
9552  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9553  * this one.
9554  *  \throw If \a this is not allocated.
9555  *  \throw If \a this->getNumberOfComponents() != 1.
9556  *
9557  *  \b Example: <br>
9558  *          - Before \a this contains [3,5,1,2,0,8]
9559  *          - After \a this contains  [0,3,8,9,11,11]<br>
9560  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9561  *          array is retained and thus there is no space to store the last element.
9562  */
9563 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9564 {
9565   checkAllocated();
9566   if(getNumberOfComponents()!=1)
9567      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9568   int nbOfTuples=getNumberOfTuples();
9569   if(nbOfTuples==0)
9570     return ;
9571   int *work=getPointer();
9572   int tmp=work[0];
9573   work[0]=0;
9574   for(int i=1;i<nbOfTuples;i++)
9575     {
9576       int tmp2=work[i];
9577       work[i]=work[i-1]+tmp;
9578       tmp=tmp2;
9579     }
9580   declareAsNew();
9581 }
9582
9583
9584 /*!
9585  * Modifies \a this one-dimensional array so that value of each element \a x
9586  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9587  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9588  * components remains the same and number of tuples is inceamented by one.<br>
9589  * This method is useful for allToAllV in MPI with contiguous policy. This method
9590  * differs from computeOffsets() in that the number of tuples is changed by this one.
9591  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9592  *  \throw If \a this is not allocated.
9593  *  \throw If \a this->getNumberOfComponents() != 1.
9594  *
9595  *  \b Example: <br>
9596  *          - Before \a this contains [3,5,1,2,0,8]
9597  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9598  * \sa DataArrayInt::deltaShiftIndex
9599  */
9600 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9601 {
9602   checkAllocated();
9603   if(getNumberOfComponents()!=1)
9604     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9605   int nbOfTuples=getNumberOfTuples();
9606   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9607   if(nbOfTuples==0)
9608     return ;
9609   const int *work=getConstPointer();
9610   ret[0]=0;
9611   for(int i=0;i<nbOfTuples;i++)
9612     ret[i+1]=work[i]+ret[i];
9613   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9614   declareAsNew();
9615 }
9616
9617 /*!
9618  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9619  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9620  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9621  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9622  * filling completely one of the ranges in \a this.
9623  *
9624  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9625  * \param [out] rangeIdsFetched the range ids fetched
9626  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9627  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9628  *
9629  * \sa DataArrayInt::computeOffsets2
9630  *
9631  *  \b Example: <br>
9632  *          - \a this : [0,3,7,9,15,18]
9633  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9634  *          - \a rangeIdsFetched result array: [0,2,4]
9635  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9636  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9637  * <br>
9638  */
9639 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9640 {
9641   if(!listOfIds)
9642     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9643   listOfIds->checkAllocated(); checkAllocated();
9644   if(listOfIds->getNumberOfComponents()!=1)
9645     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9646   if(getNumberOfComponents()!=1)
9647     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9648   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9649   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9650   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9651   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9652   while(tupPtr!=tupEnd && offPtr!=offEnd)
9653     {
9654       if(*tupPtr==*offPtr)
9655         {
9656           int i=offPtr[0];
9657           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9658           if(i==offPtr[1])
9659             {
9660               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9661               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9662               offPtr++;
9663             }
9664         }
9665       else
9666         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9667     }
9668   rangeIdsFetched=ret0.retn();
9669   idsInInputListThatFetch=ret1.retn();
9670 }
9671
9672 /*!
9673  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9674  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9675  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9676  * beginning within the "iota" array. And \a this is a one-dimensional array
9677  * considered as a selector of groups described by \a offsets to include into the result array.
9678  *  \throw If \a offsets is NULL.
9679  *  \throw If \a offsets is not allocated.
9680  *  \throw If \a offsets->getNumberOfComponents() != 1.
9681  *  \throw If \a offsets is not monotonically increasing.
9682  *  \throw If \a this is not allocated.
9683  *  \throw If \a this->getNumberOfComponents() != 1.
9684  *  \throw If any element of \a this is not a valid index for \a offsets array.
9685  *
9686  *  \b Example: <br>
9687  *          - \a this: [0,2,3]
9688  *          - \a offsets: [0,3,6,10,14,20]
9689  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9690  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9691  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9692  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9693  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9694  */
9695 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9696 {
9697   if(!offsets)
9698     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9699   checkAllocated();
9700   if(getNumberOfComponents()!=1)
9701      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9702   offsets->checkAllocated();
9703   if(offsets->getNumberOfComponents()!=1)
9704      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9705   int othNbTuples=offsets->getNumberOfTuples()-1;
9706   int nbOfTuples=getNumberOfTuples();
9707   int retNbOftuples=0;
9708   const int *work=getConstPointer();
9709   const int *offPtr=offsets->getConstPointer();
9710   for(int i=0;i<nbOfTuples;i++)
9711     {
9712       int val=work[i];
9713       if(val>=0 && val<othNbTuples)
9714         {
9715           int delta=offPtr[val+1]-offPtr[val];
9716           if(delta>=0)
9717             retNbOftuples+=delta;
9718           else
9719             {
9720               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9721               throw INTERP_KERNEL::Exception(oss.str().c_str());
9722             }
9723         }
9724       else
9725         {
9726           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9727           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9728           throw INTERP_KERNEL::Exception(oss.str().c_str());
9729         }
9730     }
9731   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9732   ret->alloc(retNbOftuples,1);
9733   int *retPtr=ret->getPointer();
9734   for(int i=0;i<nbOfTuples;i++)
9735     {
9736       int val=work[i];
9737       int start=offPtr[val];
9738       int off=offPtr[val+1]-start;
9739       for(int j=0;j<off;j++,retPtr++)
9740         *retPtr=start+j;
9741     }
9742   return ret.retn();
9743 }
9744
9745 /*!
9746  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9747  * scaled array (monotonically increasing).
9748 from that of \a this and \a
9749  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9750  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9751  * beginning within the "iota" array. And \a this is a one-dimensional array
9752  * considered as a selector of groups described by \a offsets to include into the result array.
9753  *  \throw If \a  is NULL.
9754  *  \throw If \a this is not allocated.
9755  *  \throw If \a this->getNumberOfComponents() != 1.
9756  *  \throw If \a this->getNumberOfTuples() == 0.
9757  *  \throw If \a this is not monotonically increasing.
9758  *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
9759  *
9760  *  \b Example: <br>
9761  *          - \a bg , \a end and \a step : (0,5,2)
9762  *          - \a this: [0,3,6,10,14,20]
9763  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9764  */
9765 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const throw(INTERP_KERNEL::Exception)
9766 {
9767   if(!isAllocated())
9768     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9769   if(getNumberOfComponents()!=1)
9770     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9771   int nbOfTuples(getNumberOfTuples());
9772   if(nbOfTuples==0)
9773     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9774   const int *ids(begin());
9775   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9776   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9777     {
9778       if(pos>=0 && pos<nbOfTuples-1)
9779         {
9780           int delta(ids[pos+1]-ids[pos]);
9781           sz+=delta;
9782           if(delta<0)
9783             {
9784               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9785               throw INTERP_KERNEL::Exception(oss.str().c_str());
9786             }          
9787         }
9788       else
9789         {
9790           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9791           throw INTERP_KERNEL::Exception(oss.str().c_str());
9792         }
9793     }
9794   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9795   int *retPtr(ret->getPointer());
9796   pos=bg;
9797   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9798     {
9799       int delta(ids[pos+1]-ids[pos]);
9800       for(int j=0;j<delta;j++,retPtr++)
9801         *retPtr=pos;
9802     }
9803   return ret.retn();
9804 }
9805
9806 /*!
9807  * 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.
9808  * 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
9809  * in tuple **i** of returned DataArrayInt.
9810  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9811  *
9812  * 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)]
9813  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9814  * 
9815  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9816  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9817  * \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
9818  *        is thrown if no ranges in \a ranges contains value in \a this.
9819  * 
9820  * \sa DataArrayInt::findIdInRangeForEachTuple
9821  */
9822 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9823 {
9824   if(!ranges)
9825     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9826   if(ranges->getNumberOfComponents()!=2)
9827     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9828   checkAllocated();
9829   if(getNumberOfComponents()!=1)
9830     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9831   int nbTuples=getNumberOfTuples();
9832   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9833   int nbOfRanges=ranges->getNumberOfTuples();
9834   const int *rangesPtr=ranges->getConstPointer();
9835   int *retPtr=ret->getPointer();
9836   const int *inPtr=getConstPointer();
9837   for(int i=0;i<nbTuples;i++,retPtr++)
9838     {
9839       int val=inPtr[i];
9840       bool found=false;
9841       for(int j=0;j<nbOfRanges && !found;j++)
9842         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9843           { *retPtr=j; found=true; }
9844       if(found)
9845         continue;
9846       else
9847         {
9848           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9849           throw INTERP_KERNEL::Exception(oss.str().c_str());
9850         }
9851     }
9852   return ret.retn();
9853 }
9854
9855 /*!
9856  * 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.
9857  * 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
9858  * in tuple **i** of returned DataArrayInt.
9859  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9860  *
9861  * 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)]
9862  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9863  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9864  * 
9865  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9866  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9867  * \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
9868  *        is thrown if no ranges in \a ranges contains value in \a this.
9869  * \sa DataArrayInt::findRangeIdForEachTuple
9870  */
9871 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9872 {
9873   if(!ranges)
9874     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9875   if(ranges->getNumberOfComponents()!=2)
9876     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9877   checkAllocated();
9878   if(getNumberOfComponents()!=1)
9879     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9880   int nbTuples=getNumberOfTuples();
9881   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9882   int nbOfRanges=ranges->getNumberOfTuples();
9883   const int *rangesPtr=ranges->getConstPointer();
9884   int *retPtr=ret->getPointer();
9885   const int *inPtr=getConstPointer();
9886   for(int i=0;i<nbTuples;i++,retPtr++)
9887     {
9888       int val=inPtr[i];
9889       bool found=false;
9890       for(int j=0;j<nbOfRanges && !found;j++)
9891         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9892           { *retPtr=val-rangesPtr[2*j]; found=true; }
9893       if(found)
9894         continue;
9895       else
9896         {
9897           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9898           throw INTERP_KERNEL::Exception(oss.str().c_str());
9899         }
9900     }
9901   return ret.retn();
9902 }
9903
9904 /*!
9905  * 
9906  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9907  *             \a nbTimes  should be at least equal to 1.
9908  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9909  * \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.
9910  */
9911 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9912 {
9913   checkAllocated();
9914   if(getNumberOfComponents()!=1)
9915     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9916   if(nbTimes<1)
9917     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9918   int nbTuples=getNumberOfTuples();
9919   const int *inPtr=getConstPointer();
9920   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9921   int *retPtr=ret->getPointer();
9922   for(int i=0;i<nbTuples;i++,inPtr++)
9923     {
9924       int val=*inPtr;
9925       for(int j=0;j<nbTimes;j++,retPtr++)
9926         *retPtr=val;
9927     }
9928   ret->copyStringInfoFrom(*this);
9929   return ret.retn();
9930 }
9931
9932 /*!
9933  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9934  * But the number of components can be different from one.
9935  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9936  */
9937 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9938 {
9939   checkAllocated();
9940   std::set<int> ret;
9941   ret.insert(begin(),end());
9942   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9943   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9944   return ret2.retn();
9945 }
9946
9947 /*!
9948  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9949  * them it tells which tuple id have this id.
9950  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9951  * This method returns two arrays having same size.
9952  * 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.
9953  * 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]]
9954  */
9955 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9956 {
9957   checkAllocated();
9958   if(getNumberOfComponents()!=1)
9959     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9960   int id=0;
9961   std::map<int,int> m,m2,m3;
9962   for(const int *w=begin();w!=end();w++)
9963     m[*w]++;
9964   differentIds.resize(m.size());
9965   std::vector<DataArrayInt *> ret(m.size());
9966   std::vector<int *> retPtr(m.size());
9967   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9968     {
9969       m2[(*it).first]=id;
9970       ret[id]=DataArrayInt::New();
9971       ret[id]->alloc((*it).second,1);
9972       retPtr[id]=ret[id]->getPointer();
9973       differentIds[id]=(*it).first;
9974     }
9975   id=0;
9976   for(const int *w=begin();w!=end();w++,id++)
9977     {
9978       retPtr[m2[*w]][m3[*w]++]=id;
9979     }
9980   return ret;
9981 }
9982
9983 /*!
9984  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
9985  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
9986  *
9987  * \param [in] nbOfSlices - number of slices expected.
9988  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
9989  * 
9990  * \sa DataArray::GetSlice
9991  * \throw If \a this is not allocated or not with exactly one component.
9992  * \throw If an element in \a this if < 0.
9993  */
9994 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception)
9995 {
9996   if(!isAllocated() || getNumberOfComponents()!=1)
9997     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
9998   if(nbOfSlices<=0)
9999     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10000   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10001   int sumPerSlc(sum/nbOfSlices),pos(0);
10002   const int *w(begin());
10003   std::vector< std::pair<int,int> > ret(nbOfSlices);
10004   for(int i=0;i<nbOfSlices;i++)
10005     {
10006       std::pair<int,int> p(pos,-1);
10007       int locSum(0);
10008       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10009       if(i!=nbOfSlices-1)
10010         p.second=pos;
10011       else
10012         p.second=nbOfTuples;
10013       ret[i]=p;
10014     }
10015   return ret;
10016 }
10017
10018 /*!
10019  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10020  * valid cases.
10021  * 1.  The arrays have same number of tuples and components. Then each value of
10022  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10023  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10024  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10025  *   component. Then
10026  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10027  * 3.  The arrays have same number of components and one array, say _a2_, has one
10028  *   tuple. Then
10029  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10030  *
10031  * Info on components is copied either from the first array (in the first case) or from
10032  * the array with maximal number of elements (getNbOfElems()).
10033  *  \param [in] a1 - an array to sum up.
10034  *  \param [in] a2 - another array to sum up.
10035  *  \return DataArrayInt * - the new instance of DataArrayInt.
10036  *          The caller is to delete this result array using decrRef() as it is no more
10037  *          needed.
10038  *  \throw If either \a a1 or \a a2 is NULL.
10039  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10040  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10041  *         none of them has number of tuples or components equal to 1.
10042  */
10043 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10044 {
10045   if(!a1 || !a2)
10046     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10047   int nbOfTuple=a1->getNumberOfTuples();
10048   int nbOfTuple2=a2->getNumberOfTuples();
10049   int nbOfComp=a1->getNumberOfComponents();
10050   int nbOfComp2=a2->getNumberOfComponents();
10051   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10052   if(nbOfTuple==nbOfTuple2)
10053     {
10054       if(nbOfComp==nbOfComp2)
10055         {
10056           ret=DataArrayInt::New();
10057           ret->alloc(nbOfTuple,nbOfComp);
10058           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10059           ret->copyStringInfoFrom(*a1);
10060         }
10061       else
10062         {
10063           int nbOfCompMin,nbOfCompMax;
10064           const DataArrayInt *aMin, *aMax;
10065           if(nbOfComp>nbOfComp2)
10066             {
10067               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10068               aMin=a2; aMax=a1;
10069             }
10070           else
10071             {
10072               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10073               aMin=a1; aMax=a2;
10074             }
10075           if(nbOfCompMin==1)
10076             {
10077               ret=DataArrayInt::New();
10078               ret->alloc(nbOfTuple,nbOfCompMax);
10079               const int *aMinPtr=aMin->getConstPointer();
10080               const int *aMaxPtr=aMax->getConstPointer();
10081               int *res=ret->getPointer();
10082               for(int i=0;i<nbOfTuple;i++)
10083                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10084               ret->copyStringInfoFrom(*aMax);
10085             }
10086           else
10087             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10088         }
10089     }
10090   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10091     {
10092       if(nbOfComp==nbOfComp2)
10093         {
10094           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10095           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10096           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10097           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10098           ret=DataArrayInt::New();
10099           ret->alloc(nbOfTupleMax,nbOfComp);
10100           int *res=ret->getPointer();
10101           for(int i=0;i<nbOfTupleMax;i++)
10102             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10103           ret->copyStringInfoFrom(*aMax);
10104         }
10105       else
10106         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10107     }
10108   else
10109     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10110   return ret.retn();
10111 }
10112
10113 /*!
10114  * Adds values of another DataArrayInt to values of \a this one. There are 3
10115  * valid cases.
10116  * 1.  The arrays have same number of tuples and components. Then each value of
10117  *   \a other array is added to the corresponding value of \a this array, i.e.:
10118  *   _a_ [ i, j ] += _other_ [ i, j ].
10119  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10120  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10121  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10122  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10123  *
10124  *  \param [in] other - an array to add to \a this one.
10125  *  \throw If \a other is NULL.
10126  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10127  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10128  *         \a other has number of both tuples and components not equal to 1.
10129  */
10130 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10131 {
10132   if(!other)
10133     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10134   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10135   checkAllocated(); other->checkAllocated();
10136   int nbOfTuple=getNumberOfTuples();
10137   int nbOfTuple2=other->getNumberOfTuples();
10138   int nbOfComp=getNumberOfComponents();
10139   int nbOfComp2=other->getNumberOfComponents();
10140   if(nbOfTuple==nbOfTuple2)
10141     {
10142       if(nbOfComp==nbOfComp2)
10143         {
10144           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10145         }
10146       else if(nbOfComp2==1)
10147         {
10148           int *ptr=getPointer();
10149           const int *ptrc=other->getConstPointer();
10150           for(int i=0;i<nbOfTuple;i++)
10151             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10152         }
10153       else
10154         throw INTERP_KERNEL::Exception(msg);
10155     }
10156   else if(nbOfTuple2==1)
10157     {
10158       if(nbOfComp2==nbOfComp)
10159         {
10160           int *ptr=getPointer();
10161           const int *ptrc=other->getConstPointer();
10162           for(int i=0;i<nbOfTuple;i++)
10163             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10164         }
10165       else
10166         throw INTERP_KERNEL::Exception(msg);
10167     }
10168   else
10169     throw INTERP_KERNEL::Exception(msg);
10170   declareAsNew();
10171 }
10172
10173 /*!
10174  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10175  * valid cases.
10176  * 1.  The arrays have same number of tuples and components. Then each value of
10177  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10178  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10179  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10180  *   component. Then
10181  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10182  * 3.  The arrays have same number of components and one array, say _a2_, has one
10183  *   tuple. Then
10184  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10185  *
10186  * Info on components is copied either from the first array (in the first case) or from
10187  * the array with maximal number of elements (getNbOfElems()).
10188  *  \param [in] a1 - an array to subtract from.
10189  *  \param [in] a2 - an array to subtract.
10190  *  \return DataArrayInt * - the new instance of DataArrayInt.
10191  *          The caller is to delete this result array using decrRef() as it is no more
10192  *          needed.
10193  *  \throw If either \a a1 or \a a2 is NULL.
10194  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10195  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10196  *         none of them has number of tuples or components equal to 1.
10197  */
10198 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10199 {
10200   if(!a1 || !a2)
10201     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10202   int nbOfTuple1=a1->getNumberOfTuples();
10203   int nbOfTuple2=a2->getNumberOfTuples();
10204   int nbOfComp1=a1->getNumberOfComponents();
10205   int nbOfComp2=a2->getNumberOfComponents();
10206   if(nbOfTuple2==nbOfTuple1)
10207     {
10208       if(nbOfComp1==nbOfComp2)
10209         {
10210           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10211           ret->alloc(nbOfTuple2,nbOfComp1);
10212           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10213           ret->copyStringInfoFrom(*a1);
10214           return ret.retn();
10215         }
10216       else if(nbOfComp2==1)
10217         {
10218           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10219           ret->alloc(nbOfTuple1,nbOfComp1);
10220           const int *a2Ptr=a2->getConstPointer();
10221           const int *a1Ptr=a1->getConstPointer();
10222           int *res=ret->getPointer();
10223           for(int i=0;i<nbOfTuple1;i++)
10224             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10225           ret->copyStringInfoFrom(*a1);
10226           return ret.retn();
10227         }
10228       else
10229         {
10230           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10231           return 0;
10232         }
10233     }
10234   else if(nbOfTuple2==1)
10235     {
10236       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10237       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10238       ret->alloc(nbOfTuple1,nbOfComp1);
10239       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10240       int *pt=ret->getPointer();
10241       for(int i=0;i<nbOfTuple1;i++)
10242         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10243       ret->copyStringInfoFrom(*a1);
10244       return ret.retn();
10245     }
10246   else
10247     {
10248       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10249       return 0;
10250     }
10251 }
10252
10253 /*!
10254  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10255  * valid cases.
10256  * 1.  The arrays have same number of tuples and components. Then each value of
10257  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10258  *   _a_ [ i, j ] -= _other_ [ i, j ].
10259  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10260  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10261  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10262  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10263  *
10264  *  \param [in] other - an array to subtract from \a this one.
10265  *  \throw If \a other is NULL.
10266  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10267  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10268  *         \a other has number of both tuples and components not equal to 1.
10269  */
10270 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10271 {
10272   if(!other)
10273     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10274   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10275   checkAllocated(); other->checkAllocated();
10276   int nbOfTuple=getNumberOfTuples();
10277   int nbOfTuple2=other->getNumberOfTuples();
10278   int nbOfComp=getNumberOfComponents();
10279   int nbOfComp2=other->getNumberOfComponents();
10280   if(nbOfTuple==nbOfTuple2)
10281     {
10282       if(nbOfComp==nbOfComp2)
10283         {
10284           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10285         }
10286       else if(nbOfComp2==1)
10287         {
10288           int *ptr=getPointer();
10289           const int *ptrc=other->getConstPointer();
10290           for(int i=0;i<nbOfTuple;i++)
10291             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10292         }
10293       else
10294         throw INTERP_KERNEL::Exception(msg);
10295     }
10296   else if(nbOfTuple2==1)
10297     {
10298       int *ptr=getPointer();
10299       const int *ptrc=other->getConstPointer();
10300       for(int i=0;i<nbOfTuple;i++)
10301         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10302     }
10303   else
10304     throw INTERP_KERNEL::Exception(msg);
10305   declareAsNew();
10306 }
10307
10308 /*!
10309  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10310  * valid cases.
10311  * 1.  The arrays have same number of tuples and components. Then each value of
10312  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10313  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10314  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10315  *   component. Then
10316  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10317  * 3.  The arrays have same number of components and one array, say _a2_, has one
10318  *   tuple. Then
10319  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10320  *
10321  * Info on components is copied either from the first array (in the first case) or from
10322  * the array with maximal number of elements (getNbOfElems()).
10323  *  \param [in] a1 - a factor array.
10324  *  \param [in] a2 - another factor array.
10325  *  \return DataArrayInt * - the new instance of DataArrayInt.
10326  *          The caller is to delete this result array using decrRef() as it is no more
10327  *          needed.
10328  *  \throw If either \a a1 or \a a2 is NULL.
10329  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10330  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10331  *         none of them has number of tuples or components equal to 1.
10332  */
10333 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10334 {
10335   if(!a1 || !a2)
10336     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10337   int nbOfTuple=a1->getNumberOfTuples();
10338   int nbOfTuple2=a2->getNumberOfTuples();
10339   int nbOfComp=a1->getNumberOfComponents();
10340   int nbOfComp2=a2->getNumberOfComponents();
10341   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10342   if(nbOfTuple==nbOfTuple2)
10343     {
10344       if(nbOfComp==nbOfComp2)
10345         {
10346           ret=DataArrayInt::New();
10347           ret->alloc(nbOfTuple,nbOfComp);
10348           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10349           ret->copyStringInfoFrom(*a1);
10350         }
10351       else
10352         {
10353           int nbOfCompMin,nbOfCompMax;
10354           const DataArrayInt *aMin, *aMax;
10355           if(nbOfComp>nbOfComp2)
10356             {
10357               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10358               aMin=a2; aMax=a1;
10359             }
10360           else
10361             {
10362               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10363               aMin=a1; aMax=a2;
10364             }
10365           if(nbOfCompMin==1)
10366             {
10367               ret=DataArrayInt::New();
10368               ret->alloc(nbOfTuple,nbOfCompMax);
10369               const int *aMinPtr=aMin->getConstPointer();
10370               const int *aMaxPtr=aMax->getConstPointer();
10371               int *res=ret->getPointer();
10372               for(int i=0;i<nbOfTuple;i++)
10373                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10374               ret->copyStringInfoFrom(*aMax);
10375             }
10376           else
10377             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10378         }
10379     }
10380   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10381     {
10382       if(nbOfComp==nbOfComp2)
10383         {
10384           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10385           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10386           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10387           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10388           ret=DataArrayInt::New();
10389           ret->alloc(nbOfTupleMax,nbOfComp);
10390           int *res=ret->getPointer();
10391           for(int i=0;i<nbOfTupleMax;i++)
10392             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10393           ret->copyStringInfoFrom(*aMax);
10394         }
10395       else
10396         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10397     }
10398   else
10399     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10400   return ret.retn();
10401 }
10402
10403
10404 /*!
10405  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10406  * valid cases.
10407  * 1.  The arrays have same number of tuples and components. Then each value of
10408  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10409  *   _a_ [ i, j ] *= _other_ [ i, j ].
10410  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10411  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10412  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10413  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10414  *
10415  *  \param [in] other - an array to multiply to \a this one.
10416  *  \throw If \a other is NULL.
10417  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10418  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10419  *         \a other has number of both tuples and components not equal to 1.
10420  */
10421 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10422 {
10423   if(!other)
10424     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10425   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10426   checkAllocated(); other->checkAllocated();
10427   int nbOfTuple=getNumberOfTuples();
10428   int nbOfTuple2=other->getNumberOfTuples();
10429   int nbOfComp=getNumberOfComponents();
10430   int nbOfComp2=other->getNumberOfComponents();
10431   if(nbOfTuple==nbOfTuple2)
10432     {
10433       if(nbOfComp==nbOfComp2)
10434         {
10435           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10436         }
10437       else if(nbOfComp2==1)
10438         {
10439           int *ptr=getPointer();
10440           const int *ptrc=other->getConstPointer();
10441           for(int i=0;i<nbOfTuple;i++)
10442             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10443         }
10444       else
10445         throw INTERP_KERNEL::Exception(msg);
10446     }
10447   else if(nbOfTuple2==1)
10448     {
10449       if(nbOfComp2==nbOfComp)
10450         {
10451           int *ptr=getPointer();
10452           const int *ptrc=other->getConstPointer();
10453           for(int i=0;i<nbOfTuple;i++)
10454             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10455         }
10456       else
10457         throw INTERP_KERNEL::Exception(msg);
10458     }
10459   else
10460     throw INTERP_KERNEL::Exception(msg);
10461   declareAsNew();
10462 }
10463
10464
10465 /*!
10466  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10467  * valid cases.
10468  * 1.  The arrays have same number of tuples and components. Then each value of
10469  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10470  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10471  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10472  *   component. Then
10473  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10474  * 3.  The arrays have same number of components and one array, say _a2_, has one
10475  *   tuple. Then
10476  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10477  *
10478  * Info on components is copied either from the first array (in the first case) or from
10479  * the array with maximal number of elements (getNbOfElems()).
10480  *  \warning No check of division by zero is performed!
10481  *  \param [in] a1 - a numerator array.
10482  *  \param [in] a2 - a denominator array.
10483  *  \return DataArrayInt * - the new instance of DataArrayInt.
10484  *          The caller is to delete this result array using decrRef() as it is no more
10485  *          needed.
10486  *  \throw If either \a a1 or \a a2 is NULL.
10487  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10488  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10489  *         none of them has number of tuples or components equal to 1.
10490  */
10491 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10492 {
10493   if(!a1 || !a2)
10494     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10495   int nbOfTuple1=a1->getNumberOfTuples();
10496   int nbOfTuple2=a2->getNumberOfTuples();
10497   int nbOfComp1=a1->getNumberOfComponents();
10498   int nbOfComp2=a2->getNumberOfComponents();
10499   if(nbOfTuple2==nbOfTuple1)
10500     {
10501       if(nbOfComp1==nbOfComp2)
10502         {
10503           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10504           ret->alloc(nbOfTuple2,nbOfComp1);
10505           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10506           ret->copyStringInfoFrom(*a1);
10507           return ret.retn();
10508         }
10509       else if(nbOfComp2==1)
10510         {
10511           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10512           ret->alloc(nbOfTuple1,nbOfComp1);
10513           const int *a2Ptr=a2->getConstPointer();
10514           const int *a1Ptr=a1->getConstPointer();
10515           int *res=ret->getPointer();
10516           for(int i=0;i<nbOfTuple1;i++)
10517             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10518           ret->copyStringInfoFrom(*a1);
10519           return ret.retn();
10520         }
10521       else
10522         {
10523           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10524           return 0;
10525         }
10526     }
10527   else if(nbOfTuple2==1)
10528     {
10529       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10530       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10531       ret->alloc(nbOfTuple1,nbOfComp1);
10532       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10533       int *pt=ret->getPointer();
10534       for(int i=0;i<nbOfTuple1;i++)
10535         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10536       ret->copyStringInfoFrom(*a1);
10537       return ret.retn();
10538     }
10539   else
10540     {
10541       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10542       return 0;
10543     }
10544 }
10545
10546 /*!
10547  * Divide values of \a this array by values of another DataArrayInt. There are 3
10548  * valid cases.
10549  * 1.  The arrays have same number of tuples and components. Then each value of
10550  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10551  *   _a_ [ i, j ] /= _other_ [ i, j ].
10552  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10553  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10554  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10555  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10556  *
10557  *  \warning No check of division by zero is performed!
10558  *  \param [in] other - an array to divide \a this one by.
10559  *  \throw If \a other is NULL.
10560  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10561  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10562  *         \a other has number of both tuples and components not equal to 1.
10563  */
10564 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10565 {
10566   if(!other)
10567     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10568   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10569   checkAllocated(); other->checkAllocated();
10570   int nbOfTuple=getNumberOfTuples();
10571   int nbOfTuple2=other->getNumberOfTuples();
10572   int nbOfComp=getNumberOfComponents();
10573   int nbOfComp2=other->getNumberOfComponents();
10574   if(nbOfTuple==nbOfTuple2)
10575     {
10576       if(nbOfComp==nbOfComp2)
10577         {
10578           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10579         }
10580       else if(nbOfComp2==1)
10581         {
10582           int *ptr=getPointer();
10583           const int *ptrc=other->getConstPointer();
10584           for(int i=0;i<nbOfTuple;i++)
10585             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10586         }
10587       else
10588         throw INTERP_KERNEL::Exception(msg);
10589     }
10590   else if(nbOfTuple2==1)
10591     {
10592       if(nbOfComp2==nbOfComp)
10593         {
10594           int *ptr=getPointer();
10595           const int *ptrc=other->getConstPointer();
10596           for(int i=0;i<nbOfTuple;i++)
10597             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10598         }
10599       else
10600         throw INTERP_KERNEL::Exception(msg);
10601     }
10602   else
10603     throw INTERP_KERNEL::Exception(msg);
10604   declareAsNew();
10605 }
10606
10607
10608 /*!
10609  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10610  * valid cases.
10611  * 1.  The arrays have same number of tuples and components. Then each value of
10612  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10613  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10614  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10615  *   component. Then
10616  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10617  * 3.  The arrays have same number of components and one array, say _a2_, has one
10618  *   tuple. Then
10619  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10620  *
10621  * Info on components is copied either from the first array (in the first case) or from
10622  * the array with maximal number of elements (getNbOfElems()).
10623  *  \warning No check of division by zero is performed!
10624  *  \param [in] a1 - a dividend array.
10625  *  \param [in] a2 - a divisor array.
10626  *  \return DataArrayInt * - the new instance of DataArrayInt.
10627  *          The caller is to delete this result array using decrRef() as it is no more
10628  *          needed.
10629  *  \throw If either \a a1 or \a a2 is NULL.
10630  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10631  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10632  *         none of them has number of tuples or components equal to 1.
10633  */
10634 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10635 {
10636     if(!a1 || !a2)
10637     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10638   int nbOfTuple1=a1->getNumberOfTuples();
10639   int nbOfTuple2=a2->getNumberOfTuples();
10640   int nbOfComp1=a1->getNumberOfComponents();
10641   int nbOfComp2=a2->getNumberOfComponents();
10642   if(nbOfTuple2==nbOfTuple1)
10643     {
10644       if(nbOfComp1==nbOfComp2)
10645         {
10646           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10647           ret->alloc(nbOfTuple2,nbOfComp1);
10648           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10649           ret->copyStringInfoFrom(*a1);
10650           return ret.retn();
10651         }
10652       else if(nbOfComp2==1)
10653         {
10654           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10655           ret->alloc(nbOfTuple1,nbOfComp1);
10656           const int *a2Ptr=a2->getConstPointer();
10657           const int *a1Ptr=a1->getConstPointer();
10658           int *res=ret->getPointer();
10659           for(int i=0;i<nbOfTuple1;i++)
10660             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10661           ret->copyStringInfoFrom(*a1);
10662           return ret.retn();
10663         }
10664       else
10665         {
10666           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10667           return 0;
10668         }
10669     }
10670   else if(nbOfTuple2==1)
10671     {
10672       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10673       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10674       ret->alloc(nbOfTuple1,nbOfComp1);
10675       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10676       int *pt=ret->getPointer();
10677       for(int i=0;i<nbOfTuple1;i++)
10678         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10679       ret->copyStringInfoFrom(*a1);
10680       return ret.retn();
10681     }
10682   else
10683     {
10684       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10685       return 0;
10686     }
10687 }
10688
10689 /*!
10690  * Modify \a this array so that each value becomes a modulus of division of this value by
10691  * a value of another DataArrayInt. There are 3 valid cases.
10692  * 1.  The arrays have same number of tuples and components. Then each value of
10693  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10694  *   _a_ [ i, j ] %= _other_ [ i, j ].
10695  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10696  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10697  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10698  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10699  *
10700  *  \warning No check of division by zero is performed!
10701  *  \param [in] other - a divisor array.
10702  *  \throw If \a other is NULL.
10703  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10704  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10705  *         \a other has number of both tuples and components not equal to 1.
10706  */
10707 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10708 {
10709   if(!other)
10710     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10711   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10712   checkAllocated(); other->checkAllocated();
10713   int nbOfTuple=getNumberOfTuples();
10714   int nbOfTuple2=other->getNumberOfTuples();
10715   int nbOfComp=getNumberOfComponents();
10716   int nbOfComp2=other->getNumberOfComponents();
10717   if(nbOfTuple==nbOfTuple2)
10718     {
10719       if(nbOfComp==nbOfComp2)
10720         {
10721           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10722         }
10723       else if(nbOfComp2==1)
10724         {
10725           if(nbOfComp2==nbOfComp)
10726             {
10727               int *ptr=getPointer();
10728               const int *ptrc=other->getConstPointer();
10729               for(int i=0;i<nbOfTuple;i++)
10730                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10731             }
10732           else
10733             throw INTERP_KERNEL::Exception(msg);
10734         }
10735       else
10736         throw INTERP_KERNEL::Exception(msg);
10737     }
10738   else if(nbOfTuple2==1)
10739     {
10740       int *ptr=getPointer();
10741       const int *ptrc=other->getConstPointer();
10742       for(int i=0;i<nbOfTuple;i++)
10743         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10744     }
10745   else
10746     throw INTERP_KERNEL::Exception(msg);
10747   declareAsNew();
10748 }
10749
10750 /*!
10751  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10752  * valid cases.
10753  *
10754  *  \param [in] a1 - an array to pow up.
10755  *  \param [in] a2 - another array to sum up.
10756  *  \return DataArrayInt * - the new instance of DataArrayInt.
10757  *          The caller is to delete this result array using decrRef() as it is no more
10758  *          needed.
10759  *  \throw If either \a a1 or \a a2 is NULL.
10760  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10761  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10762  *  \throw If there is a negative value in \a a2.
10763  */
10764 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10765 {
10766   if(!a1 || !a2)
10767     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10768   int nbOfTuple=a1->getNumberOfTuples();
10769   int nbOfTuple2=a2->getNumberOfTuples();
10770   int nbOfComp=a1->getNumberOfComponents();
10771   int nbOfComp2=a2->getNumberOfComponents();
10772   if(nbOfTuple!=nbOfTuple2)
10773     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10774   if(nbOfComp!=1 || nbOfComp2!=1)
10775     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10776   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10777   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10778   int *ptr=ret->getPointer();
10779   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10780     {
10781       if(*ptr2>=0)
10782         {
10783           int tmp=1;
10784           for(int j=0;j<*ptr2;j++)
10785             tmp*=*ptr1;
10786           *ptr=tmp;
10787         }
10788       else
10789         {
10790           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10791           throw INTERP_KERNEL::Exception(oss.str().c_str());
10792         }
10793     }
10794   return ret.retn();
10795 }
10796
10797 /*!
10798  * Apply pow on values of another DataArrayInt to values of \a this one.
10799  *
10800  *  \param [in] other - an array to pow to \a this one.
10801  *  \throw If \a other is NULL.
10802  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10803  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10804  *  \throw If there is a negative value in \a other.
10805  */
10806 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10807 {
10808   if(!other)
10809     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10810   int nbOfTuple=getNumberOfTuples();
10811   int nbOfTuple2=other->getNumberOfTuples();
10812   int nbOfComp=getNumberOfComponents();
10813   int nbOfComp2=other->getNumberOfComponents();
10814   if(nbOfTuple!=nbOfTuple2)
10815     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10816   if(nbOfComp!=1 || nbOfComp2!=1)
10817     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10818   int *ptr=getPointer();
10819   const int *ptrc=other->begin();
10820   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10821     {
10822       if(*ptrc>=0)
10823         {
10824           int tmp=1;
10825           for(int j=0;j<*ptrc;j++)
10826             tmp*=*ptr;
10827           *ptr=tmp;
10828         }
10829       else
10830         {
10831           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10832           throw INTERP_KERNEL::Exception(oss.str().c_str());
10833         }
10834     }
10835   declareAsNew();
10836 }
10837
10838 /*!
10839  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10840  * This map, if applied to \a start array, would make it sorted. For example, if
10841  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10842  * [5,6,0,3,2,7,1,4].
10843  *  \param [in] start - pointer to the first element of the array for which the
10844  *         permutation map is computed.
10845  *  \param [in] end - pointer specifying the end of the array \a start, so that
10846  *         the last value of \a start is \a end[ -1 ].
10847  *  \return int * - the result permutation array that the caller is to delete as it is no
10848  *         more needed.
10849  *  \throw If there are equal values in the input array.
10850  */
10851 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10852 {
10853   std::size_t sz=std::distance(start,end);
10854   int *ret=(int *)malloc(sz*sizeof(int));
10855   int *work=new int[sz];
10856   std::copy(start,end,work);
10857   std::sort(work,work+sz);
10858   if(std::unique(work,work+sz)!=work+sz)
10859     {
10860       delete [] work;
10861       free(ret);
10862       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10863     }
10864   std::map<int,int> m;
10865   for(int *workPt=work;workPt!=work+sz;workPt++)
10866     m[*workPt]=(int)std::distance(work,workPt);
10867   int *iter2=ret;
10868   for(const int *iter=start;iter!=end;iter++,iter2++)
10869     *iter2=m[*iter];
10870   delete [] work;
10871   return ret;
10872 }
10873
10874 /*!
10875  * Returns a new DataArrayInt containing an arithmetic progression
10876  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10877  * function.
10878  *  \param [in] begin - the start value of the result sequence.
10879  *  \param [in] end - limiting value, so that every value of the result array is less than
10880  *              \a end.
10881  *  \param [in] step - specifies the increment or decrement.
10882  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10883  *          array using decrRef() as it is no more needed.
10884  *  \throw If \a step == 0.
10885  *  \throw If \a end < \a begin && \a step > 0.
10886  *  \throw If \a end > \a begin && \a step < 0.
10887  */
10888 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10889 {
10890   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10891   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10892   ret->alloc(nbOfTuples,1);
10893   int *ptr=ret->getPointer();
10894   if(step>0)
10895     {
10896       for(int i=begin;i<end;i+=step,ptr++)
10897         *ptr=i;
10898     }
10899   else
10900     {
10901       for(int i=begin;i>end;i+=step,ptr++)
10902         *ptr=i;
10903     }
10904   return ret.retn();
10905 }
10906
10907 /*!
10908  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10909  * Server side.
10910  */
10911 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10912 {
10913   tinyInfo.resize(2);
10914   if(isAllocated())
10915     {
10916       tinyInfo[0]=getNumberOfTuples();
10917       tinyInfo[1]=getNumberOfComponents();
10918     }
10919   else
10920     {
10921       tinyInfo[0]=-1;
10922       tinyInfo[1]=-1;
10923     }
10924 }
10925
10926 /*!
10927  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10928  * Server side.
10929  */
10930 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10931 {
10932   if(isAllocated())
10933     {
10934       int nbOfCompo=getNumberOfComponents();
10935       tinyInfo.resize(nbOfCompo+1);
10936       tinyInfo[0]=getName();
10937       for(int i=0;i<nbOfCompo;i++)
10938         tinyInfo[i+1]=getInfoOnComponent(i);
10939     }
10940   else
10941     {
10942       tinyInfo.resize(1);
10943       tinyInfo[0]=getName();
10944     }
10945 }
10946
10947 /*!
10948  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10949  * This method returns if a feeding is needed.
10950  */
10951 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10952 {
10953   int nbOfTuple=tinyInfoI[0];
10954   int nbOfComp=tinyInfoI[1];
10955   if(nbOfTuple!=-1 || nbOfComp!=-1)
10956     {
10957       alloc(nbOfTuple,nbOfComp);
10958       return true;
10959     }
10960   return false;
10961 }
10962
10963 /*!
10964  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10965  * This method returns if a feeding is needed.
10966  */
10967 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10968 {
10969   setName(tinyInfoS[0].c_str());
10970   if(isAllocated())
10971     {
10972       int nbOfCompo=tinyInfoI[1];
10973       for(int i=0;i<nbOfCompo;i++)
10974         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10975     }
10976 }
10977
10978 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10979 {
10980   if(_da)
10981     {
10982       _da->incrRef();
10983       if(_da->isAllocated())
10984         {
10985           _nb_comp=da->getNumberOfComponents();
10986           _nb_tuple=da->getNumberOfTuples();
10987           _pt=da->getPointer();
10988         }
10989     }
10990 }
10991
10992 DataArrayIntIterator::~DataArrayIntIterator()
10993 {
10994   if(_da)
10995     _da->decrRef();
10996 }
10997
10998 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10999 {
11000   if(_tuple_id<_nb_tuple)
11001     {
11002       _tuple_id++;
11003       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11004       _pt+=_nb_comp;
11005       return ret;
11006     }
11007   else
11008     return 0;
11009 }
11010
11011 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11012 {
11013 }
11014
11015 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
11016 {
11017   std::ostringstream oss; oss << "(";
11018   for(int i=0;i<_nb_of_compo-1;i++)
11019     oss << _pt[i] << ", ";
11020   oss << _pt[_nb_of_compo-1] << ")";
11021   return oss.str();
11022 }
11023
11024 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
11025 {
11026   if(_nb_of_compo==1)
11027     return *_pt;
11028   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11029 }
11030
11031 /*!
11032  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11033  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11034  * 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
11035  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11036  */
11037 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
11038 {
11039   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11040     {
11041       DataArrayInt *ret=DataArrayInt::New();
11042       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11043       return ret;
11044     }
11045   else
11046     {
11047       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11048       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11049       throw INTERP_KERNEL::Exception(oss.str().c_str());
11050     }
11051 }