Salome HOME
DataArrayDouble::normMin, DataArrayDouble::computeAbs, DataArrayInt::computeAbs
[modules/med.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)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const char *varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * 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)
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)
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)
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
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
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
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
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
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)
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)
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)
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)
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)
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)
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)
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
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
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()
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
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
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
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
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)
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)
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)
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)
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()
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
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)
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)
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()
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)
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)
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
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)
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()
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
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
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
1140 {
1141   std::ostringstream ret;
1142   reprStream(ret);
1143   return ret.str();
1144 }
1145
1146 std::string DataArrayDouble::reprZip() const
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
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       float *pt(tmp);
1165       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1166       for(const double *src=begin();src!=end();src++,pt++)
1167         *pt=float(*src);
1168       const char *data(reinterpret_cast<const char *>((float *)tmp));
1169       std::size_t sz(getNbOfElems()*sizeof(float));
1170       byteArr->insertAtTheEnd(data,data+sz);
1171       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1172     }
1173   else
1174     {
1175       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1176       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1177     }
1178   ofs << std::endl << idt << "</DataArray>\n";
1179 }
1180
1181 void DataArrayDouble::reprStream(std::ostream& stream) const
1182 {
1183   stream << "Name of double array : \"" << _name << "\"\n";
1184   reprWithoutNameStream(stream);
1185 }
1186
1187 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1188 {
1189   stream << "Name of double array : \"" << _name << "\"\n";
1190   reprZipWithoutNameStream(stream);
1191 }
1192
1193 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1194 {
1195   DataArray::reprWithoutNameStream(stream);
1196   stream.precision(17);
1197   _mem.repr(getNumberOfComponents(),stream);
1198 }
1199
1200 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1201 {
1202   DataArray::reprWithoutNameStream(stream);
1203   stream.precision(17);
1204   _mem.reprZip(getNumberOfComponents(),stream);
1205 }
1206
1207 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const
1208 {
1209   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1210   const double *data=getConstPointer();
1211   stream.precision(17);
1212   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1213   if(nbTuples*nbComp>=1)
1214     {
1215       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1216       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1217       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1218       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1219     }
1220   else
1221     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1222   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1223 }
1224
1225 /*!
1226  * Method that gives a quick overvien of \a this for python.
1227  */
1228 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1229 {
1230   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1231   stream << "DataArrayDouble C++ instance at " << this << ". ";
1232   if(isAllocated())
1233     {
1234       int nbOfCompo=(int)_info_on_compo.size();
1235       if(nbOfCompo>=1)
1236         {
1237           int nbOfTuples=getNumberOfTuples();
1238           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1239           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1240         }
1241       else
1242         stream << "Number of components : 0.";
1243     }
1244   else
1245     stream << "*** No data allocated ****";
1246 }
1247
1248 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1249 {
1250   const double *data=begin();
1251   int nbOfTuples=getNumberOfTuples();
1252   int nbOfCompo=(int)_info_on_compo.size();
1253   std::ostringstream oss2; oss2 << "[";
1254   oss2.precision(17);
1255   std::string oss2Str(oss2.str());
1256   bool isFinished=true;
1257   for(int i=0;i<nbOfTuples && isFinished;i++)
1258     {
1259       if(nbOfCompo>1)
1260         {
1261           oss2 << "(";
1262           for(int j=0;j<nbOfCompo;j++,data++)
1263             {
1264               oss2 << *data;
1265               if(j!=nbOfCompo-1) oss2 << ", ";
1266             }
1267           oss2 << ")";
1268         }
1269       else
1270         oss2 << *data++;
1271       if(i!=nbOfTuples-1) oss2 << ", ";
1272       std::string oss3Str(oss2.str());
1273       if(oss3Str.length()<maxNbOfByteInRepr)
1274         oss2Str=oss3Str;
1275       else
1276         isFinished=false;
1277     }
1278   stream << oss2Str;
1279   if(!isFinished)
1280     stream << "... ";
1281   stream << "]";
1282 }
1283
1284 /*!
1285  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1286  * mismatch is given.
1287  * 
1288  * \param [in] other the instance to be compared with \a this
1289  * \param [in] prec the precision to compare numeric data of the arrays.
1290  * \param [out] reason In case of inequality returns the reason.
1291  * \sa DataArrayDouble::isEqual
1292  */
1293 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1294 {
1295   if(!areInfoEqualsIfNotWhy(other,reason))
1296     return false;
1297   return _mem.isEqual(other._mem,prec,reason);
1298 }
1299
1300 /*!
1301  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1302  * \ref MEDCouplingArrayBasicsCompare.
1303  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1304  *  \param [in] prec - precision value to compare numeric data of the arrays.
1305  *  \return bool - \a true if the two arrays are equal, \a false else.
1306  */
1307 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1308 {
1309   std::string tmp;
1310   return isEqualIfNotWhy(other,prec,tmp);
1311 }
1312
1313 /*!
1314  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1315  * \ref MEDCouplingArrayBasicsCompare.
1316  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1317  *  \param [in] prec - precision value to compare numeric data of the arrays.
1318  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1319  */
1320 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1321 {
1322   std::string tmp;
1323   return _mem.isEqual(other._mem,prec,tmp);
1324 }
1325
1326 /*!
1327  * Changes number of tuples in the array. If the new number of tuples is smaller
1328  * than the current number the array is truncated, otherwise the array is extended.
1329  *  \param [in] nbOfTuples - new number of tuples. 
1330  *  \throw If \a this is not allocated.
1331  *  \throw If \a nbOfTuples is negative.
1332  */
1333 void DataArrayDouble::reAlloc(int nbOfTuples)
1334 {
1335   if(nbOfTuples<0)
1336     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1337   checkAllocated();
1338   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1339   declareAsNew();
1340 }
1341
1342 /*!
1343  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1344  * array to the new one.
1345  *  \return DataArrayInt * - the new instance of DataArrayInt.
1346  */
1347 DataArrayInt *DataArrayDouble::convertToIntArr() const
1348 {
1349   DataArrayInt *ret=DataArrayInt::New();
1350   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1351   int *dest=ret->getPointer();
1352   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1353   for(const double *src=begin();src!=end();src++,dest++)
1354     *dest=(int)*src;
1355   ret->copyStringInfoFrom(*this);
1356   return ret;
1357 }
1358
1359 /*!
1360  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1361  * arranged in memory. If \a this array holds 2 components of 3 values:
1362  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1363  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1364  *  \warning Do not confuse this method with transpose()!
1365  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1366  *          is to delete using decrRef() as it is no more needed.
1367  *  \throw If \a this is not allocated.
1368  */
1369 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1370 {
1371   if(_mem.isNull())
1372     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1373   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1374   DataArrayDouble *ret=DataArrayDouble::New();
1375   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1376   return ret;
1377 }
1378
1379 /*!
1380  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1381  * arranged in memory. If \a this array holds 2 components of 3 values:
1382  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1383  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1384  *  \warning Do not confuse this method with transpose()!
1385  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1386  *          is to delete using decrRef() as it is no more needed.
1387  *  \throw If \a this is not allocated.
1388  */
1389 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1390 {
1391   if(_mem.isNull())
1392     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1393   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1394   DataArrayDouble *ret=DataArrayDouble::New();
1395   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1396   return ret;
1397 }
1398
1399 /*!
1400  * Permutes values of \a this array as required by \a old2New array. The values are
1401  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1402  * the same as in \this one.
1403  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1404  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1405  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1406  *     giving a new position for i-th old value.
1407  */
1408 void DataArrayDouble::renumberInPlace(const int *old2New)
1409 {
1410   checkAllocated();
1411   int nbTuples=getNumberOfTuples();
1412   int nbOfCompo=getNumberOfComponents();
1413   double *tmp=new double[nbTuples*nbOfCompo];
1414   const double *iptr=getConstPointer();
1415   for(int i=0;i<nbTuples;i++)
1416     {
1417       int v=old2New[i];
1418       if(v>=0 && v<nbTuples)
1419         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1420       else
1421         {
1422           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1423           throw INTERP_KERNEL::Exception(oss.str().c_str());
1424         }
1425     }
1426   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1427   delete [] tmp;
1428   declareAsNew();
1429 }
1430
1431 /*!
1432  * Permutes values of \a this array as required by \a new2Old array. The values are
1433  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1434  * the same as in \this one.
1435  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1436  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1437  *     giving a previous position of i-th new value.
1438  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1439  *          is to delete using decrRef() as it is no more needed.
1440  */
1441 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1442 {
1443   checkAllocated();
1444   int nbTuples=getNumberOfTuples();
1445   int nbOfCompo=getNumberOfComponents();
1446   double *tmp=new double[nbTuples*nbOfCompo];
1447   const double *iptr=getConstPointer();
1448   for(int i=0;i<nbTuples;i++)
1449     {
1450       int v=new2Old[i];
1451       if(v>=0 && v<nbTuples)
1452         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1453       else
1454         {
1455           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1456           throw INTERP_KERNEL::Exception(oss.str().c_str());
1457         }
1458     }
1459   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1460   delete [] tmp;
1461   declareAsNew();
1462 }
1463
1464 /*!
1465  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1466  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1467  * Number of tuples in the result array remains the same as in \this one.
1468  * If a permutation reduction is needed, renumberAndReduce() should be used.
1469  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1470  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1471  *          giving a new position for i-th old value.
1472  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1473  *          is to delete using decrRef() as it is no more needed.
1474  *  \throw If \a this is not allocated.
1475  */
1476 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1477 {
1478   checkAllocated();
1479   int nbTuples=getNumberOfTuples();
1480   int nbOfCompo=getNumberOfComponents();
1481   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1482   ret->alloc(nbTuples,nbOfCompo);
1483   ret->copyStringInfoFrom(*this);
1484   const double *iptr=getConstPointer();
1485   double *optr=ret->getPointer();
1486   for(int i=0;i<nbTuples;i++)
1487     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1488   ret->copyStringInfoFrom(*this);
1489   return ret.retn();
1490 }
1491
1492 /*!
1493  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1494  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1495  * tuples in the result array remains the same as in \this one.
1496  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1497  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1498  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1499  *     giving a previous position of i-th new value.
1500  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1501  *          is to delete using decrRef() as it is no more needed.
1502  */
1503 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1504 {
1505   checkAllocated();
1506   int nbTuples=getNumberOfTuples();
1507   int nbOfCompo=getNumberOfComponents();
1508   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1509   ret->alloc(nbTuples,nbOfCompo);
1510   ret->copyStringInfoFrom(*this);
1511   const double *iptr=getConstPointer();
1512   double *optr=ret->getPointer();
1513   for(int i=0;i<nbTuples;i++)
1514     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1515   ret->copyStringInfoFrom(*this);
1516   return ret.retn();
1517 }
1518
1519 /*!
1520  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1521  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1522  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1523  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1524  * \a old2New[ i ] is negative, is missing from the result array.
1525  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1526  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1527  *     giving a new position for i-th old tuple and giving negative position for
1528  *     for i-th old tuple that should be omitted.
1529  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1530  *          is to delete using decrRef() as it is no more needed.
1531  */
1532 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1533 {
1534   checkAllocated();
1535   int nbTuples=getNumberOfTuples();
1536   int nbOfCompo=getNumberOfComponents();
1537   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1538   ret->alloc(newNbOfTuple,nbOfCompo);
1539   const double *iptr=getConstPointer();
1540   double *optr=ret->getPointer();
1541   for(int i=0;i<nbTuples;i++)
1542     {
1543       int w=old2New[i];
1544       if(w>=0)
1545         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1546     }
1547   ret->copyStringInfoFrom(*this);
1548   return ret.retn();
1549 }
1550
1551 /*!
1552  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1553  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1554  * \a new2OldBg array.
1555  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1556  * This method is equivalent to renumberAndReduce() except that convention in input is
1557  * \c new2old and \b not \c old2new.
1558  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1559  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1560  *              tuple index in \a this array to fill the i-th tuple in the new array.
1561  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1562  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1563  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1564  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1565  *          is to delete using decrRef() as it is no more needed.
1566  */
1567 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1568 {
1569   checkAllocated();
1570   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1571   int nbComp=getNumberOfComponents();
1572   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1573   ret->copyStringInfoFrom(*this);
1574   double *pt=ret->getPointer();
1575   const double *srcPt=getConstPointer();
1576   int i=0;
1577   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1578     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1579   ret->copyStringInfoFrom(*this);
1580   return ret.retn();
1581 }
1582
1583 /*!
1584  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1585  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1586  * \a new2OldBg array.
1587  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1588  * This method is equivalent to renumberAndReduce() except that convention in input is
1589  * \c new2old and \b not \c old2new.
1590  * This method is equivalent to selectByTupleId() except that it prevents coping data
1591  * from behind the end of \a this array.
1592  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1593  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1594  *              tuple index in \a this array to fill the i-th tuple in the new array.
1595  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1596  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1597  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1598  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1599  *          is to delete using decrRef() as it is no more needed.
1600  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1601  */
1602 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1603 {
1604   checkAllocated();
1605   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1606   int nbComp=getNumberOfComponents();
1607   int oldNbOfTuples=getNumberOfTuples();
1608   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1609   ret->copyStringInfoFrom(*this);
1610   double *pt=ret->getPointer();
1611   const double *srcPt=getConstPointer();
1612   int i=0;
1613   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1614     if(*w>=0 && *w<oldNbOfTuples)
1615       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1616     else
1617       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1618   ret->copyStringInfoFrom(*this);
1619   return ret.retn();
1620 }
1621
1622 /*!
1623  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1624  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1625  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1626  * command \c range( \a bg, \a end2, \a step ).
1627  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1628  * not constructed explicitly.
1629  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1630  *  \param [in] bg - index of the first tuple to copy from \a this array.
1631  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1632  *  \param [in] step - index increment to get index of the next tuple to copy.
1633  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1634  *          is to delete using decrRef() as it is no more needed.
1635  *  \sa DataArrayDouble::substr.
1636  */
1637 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1638 {
1639   checkAllocated();
1640   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1641   int nbComp=getNumberOfComponents();
1642   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1643   ret->alloc(newNbOfTuples,nbComp);
1644   double *pt=ret->getPointer();
1645   const double *srcPt=getConstPointer()+bg*nbComp;
1646   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1647     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1648   ret->copyStringInfoFrom(*this);
1649   return ret.retn();
1650 }
1651
1652 /*!
1653  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1654  * of tuples specified by \a ranges parameter.
1655  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1656  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1657  *              of tuples in [\c begin,\c end) format.
1658  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1659  *          is to delete using decrRef() as it is no more needed.
1660  *  \throw If \a end < \a begin.
1661  *  \throw If \a end > \a this->getNumberOfTuples().
1662  *  \throw If \a this is not allocated.
1663  */
1664 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1665 {
1666   checkAllocated();
1667   int nbOfComp=getNumberOfComponents();
1668   int nbOfTuplesThis=getNumberOfTuples();
1669   if(ranges.empty())
1670     {
1671       DataArrayDouble *ret=DataArrayDouble::New();
1672       ret->alloc(0,nbOfComp);
1673       ret->copyStringInfoFrom(*this);
1674       return ret;
1675     }
1676   int ref=ranges.front().first;
1677   int nbOfTuples=0;
1678   bool isIncreasing=true;
1679   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1680     {
1681       if((*it).first<=(*it).second)
1682         {
1683           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1684             {
1685               nbOfTuples+=(*it).second-(*it).first;
1686               if(isIncreasing)
1687                 isIncreasing=ref<=(*it).first;
1688               ref=(*it).second;
1689             }
1690           else
1691             {
1692               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1693               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1694               throw INTERP_KERNEL::Exception(oss.str().c_str());
1695             }
1696         }
1697       else
1698         {
1699           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1700           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1701           throw INTERP_KERNEL::Exception(oss.str().c_str());
1702         }
1703     }
1704   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1705     return deepCpy();
1706   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1707   ret->alloc(nbOfTuples,nbOfComp);
1708   ret->copyStringInfoFrom(*this);
1709   const double *src=getConstPointer();
1710   double *work=ret->getPointer();
1711   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1712     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1713   return ret.retn();
1714 }
1715
1716 /*!
1717  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1718  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1719  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1720  * This method is a specialization of selectByTupleId2().
1721  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1722  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1723  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1724  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1725  *          is to delete using decrRef() as it is no more needed.
1726  *  \throw If \a tupleIdBg < 0.
1727  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1728     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1729  *  \sa DataArrayDouble::selectByTupleId2
1730  */
1731 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1732 {
1733   checkAllocated();
1734   int nbt=getNumberOfTuples();
1735   if(tupleIdBg<0)
1736     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1737   if(tupleIdBg>nbt)
1738     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1739   int trueEnd=tupleIdEnd;
1740   if(tupleIdEnd!=-1)
1741     {
1742       if(tupleIdEnd>nbt)
1743         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1744     }
1745   else
1746     trueEnd=nbt;
1747   int nbComp=getNumberOfComponents();
1748   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1749   ret->alloc(trueEnd-tupleIdBg,nbComp);
1750   ret->copyStringInfoFrom(*this);
1751   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1752   return ret.retn();
1753 }
1754
1755 /*!
1756  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1757  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1758  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1759  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1760  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1761  * components.  
1762  *  \param [in] newNbOfComp - number of components for the new array to have.
1763  *  \param [in] dftValue - value assigned to new values added to the new array.
1764  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1765  *          is to delete using decrRef() as it is no more needed.
1766  *  \throw If \a this is not allocated.
1767  */
1768 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1769 {
1770   checkAllocated();
1771   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1772   ret->alloc(getNumberOfTuples(),newNbOfComp);
1773   const double *oldc=getConstPointer();
1774   double *nc=ret->getPointer();
1775   int nbOfTuples=getNumberOfTuples();
1776   int oldNbOfComp=getNumberOfComponents();
1777   int dim=std::min(oldNbOfComp,newNbOfComp);
1778   for(int i=0;i<nbOfTuples;i++)
1779     {
1780       int j=0;
1781       for(;j<dim;j++)
1782         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1783       for(;j<newNbOfComp;j++)
1784         nc[newNbOfComp*i+j]=dftValue;
1785     }
1786   ret->setName(getName().c_str());
1787   for(int i=0;i<dim;i++)
1788     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1789   ret->setName(getName().c_str());
1790   return ret.retn();
1791 }
1792
1793 /*!
1794  * Changes the number of components within \a this array so that its raw data **does
1795  * not** change, instead splitting this data into tuples changes.
1796  *  \warning This method erases all (name and unit) component info set before!
1797  *  \param [in] newNbOfComp - number of components for \a this array to have.
1798  *  \throw If \a this is not allocated
1799  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1800  *  \throw If \a newNbOfCompo is lower than 1.
1801  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1802  *  \warning This method erases all (name and unit) component info set before!
1803  */
1804 void DataArrayDouble::rearrange(int newNbOfCompo)
1805 {
1806   checkAllocated();
1807   if(newNbOfCompo<1)
1808     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1809   std::size_t nbOfElems=getNbOfElems();
1810   if(nbOfElems%newNbOfCompo!=0)
1811     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1812   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1813     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1814   _info_on_compo.clear();
1815   _info_on_compo.resize(newNbOfCompo);
1816   declareAsNew();
1817 }
1818
1819 /*!
1820  * Changes the number of components within \a this array to be equal to its number
1821  * of tuples, and inversely its number of tuples to become equal to its number of 
1822  * components. So that its raw data **does not** change, instead splitting this
1823  * data into tuples changes.
1824  *  \warning This method erases all (name and unit) component info set before!
1825  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1826  *  \throw If \a this is not allocated.
1827  *  \sa rearrange()
1828  */
1829 void DataArrayDouble::transpose()
1830 {
1831   checkAllocated();
1832   int nbOfTuples=getNumberOfTuples();
1833   rearrange(nbOfTuples);
1834 }
1835
1836 /*!
1837  * Returns a copy of \a this array composed of selected components.
1838  * The new DataArrayDouble has the same number of tuples but includes components
1839  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1840  * can be either less, same or more than \a this->getNbOfElems().
1841  *  \param [in] compoIds - sequence of zero based indices of components to include
1842  *              into the new array.
1843  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1844  *          is to delete using decrRef() as it is no more needed.
1845  *  \throw If \a this is not allocated.
1846  *  \throw If a component index (\a i) is not valid: 
1847  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1848  *
1849  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1850  */
1851 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1852 {
1853   checkAllocated();
1854   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1855   std::size_t newNbOfCompo=compoIds.size();
1856   int oldNbOfCompo=getNumberOfComponents();
1857   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1858     if((*it)<0 || (*it)>=oldNbOfCompo)
1859       {
1860         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1861         throw INTERP_KERNEL::Exception(oss.str().c_str());
1862       }
1863   int nbOfTuples=getNumberOfTuples();
1864   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1865   ret->copyPartOfStringInfoFrom(*this,compoIds);
1866   const double *oldc=getConstPointer();
1867   double *nc=ret->getPointer();
1868   for(int i=0;i<nbOfTuples;i++)
1869     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1870       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1871   return ret.retn();
1872 }
1873
1874 /*!
1875  * Appends components of another array to components of \a this one, tuple by tuple.
1876  * So that the number of tuples of \a this array remains the same and the number of 
1877  * components increases.
1878  *  \param [in] other - the DataArrayDouble to append to \a this one.
1879  *  \throw If \a this is not allocated.
1880  *  \throw If \a this and \a other arrays have different number of tuples.
1881  *
1882  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1883  *
1884  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1885  */
1886 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1887 {
1888   checkAllocated();
1889   other->checkAllocated();
1890   int nbOfTuples=getNumberOfTuples();
1891   if(nbOfTuples!=other->getNumberOfTuples())
1892     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1893   int nbOfComp1=getNumberOfComponents();
1894   int nbOfComp2=other->getNumberOfComponents();
1895   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1896   double *w=newArr;
1897   const double *inp1=getConstPointer();
1898   const double *inp2=other->getConstPointer();
1899   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1900     {
1901       w=std::copy(inp1,inp1+nbOfComp1,w);
1902       w=std::copy(inp2,inp2+nbOfComp2,w);
1903     }
1904   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1905   std::vector<int> compIds(nbOfComp2);
1906   for(int i=0;i<nbOfComp2;i++)
1907     compIds[i]=nbOfComp1+i;
1908   copyPartOfStringInfoFrom2(compIds,*other);
1909 }
1910
1911 /*!
1912  * This method checks that all tuples in \a other are in \a this.
1913  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1914  * 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.
1915  *
1916  * \param [in] other - the array having the same number of components than \a this.
1917  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1918  * \sa DataArrayDouble::findCommonTuples
1919  */
1920 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1921 {
1922   if(!other)
1923     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1924   checkAllocated(); other->checkAllocated();
1925   if(getNumberOfComponents()!=other->getNumberOfComponents())
1926     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1927   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1928   DataArrayInt *c=0,*ci=0;
1929   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1930   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1931   int newNbOfTuples=-1;
1932   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1934   tupleIds=ret1.retn();
1935   return newNbOfTuples==getNumberOfTuples();
1936 }
1937
1938 /*!
1939  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1940  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1941  * distance separating two points is computed with the infinite norm.
1942  *
1943  * Indices of coincident tuples are stored in output arrays.
1944  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1945  *
1946  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1947  * MEDCouplingUMesh::mergeNodes().
1948  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1949  *              considered not coincident.
1950  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1951  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1952  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1953  *               \a comm->getNumberOfComponents() == 1. 
1954  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1955  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1956  *               groups of (indices of) coincident tuples. Its every value is a tuple
1957  *               index where a next group of tuples begins. For example the second
1958  *               group of tuples in \a comm is described by following range of indices:
1959  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1960  *               gives the number of groups of coincident tuples.
1961  *  \throw If \a this is not allocated.
1962  *  \throw If the number of components is not in [1,2,3,4].
1963  *
1964  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1965  *
1966  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1967  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1968  */
1969 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1970 {
1971   checkAllocated();
1972   int nbOfCompo=getNumberOfComponents();
1973   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1974     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1975   
1976   int nbOfTuples=getNumberOfTuples();
1977   //
1978   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1979   switch(nbOfCompo)
1980     {
1981     case 4:
1982       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1983       break;
1984     case 3:
1985       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1986       break;
1987     case 2:
1988       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1989       break;
1990     case 1:
1991       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1992       break;
1993     default:
1994       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1995     }
1996   comm=c.retn();
1997   commIndex=cI.retn();
1998 }
1999
2000 /*!
2001  * 
2002  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2003  *             \a nbTimes  should be at least equal to 1.
2004  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2005  * \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.
2006  */
2007 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2008 {
2009   checkAllocated();
2010   if(getNumberOfComponents()!=1)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2012   if(nbTimes<1)
2013     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2014   int nbTuples=getNumberOfTuples();
2015   const double *inPtr=getConstPointer();
2016   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2017   double *retPtr=ret->getPointer();
2018   for(int i=0;i<nbTuples;i++,inPtr++)
2019     {
2020       double val=*inPtr;
2021       for(int j=0;j<nbTimes;j++,retPtr++)
2022         *retPtr=val;
2023     }
2024   ret->copyStringInfoFrom(*this);
2025   return ret.retn();
2026 }
2027
2028 /*!
2029  * This methods returns the minimal distance between the two set of points \a this and \a other.
2030  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2031  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2032  *
2033  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2034  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2035  * \return the minimal distance between the two set of points \a this and \a other.
2036  * \sa DataArrayDouble::findClosestTupleId
2037  */
2038 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2039 {
2040   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2041   int nbOfCompo(getNumberOfComponents());
2042   int otherNbTuples(other->getNumberOfTuples());
2043   const double *thisPt(begin()),*otherPt(other->begin());
2044   const int *part1Pt(part1->begin());
2045   double ret=std::numeric_limits<double>::max();
2046   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2047     {
2048       double tmp(0.);
2049       for(int j=0;j<nbOfCompo;j++)
2050         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2051       if(tmp<ret)
2052         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2053     }
2054   return sqrt(ret);
2055 }
2056
2057 /*!
2058  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2059  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2060  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2061  *
2062  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2063  * \sa DataArrayDouble::minimalDistanceTo
2064  */
2065 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2066 {
2067   if(!other)
2068     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2069   checkAllocated(); other->checkAllocated();
2070   int nbOfCompo=getNumberOfComponents();
2071   if(nbOfCompo!=other->getNumberOfComponents())
2072     {
2073       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2074       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2075       throw INTERP_KERNEL::Exception(oss.str().c_str());
2076     }
2077   int nbOfTuples=other->getNumberOfTuples();
2078   int thisNbOfTuples=getNumberOfTuples();
2079   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2080   double bounds[6];
2081   getMinMaxPerComponent(bounds);
2082   switch(nbOfCompo)
2083     {
2084     case 3:
2085       {
2086         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2087         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2088         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2089         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2090         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2091         break;
2092       }
2093     case 2:
2094       {
2095         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2096         double delta=std::max(xDelta,yDelta);
2097         double characSize=sqrt(delta/(double)thisNbOfTuples);
2098         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2099         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2100         break;
2101       }
2102     case 1:
2103       {
2104         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2105         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2106         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2107         break;
2108       }
2109     default:
2110       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2111     }
2112   return ret.retn();
2113 }
2114
2115 /*!
2116  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2117  * 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
2118  * how many bounding boxes in \a otherBBoxFrmt.
2119  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2120  *
2121  * \param [in] otherBBoxFrmt - It is an array .
2122  * \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.
2123  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2124  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2125  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2126  */
2127 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2128 {
2129   if(!otherBBoxFrmt)
2130     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2131   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2132     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2133   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2134   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2135     {
2136       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2137       throw INTERP_KERNEL::Exception(oss.str().c_str());
2138     }
2139   if(nbOfComp%2!=0)
2140     {
2141       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2142       throw INTERP_KERNEL::Exception(oss.str().c_str());
2143     }
2144   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2145   const double *thisBBPtr(begin());
2146   int *retPtr(ret->getPointer());
2147   switch(nbOfComp/2)
2148     {
2149     case 3:
2150       {
2151         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2152         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2153           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2154         break;
2155       }
2156     case 2:
2157       {
2158         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2159         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2160           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2161         break;
2162       }
2163     case 1:
2164       {
2165         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2166         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2167           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2168         break;
2169       }
2170     default:
2171       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2172     }
2173   
2174   return ret.retn();
2175 }
2176
2177 /*!
2178  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2179  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2180  * space. The distance between tuples is computed using norm2. If several tuples are
2181  * not far each from other than \a prec, only one of them remains in the result
2182  * array. The order of tuples in the result array is same as in \a this one except
2183  * that coincident tuples are excluded.
2184  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2185  *              considered not coincident.
2186  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2187  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2188  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2189  *          is to delete using decrRef() as it is no more needed.
2190  *  \throw If \a this is not allocated.
2191  *  \throw If the number of components is not in [1,2,3,4].
2192  *
2193  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2194  */
2195 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2196 {
2197   checkAllocated();
2198   DataArrayInt *c0=0,*cI0=0;
2199   findCommonTuples(prec,limitTupleId,c0,cI0);
2200   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2201   int newNbOfTuples=-1;
2202   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2203   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2204 }
2205
2206 /*!
2207  * Copy all components in a specified order from another DataArrayDouble.
2208  * Both numerical and textual data is copied. The number of tuples in \a this and
2209  * the other array can be different.
2210  *  \param [in] a - the array to copy data from.
2211  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2212  *              to be copied.
2213  *  \throw If \a a is NULL.
2214  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2215  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2216  *
2217  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2218  */
2219 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2220 {
2221   if(!a)
2222     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2223   checkAllocated();
2224   copyPartOfStringInfoFrom2(compoIds,*a);
2225   std::size_t partOfCompoSz=compoIds.size();
2226   int nbOfCompo=getNumberOfComponents();
2227   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2228   const double *ac=a->getConstPointer();
2229   double *nc=getPointer();
2230   for(int i=0;i<nbOfTuples;i++)
2231     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2232       nc[nbOfCompo*i+compoIds[j]]=*ac;
2233 }
2234
2235 /*!
2236  * Copy all values from another DataArrayDouble into specified tuples and components
2237  * of \a this array. Textual data is not copied.
2238  * The tree parameters defining set of indices of tuples and components are similar to
2239  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2240  *  \param [in] a - the array to copy values from.
2241  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2242  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2243  *              are located.
2244  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2245  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2246  *  \param [in] endComp - index of the component before which the components to assign
2247  *              to are located.
2248  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2249  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2250  *              must be equal to the number of columns to assign to, else an
2251  *              exception is thrown; if \a false, then it is only required that \a
2252  *              a->getNbOfElems() equals to number of values to assign to (this condition
2253  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2254  *              values to assign to is given by following Python expression:
2255  *              \a nbTargetValues = 
2256  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2257  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2258  *  \throw If \a a is NULL.
2259  *  \throw If \a a is not allocated.
2260  *  \throw If \a this is not allocated.
2261  *  \throw If parameters specifying tuples and components to assign to do not give a
2262  *            non-empty range of increasing indices.
2263  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2264  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2265  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2266  *
2267  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2268  */
2269 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2270 {
2271   if(!a)
2272     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2273   const char msg[]="DataArrayDouble::setPartOfValues1";
2274   checkAllocated();
2275   a->checkAllocated();
2276   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2277   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2278   int nbComp=getNumberOfComponents();
2279   int nbOfTuples=getNumberOfTuples();
2280   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2281   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2282   bool assignTech=true;
2283   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2284     {
2285       if(strictCompoCompare)
2286         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2287     }
2288   else
2289     {
2290       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2291       assignTech=false;
2292     }
2293   const double *srcPt=a->getConstPointer();
2294   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2295   if(assignTech)
2296     {
2297       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2298         for(int j=0;j<newNbOfComp;j++,srcPt++)
2299           pt[j*stepComp]=*srcPt;
2300     }
2301   else
2302     {
2303       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2304         {
2305           const double *srcPt2=srcPt;
2306           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2307             pt[j*stepComp]=*srcPt2;
2308         }
2309     }
2310 }
2311
2312 /*!
2313  * Assign a given value to values at specified tuples and components of \a this array.
2314  * The tree parameters defining set of indices of tuples and components are similar to
2315  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2316  *  \param [in] a - the value to assign.
2317  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2318  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2319  *              are located.
2320  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2321  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2322  *  \param [in] endComp - index of the component before which the components to assign
2323  *              to are located.
2324  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2325  *  \throw If \a this is not allocated.
2326  *  \throw If parameters specifying tuples and components to assign to, do not give a
2327  *            non-empty range of increasing indices or indices are out of a valid range
2328  *            for \this array.
2329  *
2330  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2331  */
2332 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2333 {
2334   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2335   checkAllocated();
2336   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2337   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2338   int nbComp=getNumberOfComponents();
2339   int nbOfTuples=getNumberOfTuples();
2340   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2341   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2342   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2343   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2344     for(int j=0;j<newNbOfComp;j++)
2345       pt[j*stepComp]=a;
2346 }
2347
2348 /*!
2349  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2350  * components of \a this array. Textual data is not copied.
2351  * The tuples and components to assign to are defined by C arrays of indices.
2352  * There are two *modes of usage*:
2353  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2354  *   of \a a is assigned to its own location within \a this array. 
2355  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2356  *   components of every specified tuple of \a this array. In this mode it is required
2357  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2358  *
2359  *  \param [in] a - the array to copy values from.
2360  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2361  *              assign values of \a a to.
2362  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2363  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2364  *              \a bgTuples <= \a pi < \a endTuples.
2365  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2366  *              assign values of \a a to.
2367  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2368  *              pointer to a component index <em>(pi)</em> varies as this: 
2369  *              \a bgComp <= \a pi < \a endComp.
2370  *  \param [in] strictCompoCompare - this parameter is checked only if the
2371  *               *mode of usage* is the first; if it is \a true (default), 
2372  *               then \a a->getNumberOfComponents() must be equal 
2373  *               to the number of specified columns, else this is not required.
2374  *  \throw If \a a is NULL.
2375  *  \throw If \a a is not allocated.
2376  *  \throw If \a this is not allocated.
2377  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2378  *         out of a valid range for \a this array.
2379  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2380  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2381  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2382  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2383  *
2384  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2385  */
2386 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2387 {
2388   if(!a)
2389     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2390   const char msg[]="DataArrayDouble::setPartOfValues2";
2391   checkAllocated();
2392   a->checkAllocated();
2393   int nbComp=getNumberOfComponents();
2394   int nbOfTuples=getNumberOfTuples();
2395   for(const int *z=bgComp;z!=endComp;z++)
2396     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2397   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2398   int newNbOfComp=(int)std::distance(bgComp,endComp);
2399   bool assignTech=true;
2400   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2401     {
2402       if(strictCompoCompare)
2403         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2404     }
2405   else
2406     {
2407       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2408       assignTech=false;
2409     }
2410   double *pt=getPointer();
2411   const double *srcPt=a->getConstPointer();
2412   if(assignTech)
2413     {    
2414       for(const int *w=bgTuples;w!=endTuples;w++)
2415         {
2416           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2417           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2418             {    
2419               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2420             }
2421         }
2422     }
2423   else
2424     {
2425       for(const int *w=bgTuples;w!=endTuples;w++)
2426         {
2427           const double *srcPt2=srcPt;
2428           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2429           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2430             {    
2431               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2432             }
2433         }
2434     }
2435 }
2436
2437 /*!
2438  * Assign a given value to values at specified tuples and components of \a this array.
2439  * The tuples and components to assign to are defined by C arrays of indices.
2440  *  \param [in] a - the value to assign.
2441  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2442  *              assign \a a to.
2443  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2444  *              pointer to a tuple index (\a pi) varies as this: 
2445  *              \a bgTuples <= \a pi < \a endTuples.
2446  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2447  *              assign \a a to.
2448  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2449  *              pointer to a component index (\a pi) varies as this: 
2450  *              \a bgComp <= \a pi < \a endComp.
2451  *  \throw If \a this is not allocated.
2452  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2453  *         out of a valid range for \a this array.
2454  *
2455  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2456  */
2457 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2458 {
2459   checkAllocated();
2460   int nbComp=getNumberOfComponents();
2461   int nbOfTuples=getNumberOfTuples();
2462   for(const int *z=bgComp;z!=endComp;z++)
2463     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2464   double *pt=getPointer();
2465   for(const int *w=bgTuples;w!=endTuples;w++)
2466     for(const int *z=bgComp;z!=endComp;z++)
2467       {
2468         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2469         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2470       }
2471 }
2472
2473 /*!
2474  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2475  * components of \a this array. Textual data is not copied.
2476  * The tuples to assign to are defined by a C array of indices.
2477  * The components to assign to are defined by three values similar to parameters of
2478  * the Python function \c range(\c start,\c stop,\c step).
2479  * There are two *modes of usage*:
2480  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2481  *   of \a a is assigned to its own location within \a this array. 
2482  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2483  *   components of every specified tuple of \a this array. In this mode it is required
2484  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2485  *
2486  *  \param [in] a - the array to copy values from.
2487  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2488  *              assign values of \a a to.
2489  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2490  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2491  *              \a bgTuples <= \a pi < \a endTuples.
2492  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2493  *  \param [in] endComp - index of the component before which the components to assign
2494  *              to are located.
2495  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2496  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2497  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2498  *               then \a a->getNumberOfComponents() must be equal 
2499  *               to the number of specified columns, else this is not required.
2500  *  \throw If \a a is NULL.
2501  *  \throw If \a a is not allocated.
2502  *  \throw If \a this is not allocated.
2503  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2504  *         \a this array.
2505  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2506  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2507  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2508  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2509  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2510  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2511  *  \throw If parameters specifying components to assign to, do not give a
2512  *            non-empty range of increasing indices or indices are out of a valid range
2513  *            for \this array.
2514  *
2515  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2516  */
2517 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2518 {
2519   if(!a)
2520     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2521   const char msg[]="DataArrayDouble::setPartOfValues3";
2522   checkAllocated();
2523   a->checkAllocated();
2524   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2525   int nbComp=getNumberOfComponents();
2526   int nbOfTuples=getNumberOfTuples();
2527   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2528   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2529   bool assignTech=true;
2530   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2531     {
2532       if(strictCompoCompare)
2533         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2534     }
2535   else
2536     {
2537       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2538       assignTech=false;
2539     }
2540   double *pt=getPointer()+bgComp;
2541   const double *srcPt=a->getConstPointer();
2542   if(assignTech)
2543     {
2544       for(const int *w=bgTuples;w!=endTuples;w++)
2545         for(int j=0;j<newNbOfComp;j++,srcPt++)
2546           {
2547             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2548             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2549           }
2550     }
2551   else
2552     {
2553       for(const int *w=bgTuples;w!=endTuples;w++)
2554         {
2555           const double *srcPt2=srcPt;
2556           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2557             {
2558               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2559               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2560             }
2561         }
2562     }
2563 }
2564
2565 /*!
2566  * Assign a given value to values at specified tuples and components of \a this array.
2567  * The tuples to assign to are defined by a C array of indices.
2568  * The components to assign to are defined by three values similar to parameters of
2569  * the Python function \c range(\c start,\c stop,\c step).
2570  *  \param [in] a - the value to assign.
2571  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2572  *              assign \a a to.
2573  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2574  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2575  *              \a bgTuples <= \a pi < \a endTuples.
2576  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2577  *  \param [in] endComp - index of the component before which the components to assign
2578  *              to are located.
2579  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2580  *  \throw If \a this is not allocated.
2581  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2582  *         \a this array.
2583  *  \throw If parameters specifying components to assign to, do not give a
2584  *            non-empty range of increasing indices or indices are out of a valid range
2585  *            for \this array.
2586  *
2587  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2588  */
2589 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2590 {
2591   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2592   checkAllocated();
2593   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2594   int nbComp=getNumberOfComponents();
2595   int nbOfTuples=getNumberOfTuples();
2596   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2597   double *pt=getPointer()+bgComp;
2598   for(const int *w=bgTuples;w!=endTuples;w++)
2599     for(int j=0;j<newNbOfComp;j++)
2600       {
2601         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2602         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2603       }
2604 }
2605
2606 /*!
2607  * Copy all values from another DataArrayDouble into specified tuples and components
2608  * of \a this array. Textual data is not copied.
2609  * The tree parameters defining set of indices of tuples and components are similar to
2610  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2611  *  \param [in] a - the array to copy values from.
2612  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2613  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2614  *              are located.
2615  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2616  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2617  *              assign \a a to.
2618  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2619  *              pointer to a component index (\a pi) varies as this: 
2620  *              \a bgComp <= \a pi < \a endComp.
2621  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2622  *              must be equal to the number of columns to assign to, else an
2623  *              exception is thrown; if \a false, then it is only required that \a
2624  *              a->getNbOfElems() equals to number of values to assign to (this condition
2625  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2626  *              values to assign to is given by following Python expression:
2627  *              \a nbTargetValues = 
2628  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2629  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2630  *  \throw If \a a is NULL.
2631  *  \throw If \a a is not allocated.
2632  *  \throw If \a this is not allocated.
2633  *  \throw If parameters specifying tuples and components to assign to do not give a
2634  *            non-empty range of increasing indices.
2635  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2636  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2637  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2638  *
2639  */
2640 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2641 {
2642   if(!a)
2643     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2644   const char msg[]="DataArrayDouble::setPartOfValues4";
2645   checkAllocated();
2646   a->checkAllocated();
2647   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2648   int newNbOfComp=(int)std::distance(bgComp,endComp);
2649   int nbComp=getNumberOfComponents();
2650   for(const int *z=bgComp;z!=endComp;z++)
2651     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2652   int nbOfTuples=getNumberOfTuples();
2653   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2654   bool assignTech=true;
2655   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2656     {
2657       if(strictCompoCompare)
2658         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2659     }
2660   else
2661     {
2662       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2663       assignTech=false;
2664     }
2665   const double *srcPt=a->getConstPointer();
2666   double *pt=getPointer()+bgTuples*nbComp;
2667   if(assignTech)
2668     {
2669       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2670         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2671           pt[*z]=*srcPt;
2672     }
2673   else
2674     {
2675       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2676         {
2677           const double *srcPt2=srcPt;
2678           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2679             pt[*z]=*srcPt2;
2680         }
2681     }
2682 }
2683
2684 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2685 {
2686   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2687   checkAllocated();
2688   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2689   int nbComp=getNumberOfComponents();
2690   for(const int *z=bgComp;z!=endComp;z++)
2691     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2692   int nbOfTuples=getNumberOfTuples();
2693   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2694   double *pt=getPointer()+bgTuples*nbComp;
2695   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2696     for(const int *z=bgComp;z!=endComp;z++)
2697       pt[*z]=a;
2698 }
2699
2700 /*!
2701  * Copy some tuples from another DataArrayDouble into specified tuples
2702  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2703  * components.
2704  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2705  * All components of selected tuples are copied.
2706  *  \param [in] a - the array to copy values from.
2707  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2708  *              target tuples of \a this. \a tuplesSelec has two components, and the
2709  *              first component specifies index of the source tuple and the second
2710  *              one specifies index of the target tuple.
2711  *  \throw If \a this is not allocated.
2712  *  \throw If \a a is NULL.
2713  *  \throw If \a a is not allocated.
2714  *  \throw If \a tuplesSelec is NULL.
2715  *  \throw If \a tuplesSelec is not allocated.
2716  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2717  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2718  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2719  *         the corresponding (\a this or \a a) array.
2720  */
2721 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2722 {
2723   if(!a || !tuplesSelec)
2724     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2725   checkAllocated();
2726   a->checkAllocated();
2727   tuplesSelec->checkAllocated();
2728   int nbOfComp=getNumberOfComponents();
2729   if(nbOfComp!=a->getNumberOfComponents())
2730     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2731   if(tuplesSelec->getNumberOfComponents()!=2)
2732     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2733   int thisNt=getNumberOfTuples();
2734   int aNt=a->getNumberOfTuples();
2735   double *valsToSet=getPointer();
2736   const double *valsSrc=a->getConstPointer();
2737   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2738     {
2739       if(tuple[1]>=0 && tuple[1]<aNt)
2740         {
2741           if(tuple[0]>=0 && tuple[0]<thisNt)
2742             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2743           else
2744             {
2745               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2746               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2747               throw INTERP_KERNEL::Exception(oss.str().c_str());
2748             }
2749         }
2750       else
2751         {
2752           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2753           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2754           throw INTERP_KERNEL::Exception(oss.str().c_str());
2755         }
2756     }
2757 }
2758
2759 /*!
2760  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2761  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2762  * components.
2763  * The tuples to assign to are defined by index of the first tuple, and
2764  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2765  * The tuples to copy are defined by values of a DataArrayInt.
2766  * All components of selected tuples are copied.
2767  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2768  *              values to.
2769  *  \param [in] aBase - the array to copy values from.
2770  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2771  *  \throw If \a this is not allocated.
2772  *  \throw If \a aBase is NULL.
2773  *  \throw If \a aBase is not allocated.
2774  *  \throw If \a tuplesSelec is NULL.
2775  *  \throw If \a tuplesSelec is not allocated.
2776  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2777  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2778  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2779  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2780  *         \a aBase array.
2781  */
2782 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2783 {
2784   if(!aBase || !tuplesSelec)
2785     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2786   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2787   if(!a)
2788     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2789   checkAllocated();
2790   a->checkAllocated();
2791   tuplesSelec->checkAllocated();
2792   int nbOfComp=getNumberOfComponents();
2793   if(nbOfComp!=a->getNumberOfComponents())
2794     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2795   if(tuplesSelec->getNumberOfComponents()!=1)
2796     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2797   int thisNt=getNumberOfTuples();
2798   int aNt=a->getNumberOfTuples();
2799   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2800   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2801   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2802     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2803   const double *valsSrc=a->getConstPointer();
2804   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2805     {
2806       if(*tuple>=0 && *tuple<aNt)
2807         {
2808           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2809         }
2810       else
2811         {
2812           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2813           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2814           throw INTERP_KERNEL::Exception(oss.str().c_str());
2815         }
2816     }
2817 }
2818
2819 /*!
2820  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2821  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2822  * components.
2823  * The tuples to copy are defined by three values similar to parameters of
2824  * the Python function \c range(\c start,\c stop,\c step).
2825  * The tuples to assign to are defined by index of the first tuple, and
2826  * their number is defined by number of tuples to copy.
2827  * All components of selected tuples are copied.
2828  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2829  *              values to.
2830  *  \param [in] aBase - the array to copy values from.
2831  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2832  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2833  *              are located.
2834  *  \param [in] step - index increment to get index of the next tuple to copy.
2835  *  \throw If \a this is not allocated.
2836  *  \throw If \a aBase is NULL.
2837  *  \throw If \a aBase is not allocated.
2838  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2839  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2840  *  \throw If parameters specifying tuples to copy, do not give a
2841  *            non-empty range of increasing indices or indices are out of a valid range
2842  *            for the array \a aBase.
2843  */
2844 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2845 {
2846   if(!aBase)
2847     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2848   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2849   if(!a)
2850     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2851   checkAllocated();
2852   a->checkAllocated();
2853   int nbOfComp=getNumberOfComponents();
2854   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2855   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2856   if(nbOfComp!=a->getNumberOfComponents())
2857     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2858   int thisNt=getNumberOfTuples();
2859   int aNt=a->getNumberOfTuples();
2860   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2861   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2862     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2863   if(end2>aNt)
2864     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2865   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2866   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2867     {
2868       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2869     }
2870 }
2871
2872 /*!
2873  * Returns a value located at specified tuple and component.
2874  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2875  * parameters is checked. So this method is safe but expensive if used to go through
2876  * all values of \a this.
2877  *  \param [in] tupleId - index of tuple of interest.
2878  *  \param [in] compoId - index of component of interest.
2879  *  \return double - value located by \a tupleId and \a compoId.
2880  *  \throw If \a this is not allocated.
2881  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2882  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2883  */
2884 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2885 {
2886   checkAllocated();
2887   if(tupleId<0 || tupleId>=getNumberOfTuples())
2888     {
2889       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2890       throw INTERP_KERNEL::Exception(oss.str().c_str());
2891     }
2892   if(compoId<0 || compoId>=getNumberOfComponents())
2893     {
2894       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2895       throw INTERP_KERNEL::Exception(oss.str().c_str());
2896     }
2897   return _mem[tupleId*_info_on_compo.size()+compoId];
2898 }
2899
2900 /*!
2901  * Returns the first value of \a this. 
2902  *  \return double - the last value of \a this array.
2903  *  \throw If \a this is not allocated.
2904  *  \throw If \a this->getNumberOfComponents() != 1.
2905  *  \throw If \a this->getNumberOfTuples() < 1.
2906  */
2907 double DataArrayDouble::front() const
2908 {
2909   checkAllocated();
2910   if(getNumberOfComponents()!=1)
2911     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2912   int nbOfTuples=getNumberOfTuples();
2913   if(nbOfTuples<1)
2914     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2915   return *(getConstPointer());
2916 }
2917
2918 /*!
2919  * Returns the last value of \a this. 
2920  *  \return double - the last value of \a this array.
2921  *  \throw If \a this is not allocated.
2922  *  \throw If \a this->getNumberOfComponents() != 1.
2923  *  \throw If \a this->getNumberOfTuples() < 1.
2924  */
2925 double DataArrayDouble::back() const
2926 {
2927   checkAllocated();
2928   if(getNumberOfComponents()!=1)
2929     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2930   int nbOfTuples=getNumberOfTuples();
2931   if(nbOfTuples<1)
2932     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2933   return *(getConstPointer()+nbOfTuples-1);
2934 }
2935
2936 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2937 {
2938   if(newArray!=arrayToSet)
2939     {
2940       if(arrayToSet)
2941         arrayToSet->decrRef();
2942       arrayToSet=newArray;
2943       if(arrayToSet)
2944         arrayToSet->incrRef();
2945     }
2946 }
2947
2948 /*!
2949  * Sets a C array to be used as raw data of \a this. The previously set info
2950  *  of components is retained and re-sized. 
2951  * For more info see \ref MEDCouplingArraySteps1.
2952  *  \param [in] array - the C array to be used as raw data of \a this.
2953  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2954  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2955  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2956  *                     \c free(\c array ) will be called.
2957  *  \param [in] nbOfTuple - new number of tuples in \a this.
2958  *  \param [in] nbOfCompo - new number of components in \a this.
2959  */
2960 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2961 {
2962   _info_on_compo.resize(nbOfCompo);
2963   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2964   declareAsNew();
2965 }
2966
2967 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
2968 {
2969   _info_on_compo.resize(nbOfCompo);
2970   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2971   declareAsNew();
2972 }
2973
2974 /*!
2975  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2976  * is thrown.
2977  * \throw If zero is found in \a this array.
2978  */
2979 void DataArrayDouble::checkNoNullValues() const
2980 {
2981   const double *tmp=getConstPointer();
2982   std::size_t nbOfElems=getNbOfElems();
2983   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2984   if(where!=tmp+nbOfElems)
2985     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2986 }
2987
2988 /*!
2989  * Computes minimal and maximal value in each component. An output array is filled
2990  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2991  * enough memory before calling this method.
2992  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2993  *               It is filled as follows:<br>
2994  *               \a bounds[0] = \c min_of_component_0 <br>
2995  *               \a bounds[1] = \c max_of_component_0 <br>
2996  *               \a bounds[2] = \c min_of_component_1 <br>
2997  *               \a bounds[3] = \c max_of_component_1 <br>
2998  *               ...
2999  */
3000 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3001 {
3002   checkAllocated();
3003   int dim=getNumberOfComponents();
3004   for (int idim=0; idim<dim; idim++)
3005     {
3006       bounds[idim*2]=std::numeric_limits<double>::max();
3007       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3008     } 
3009   const double *ptr=getConstPointer();
3010   int nbOfTuples=getNumberOfTuples();
3011   for(int i=0;i<nbOfTuples;i++)
3012     {
3013       for(int idim=0;idim<dim;idim++)
3014         {
3015           if(bounds[idim*2]>ptr[i*dim+idim])
3016             {
3017               bounds[idim*2]=ptr[i*dim+idim];
3018             }
3019           if(bounds[idim*2+1]<ptr[i*dim+idim])
3020             {
3021               bounds[idim*2+1]=ptr[i*dim+idim];
3022             }
3023         }
3024     }
3025 }
3026
3027 /*!
3028  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3029  * to store both the min and max per component of each tuples. 
3030  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3031  *
3032  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3033  *
3034  * \throw If \a this is not allocated yet.
3035  */
3036 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3037 {
3038   checkAllocated();
3039   const double *dataPtr=getConstPointer();
3040   int nbOfCompo=getNumberOfComponents();
3041   int nbTuples=getNumberOfTuples();
3042   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3043   bbox->alloc(nbTuples,2*nbOfCompo);
3044   double *bboxPtr=bbox->getPointer();
3045   for(int i=0;i<nbTuples;i++)
3046     {
3047       for(int j=0;j<nbOfCompo;j++)
3048         {
3049           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3050           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3051         }
3052     }
3053   return bbox.retn();
3054 }
3055
3056 /*!
3057  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3058  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3059  * 
3060  * \param [in] other a DataArrayDouble having same number of components than \a this.
3061  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3062  * \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.
3063  *             \a cI allows to extract information in \a c.
3064  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3065  *
3066  * \throw In case of:
3067  *  - \a this is not allocated
3068  *  - \a other is not allocated or null
3069  *  - \a this and \a other do not have the same number of components
3070  *  - if number of components of \a this is not in [1,2,3]
3071  *
3072  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3073  */
3074 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3075 {
3076   if(!other)
3077     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3078   checkAllocated();
3079   other->checkAllocated();
3080   int nbOfCompo=getNumberOfComponents();
3081   int otherNbOfCompo=other->getNumberOfComponents();
3082   if(nbOfCompo!=otherNbOfCompo)
3083     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3084   int nbOfTuplesOther=other->getNumberOfTuples();
3085   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3086   switch(nbOfCompo)
3087     {
3088     case 3:
3089       {
3090         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3091         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3092         break;
3093       }
3094     case 2:
3095       {
3096         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3097         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3098         break;
3099       }
3100     case 1:
3101       {
3102         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3103         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3104         break;
3105       }
3106     default:
3107       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3108     }
3109   c=cArr.retn(); cI=cIArr.retn();
3110 }
3111
3112 /*!
3113  * 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
3114  * around origin of 'radius' 1.
3115  * 
3116  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3117  */
3118 void DataArrayDouble::recenterForMaxPrecision(double eps)
3119 {
3120   checkAllocated();
3121   int dim=getNumberOfComponents();
3122   std::vector<double> bounds(2*dim);
3123   getMinMaxPerComponent(&bounds[0]);
3124   for(int i=0;i<dim;i++)
3125     {
3126       double delta=bounds[2*i+1]-bounds[2*i];
3127       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3128       if(delta>eps)
3129         applyLin(1./delta,-offset/delta,i);
3130       else
3131         applyLin(1.,-offset,i);
3132     }
3133 }
3134
3135 /*!
3136  * Returns the maximal value and its location within \a this one-dimensional array.
3137  *  \param [out] tupleId - index of the tuple holding the maximal value.
3138  *  \return double - the maximal value among all values of \a this array.
3139  *  \throw If \a this->getNumberOfComponents() != 1
3140  *  \throw If \a this->getNumberOfTuples() < 1
3141  */
3142 double DataArrayDouble::getMaxValue(int& tupleId) const
3143 {
3144   checkAllocated();
3145   if(getNumberOfComponents()!=1)
3146     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 !");
3147   int nbOfTuples=getNumberOfTuples();
3148   if(nbOfTuples<=0)
3149     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3150   const double *vals=getConstPointer();
3151   const double *loc=std::max_element(vals,vals+nbOfTuples);
3152   tupleId=(int)std::distance(vals,loc);
3153   return *loc;
3154 }
3155
3156 /*!
3157  * Returns the maximal value within \a this array that is allowed to have more than
3158  *  one component.
3159  *  \return double - the maximal value among all values of \a this array.
3160  *  \throw If \a this is not allocated.
3161  */
3162 double DataArrayDouble::getMaxValueInArray() const
3163 {
3164   checkAllocated();
3165   const double *loc=std::max_element(begin(),end());
3166   return *loc;
3167 }
3168
3169 /*!
3170  * Returns the maximal value and all its locations within \a this one-dimensional array.
3171  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3172  *               tuples holding the maximal value. The caller is to delete it using
3173  *               decrRef() as it is no more needed.
3174  *  \return double - the maximal value among all values of \a this array.
3175  *  \throw If \a this->getNumberOfComponents() != 1
3176  *  \throw If \a this->getNumberOfTuples() < 1
3177  */
3178 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3179 {
3180   int tmp;
3181   tupleIds=0;
3182   double ret=getMaxValue(tmp);
3183   tupleIds=getIdsInRange(ret,ret);
3184   return ret;
3185 }
3186
3187 /*!
3188  * Returns the minimal value and its location within \a this one-dimensional array.
3189  *  \param [out] tupleId - index of the tuple holding the minimal value.
3190  *  \return double - the minimal value among all values of \a this array.
3191  *  \throw If \a this->getNumberOfComponents() != 1
3192  *  \throw If \a this->getNumberOfTuples() < 1
3193  */
3194 double DataArrayDouble::getMinValue(int& tupleId) const
3195 {
3196   checkAllocated();
3197   if(getNumberOfComponents()!=1)
3198     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3199   int nbOfTuples=getNumberOfTuples();
3200   if(nbOfTuples<=0)
3201     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3202   const double *vals=getConstPointer();
3203   const double *loc=std::min_element(vals,vals+nbOfTuples);
3204   tupleId=(int)std::distance(vals,loc);
3205   return *loc;
3206 }
3207
3208 /*!
3209  * Returns the minimal value within \a this array that is allowed to have more than
3210  *  one component.
3211  *  \return double - the minimal value among all values of \a this array.
3212  *  \throw If \a this is not allocated.
3213  */
3214 double DataArrayDouble::getMinValueInArray() const
3215 {
3216   checkAllocated();
3217   const double *loc=std::min_element(begin(),end());
3218   return *loc;
3219 }
3220
3221 /*!
3222  * Returns the minimal value and all its locations within \a this one-dimensional array.
3223  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3224  *               tuples holding the minimal value. The caller is to delete it using
3225  *               decrRef() as it is no more needed.
3226  *  \return double - the minimal value among all values of \a this array.
3227  *  \throw If \a this->getNumberOfComponents() != 1
3228  *  \throw If \a this->getNumberOfTuples() < 1
3229  */
3230 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3231 {
3232   int tmp;
3233   tupleIds=0;
3234   double ret=getMinValue(tmp);
3235   tupleIds=getIdsInRange(ret,ret);
3236   return ret;
3237 }
3238
3239 /*!
3240  * 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.
3241  * This method only works for single component array.
3242  *
3243  * \return a value in [ 0, \c this->getNumberOfTuples() )
3244  *
3245  * \throw If \a this is not allocated
3246  *
3247  */
3248 int DataArrayDouble::count(double value, double eps) const
3249 {
3250   int ret=0;
3251   checkAllocated();
3252   if(getNumberOfComponents()!=1)
3253     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3254   const double *vals=begin();
3255   int nbOfTuples=getNumberOfTuples();
3256   for(int i=0;i<nbOfTuples;i++,vals++)
3257     if(fabs(*vals-value)<=eps)
3258       ret++;
3259   return ret;
3260 }
3261
3262 /*!
3263  * Returns the average value of \a this one-dimensional array.
3264  *  \return double - the average value over all values of \a this array.
3265  *  \throw If \a this->getNumberOfComponents() != 1
3266  *  \throw If \a this->getNumberOfTuples() < 1
3267  */
3268 double DataArrayDouble::getAverageValue() const
3269 {
3270   if(getNumberOfComponents()!=1)
3271     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3272   int nbOfTuples=getNumberOfTuples();
3273   if(nbOfTuples<=0)
3274     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3275   const double *vals=getConstPointer();
3276   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3277   return ret/nbOfTuples;
3278 }
3279
3280 /*!
3281  * Returns the Euclidean norm of the vector defined by \a this array.
3282  *  \return double - the value of the Euclidean norm, i.e.
3283  *          the square root of the inner product of vector.
3284  *  \throw If \a this is not allocated.
3285  */
3286 double DataArrayDouble::norm2() const
3287 {
3288   checkAllocated();
3289   double ret=0.;
3290   std::size_t nbOfElems=getNbOfElems();
3291   const double *pt=getConstPointer();
3292   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3293     ret+=(*pt)*(*pt);
3294   return sqrt(ret);
3295 }
3296
3297 /*!
3298  * Returns the maximum norm of the vector defined by \a this array.
3299  * This method works even if the number of components is diferent from one.
3300  * If the number of elements in \a this is 0, -1. is returned.
3301  *  \return double - the value of the maximum norm, i.e.
3302  *          the maximal absolute value among values of \a this array (whatever its number of components).
3303  *  \throw If \a this is not allocated.
3304  */
3305 double DataArrayDouble::normMax() const
3306 {
3307   checkAllocated();
3308   double ret(-1.);
3309   std::size_t nbOfElems(getNbOfElems());
3310   const double *pt(getConstPointer());
3311   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3312     {
3313       double val(std::abs(*pt));
3314       if(val>ret)
3315         ret=val;
3316     }
3317   return ret;
3318 }
3319
3320 /*!
3321  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3322  * This method works even if the number of components is diferent from one.
3323  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3324  *  \return double - the value of the minimum norm, i.e.
3325  *          the minimal absolute value among values of \a this array (whatever its number of components).
3326  *  \throw If \a this is not allocated.
3327  */
3328 double DataArrayDouble::normMin() const
3329 {
3330   checkAllocated();
3331   double ret(std::numeric_limits<double>::max());
3332   std::size_t nbOfElems(getNbOfElems());
3333   const double *pt(getConstPointer());
3334   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3335     {
3336       double val(std::abs(*pt));
3337       if(val<ret)
3338         ret=val;
3339     }
3340   return ret;
3341 }
3342
3343 /*!
3344  * Accumulates values of each component of \a this array.
3345  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3346  *         by the caller, that is filled by this method with sum value for each
3347  *         component.
3348  *  \throw If \a this is not allocated.
3349  */
3350 void DataArrayDouble::accumulate(double *res) const
3351 {
3352   checkAllocated();
3353   const double *ptr=getConstPointer();
3354   int nbTuple=getNumberOfTuples();
3355   int nbComps=getNumberOfComponents();
3356   std::fill(res,res+nbComps,0.);
3357   for(int i=0;i<nbTuple;i++)
3358     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3359 }
3360
3361 /*!
3362  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3363  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3364  *
3365  *
3366  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3367  * \a tupleEnd. If not an exception will be thrown.
3368  *
3369  * \param [in] tupleBg start pointer (included) of input external tuple
3370  * \param [in] tupleEnd end pointer (not included) of input external tuple
3371  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3372  * \return the min distance.
3373  * \sa MEDCouplingUMesh::distanceToPoint
3374  */
3375 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3376 {
3377   checkAllocated();
3378   int nbTuple=getNumberOfTuples();
3379   int nbComps=getNumberOfComponents();
3380   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3381     { 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()); }
3382   if(nbTuple==0)
3383     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3384   double ret0=std::numeric_limits<double>::max();
3385   tupleId=-1;
3386   const double *work=getConstPointer();
3387   for(int i=0;i<nbTuple;i++)
3388     {
3389       double val=0.;
3390       for(int j=0;j<nbComps;j++,work++) 
3391         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3392       if(val>=ret0)
3393         continue;
3394       else
3395         { ret0=val; tupleId=i; }
3396     }
3397   return sqrt(ret0);
3398 }
3399
3400 /*!
3401  * Accumulate values of the given component of \a this array.
3402  *  \param [in] compId - the index of the component of interest.
3403  *  \return double - a sum value of \a compId-th component.
3404  *  \throw If \a this is not allocated.
3405  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3406  *         not respected.
3407  */
3408 double DataArrayDouble::accumulate(int compId) const
3409 {
3410   checkAllocated();
3411   const double *ptr=getConstPointer();
3412   int nbTuple=getNumberOfTuples();
3413   int nbComps=getNumberOfComponents();
3414   if(compId<0 || compId>=nbComps)
3415     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3416   double ret=0.;
3417   for(int i=0;i<nbTuple;i++)
3418     ret+=ptr[i*nbComps+compId];
3419   return ret;
3420 }
3421
3422 /*!
3423  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3424  * The returned array will have same number of components than \a this and number of tuples equal to
3425  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3426  *
3427  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3428  * 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.
3429  *
3430  * \param [in] bgOfIndex - begin (included) of the input index array.
3431  * \param [in] endOfIndex - end (excluded) of the input index array.
3432  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3433  * 
3434  * \throw If bgOfIndex or end is NULL.
3435  * \throw If input index array is not ascendingly sorted.
3436  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3437  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3438  */
3439 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3440 {
3441   if(!bgOfIndex || !endOfIndex)
3442     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3443   checkAllocated();
3444   int nbCompo=getNumberOfComponents();
3445   int nbOfTuples=getNumberOfTuples();
3446   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3447   if(sz<1)
3448     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3449   sz--;
3450   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3451   const int *w=bgOfIndex;
3452   if(*w<0 || *w>=nbOfTuples)
3453     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3454   const double *srcPt=begin()+(*w)*nbCompo;
3455   double *tmp=ret->getPointer();
3456   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3457     {
3458       std::fill(tmp,tmp+nbCompo,0.);
3459       if(w[1]>=w[0])
3460         {
3461           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3462             {
3463               if(j>=0 && j<nbOfTuples)
3464                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3465               else
3466                 {
3467                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3468                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3469                 }
3470             }
3471         }
3472       else
3473         {
3474           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3475           throw INTERP_KERNEL::Exception(oss.str().c_str());
3476         }
3477     }
3478   ret->copyStringInfoFrom(*this);
3479   return ret.retn();
3480 }
3481
3482 /*!
3483  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3484  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3485  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3486  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3487  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3488  *          is to delete this array using decrRef() as it is no more needed. The array
3489  *          does not contain any textual info on components.
3490  *  \throw If \a this->getNumberOfComponents() != 2.
3491  */
3492 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3493 {
3494   checkAllocated();
3495   int nbOfComp=getNumberOfComponents();
3496   if(nbOfComp!=2)
3497     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3498   int nbOfTuple=getNumberOfTuples();
3499   DataArrayDouble *ret=DataArrayDouble::New();
3500   ret->alloc(nbOfTuple,2);
3501   double *w=ret->getPointer();
3502   const double *wIn=getConstPointer();
3503   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3504     {
3505       w[0]=wIn[0]*cos(wIn[1]);
3506       w[1]=wIn[0]*sin(wIn[1]);
3507     }
3508   return ret;
3509 }
3510
3511 /*!
3512  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3513  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3514  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3515  * the Cylindrical CS.
3516  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3517  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3518  *          on the third component is copied from \a this array. The caller
3519  *          is to delete this array using decrRef() as it is no more needed. 
3520  *  \throw If \a this->getNumberOfComponents() != 3.
3521  */
3522 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3523 {
3524   checkAllocated();
3525   int nbOfComp=getNumberOfComponents();
3526   if(nbOfComp!=3)
3527     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3528   int nbOfTuple=getNumberOfTuples();
3529   DataArrayDouble *ret=DataArrayDouble::New();
3530   ret->alloc(getNumberOfTuples(),3);
3531   double *w=ret->getPointer();
3532   const double *wIn=getConstPointer();
3533   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3534     {
3535       w[0]=wIn[0]*cos(wIn[1]);
3536       w[1]=wIn[0]*sin(wIn[1]);
3537       w[2]=wIn[2];
3538     }
3539   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3540   return ret;
3541 }
3542
3543 /*!
3544  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3545  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3546  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3547  * point in the Cylindrical CS.
3548  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3549  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3550  *          on the third component is copied from \a this array. The caller
3551  *          is to delete this array using decrRef() as it is no more needed.
3552  *  \throw If \a this->getNumberOfComponents() != 3.
3553  */
3554 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3555 {
3556   checkAllocated();
3557   int nbOfComp=getNumberOfComponents();
3558   if(nbOfComp!=3)
3559     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3560   int nbOfTuple=getNumberOfTuples();
3561   DataArrayDouble *ret=DataArrayDouble::New();
3562   ret->alloc(getNumberOfTuples(),3);
3563   double *w=ret->getPointer();
3564   const double *wIn=getConstPointer();
3565   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3566     {
3567       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3568       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3569       w[2]=wIn[0]*cos(wIn[1]);
3570     }
3571   return ret;
3572 }
3573
3574 /*!
3575  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3576  * array contating 6 components.
3577  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3578  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3579  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3580  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3581  *  \throw If \a this->getNumberOfComponents() != 6.
3582  */
3583 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3584 {
3585   checkAllocated();
3586   int nbOfComp=getNumberOfComponents();
3587   if(nbOfComp!=6)
3588     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3589   DataArrayDouble *ret=DataArrayDouble::New();
3590   int nbOfTuple=getNumberOfTuples();
3591   ret->alloc(nbOfTuple,1);
3592   const double *src=getConstPointer();
3593   double *dest=ret->getPointer();
3594   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3595     *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];
3596   return ret;
3597 }
3598
3599 /*!
3600  * Computes the determinant of every square matrix defined by the tuple of \a this
3601  * array, which contains either 4, 6 or 9 components. The case of 6 components
3602  * corresponds to that of the upper triangular matrix.
3603  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3604  *          is the determinant of matrix of the corresponding tuple of \a this array.
3605  *          The caller is to delete this result array using decrRef() as it is no more
3606  *          needed. 
3607  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3608  */
3609 DataArrayDouble *DataArrayDouble::determinant() const
3610 {
3611   checkAllocated();
3612   DataArrayDouble *ret=DataArrayDouble::New();
3613   int nbOfTuple=getNumberOfTuples();
3614   ret->alloc(nbOfTuple,1);
3615   const double *src=getConstPointer();
3616   double *dest=ret->getPointer();
3617   switch(getNumberOfComponents())
3618     {
3619     case 6:
3620       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3621         *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];
3622       return ret;
3623     case 4:
3624       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3625         *dest=src[0]*src[3]-src[1]*src[2];
3626       return ret;
3627     case 9:
3628       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3629         *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];
3630       return ret;
3631     default:
3632       ret->decrRef();
3633       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3634     }
3635 }
3636
3637 /*!
3638  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3639  * \a this array, which contains 6 components.
3640  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3641  *          components, whose each tuple contains the eigenvalues of the matrix of
3642  *          corresponding tuple of \a this array. 
3643  *          The caller is to delete this result array using decrRef() as it is no more
3644  *          needed. 
3645  *  \throw If \a this->getNumberOfComponents() != 6.
3646  */
3647 DataArrayDouble *DataArrayDouble::eigenValues() const
3648 {
3649   checkAllocated();
3650   int nbOfComp=getNumberOfComponents();
3651   if(nbOfComp!=6)
3652     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3653   DataArrayDouble *ret=DataArrayDouble::New();
3654   int nbOfTuple=getNumberOfTuples();
3655   ret->alloc(nbOfTuple,3);
3656   const double *src=getConstPointer();
3657   double *dest=ret->getPointer();
3658   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3659     INTERP_KERNEL::computeEigenValues6(src,dest);
3660   return ret;
3661 }
3662
3663 /*!
3664  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3665  * \a this array, which contains 6 components.
3666  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3667  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3668  *          corresponding tuple of \a this array.
3669  *          The caller is to delete this result array using decrRef() as it is no more
3670  *          needed.
3671  *  \throw If \a this->getNumberOfComponents() != 6.
3672  */
3673 DataArrayDouble *DataArrayDouble::eigenVectors() const
3674 {
3675   checkAllocated();
3676   int nbOfComp=getNumberOfComponents();
3677   if(nbOfComp!=6)
3678     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3679   DataArrayDouble *ret=DataArrayDouble::New();
3680   int nbOfTuple=getNumberOfTuples();
3681   ret->alloc(nbOfTuple,9);
3682   const double *src=getConstPointer();
3683   double *dest=ret->getPointer();
3684   for(int i=0;i<nbOfTuple;i++,src+=6)
3685     {
3686       double tmp[3];
3687       INTERP_KERNEL::computeEigenValues6(src,tmp);
3688       for(int j=0;j<3;j++,dest+=3)
3689         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3690     }
3691   return ret;
3692 }
3693
3694 /*!
3695  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3696  * array, which contains either 4, 6 or 9 components. The case of 6 components
3697  * corresponds to that of the upper triangular matrix.
3698  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3699  *          same number of components as \a this one, whose each tuple is the inverse
3700  *          matrix of the matrix of corresponding tuple of \a this array. 
3701  *          The caller is to delete this result array using decrRef() as it is no more
3702  *          needed. 
3703  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3704  */
3705 DataArrayDouble *DataArrayDouble::inverse() const
3706 {
3707   checkAllocated();
3708   int nbOfComp=getNumberOfComponents();
3709   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3710     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3711   DataArrayDouble *ret=DataArrayDouble::New();
3712   int nbOfTuple=getNumberOfTuples();
3713   ret->alloc(nbOfTuple,nbOfComp);
3714   const double *src=getConstPointer();
3715   double *dest=ret->getPointer();
3716 if(nbOfComp==6)
3717     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3718       {
3719         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];
3720         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3721         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3722         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3723         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3724         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3725         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3726       }
3727   else if(nbOfComp==4)
3728     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3729       {
3730         double det=src[0]*src[3]-src[1]*src[2];
3731         dest[0]=src[3]/det;
3732         dest[1]=-src[1]/det;
3733         dest[2]=-src[2]/det;
3734         dest[3]=src[0]/det;
3735       }
3736   else
3737     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3738       {
3739         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];
3740         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3741         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3742         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3743         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3744         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3745         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3746         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3747         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3748         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3749       }
3750   return ret;
3751 }
3752
3753 /*!
3754  * Computes the trace of every matrix defined by the tuple of \a this
3755  * array, which contains either 4, 6 or 9 components. The case of 6 components
3756  * corresponds to that of the upper triangular matrix.
3757  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3758  *          1 component, whose each tuple is the trace of
3759  *          the matrix of corresponding tuple of \a this array. 
3760  *          The caller is to delete this result array using decrRef() as it is no more
3761  *          needed. 
3762  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3763  */
3764 DataArrayDouble *DataArrayDouble::trace() const
3765 {
3766   checkAllocated();
3767   int nbOfComp=getNumberOfComponents();
3768   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3769     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3770   DataArrayDouble *ret=DataArrayDouble::New();
3771   int nbOfTuple=getNumberOfTuples();
3772   ret->alloc(nbOfTuple,1);
3773   const double *src=getConstPointer();
3774   double *dest=ret->getPointer();
3775   if(nbOfComp==6)
3776     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3777       *dest=src[0]+src[1]+src[2];
3778   else if(nbOfComp==4)
3779     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3780       *dest=src[0]+src[3];
3781   else
3782     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3783       *dest=src[0]+src[4]+src[8];
3784   return ret;
3785 }
3786
3787 /*!
3788  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3789  * \a this array, which contains 6 components.
3790  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3791  *          same number of components and tuples as \a this array.
3792  *          The caller is to delete this result array using decrRef() as it is no more
3793  *          needed.
3794  *  \throw If \a this->getNumberOfComponents() != 6.
3795  */
3796 DataArrayDouble *DataArrayDouble::deviator() const
3797 {
3798   checkAllocated();
3799   int nbOfComp=getNumberOfComponents();
3800   if(nbOfComp!=6)
3801     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3802   DataArrayDouble *ret=DataArrayDouble::New();
3803   int nbOfTuple=getNumberOfTuples();
3804   ret->alloc(nbOfTuple,6);
3805   const double *src=getConstPointer();
3806   double *dest=ret->getPointer();
3807   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3808     {
3809       double tr=(src[0]+src[1]+src[2])/3.;
3810       dest[0]=src[0]-tr;
3811       dest[1]=src[1]-tr;
3812       dest[2]=src[2]-tr;
3813       dest[3]=src[3];
3814       dest[4]=src[4];
3815       dest[5]=src[5];
3816     }
3817   return ret;
3818 }
3819
3820 /*!
3821  * Computes the magnitude of every vector defined by the tuple of
3822  * \a this array.
3823  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3824  *          same number of tuples as \a this array and one component.
3825  *          The caller is to delete this result array using decrRef() as it is no more
3826  *          needed.
3827  *  \throw If \a this is not allocated.
3828  */
3829 DataArrayDouble *DataArrayDouble::magnitude() const
3830 {
3831   checkAllocated();
3832   int nbOfComp=getNumberOfComponents();
3833   DataArrayDouble *ret=DataArrayDouble::New();
3834   int nbOfTuple=getNumberOfTuples();
3835   ret->alloc(nbOfTuple,1);
3836   const double *src=getConstPointer();
3837   double *dest=ret->getPointer();
3838   for(int i=0;i<nbOfTuple;i++,dest++)
3839     {
3840       double sum=0.;
3841       for(int j=0;j<nbOfComp;j++,src++)
3842         sum+=(*src)*(*src);
3843       *dest=sqrt(sum);
3844     }
3845   return ret;
3846 }
3847
3848 /*!
3849  * Computes for each tuple the sum of number of components values in the tuple and return it.
3850  * 
3851  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3852  *          same number of tuples as \a this array and one component.
3853  *          The caller is to delete this result array using decrRef() as it is no more
3854  *          needed.
3855  *  \throw If \a this is not allocated.
3856  */
3857 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3858 {
3859   checkAllocated();
3860   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3861   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3862   ret->alloc(nbOfTuple,1);
3863   const double *src(getConstPointer());
3864   double *dest(ret->getPointer());
3865   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3866     *dest=std::accumulate(src,src+nbOfComp,0.);
3867   return ret.retn();
3868 }
3869
3870 /*!
3871  * Computes the maximal value within every tuple of \a this array.
3872  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3873  *          same number of tuples as \a this array and one component.
3874  *          The caller is to delete this result array using decrRef() as it is no more
3875  *          needed.
3876  *  \throw If \a this is not allocated.
3877  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3878  */
3879 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3880 {
3881   checkAllocated();
3882   int nbOfComp=getNumberOfComponents();
3883   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3884   int nbOfTuple=getNumberOfTuples();
3885   ret->alloc(nbOfTuple,1);
3886   const double *src=getConstPointer();
3887   double *dest=ret->getPointer();
3888   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3889     *dest=*std::max_element(src,src+nbOfComp);
3890   return ret.retn();
3891 }
3892
3893 /*!
3894  * Computes the maximal value within every tuple of \a this array and it returns the first component
3895  * id for each tuple that corresponds to the maximal value within the tuple.
3896  * 
3897  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3898  *          same number of tuples and only one component.
3899  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3900  *          same number of tuples as \a this array and one component.
3901  *          The caller is to delete this result array using decrRef() as it is no more
3902  *          needed.
3903  *  \throw If \a this is not allocated.
3904  *  \sa DataArrayDouble::maxPerTuple
3905  */
3906 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3907 {
3908   checkAllocated();
3909   int nbOfComp=getNumberOfComponents();
3910   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3911   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3912   int nbOfTuple=getNumberOfTuples();
3913   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3914   const double *src=getConstPointer();
3915   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3916   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3917     {
3918       const double *loc=std::max_element(src,src+nbOfComp);
3919       *dest=*loc;
3920       *dest1=(int)std::distance(src,loc);
3921     }
3922   compoIdOfMaxPerTuple=ret1.retn();
3923   return ret0.retn();
3924 }
3925
3926 /*!
3927  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3928  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3929  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3930  * \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)
3931  *
3932  * \warning use this method with care because it can leads to big amount of consumed memory !
3933  * 
3934  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3935  *
3936  * \throw If \a this is not allocated.
3937  *
3938  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3939  */
3940 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3941 {
3942   checkAllocated();
3943   int nbOfComp=getNumberOfComponents();
3944   int nbOfTuples=getNumberOfTuples();
3945   const double *inData=getConstPointer();
3946   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3947   ret->alloc(nbOfTuples*nbOfTuples,1);
3948   double *outData=ret->getPointer();
3949   for(int i=0;i<nbOfTuples;i++)
3950     {
3951       outData[i*nbOfTuples+i]=0.;
3952       for(int j=i+1;j<nbOfTuples;j++)
3953         {
3954           double dist=0.;
3955           for(int k=0;k<nbOfComp;k++)
3956             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3957           dist=sqrt(dist);
3958           outData[i*nbOfTuples+j]=dist;
3959           outData[j*nbOfTuples+i]=dist;
3960         }
3961     }
3962   return ret.retn();
3963 }
3964
3965 /*!
3966  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3967  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3968  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3969  * \n Output rectangular matrix is sorted along rows.
3970  * \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)
3971  *
3972  * \warning use this method with care because it can leads to big amount of consumed memory !
3973  * 
3974  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3975  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3976  *
3977  * \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.
3978  *
3979  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3980  */
3981 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
3982 {
3983   if(!other)
3984     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3985   checkAllocated();
3986   other->checkAllocated();
3987   int nbOfComp=getNumberOfComponents();
3988   int otherNbOfComp=other->getNumberOfComponents();
3989   if(nbOfComp!=otherNbOfComp)
3990     {
3991       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3992       throw INTERP_KERNEL::Exception(oss.str().c_str());
3993     }
3994   int nbOfTuples=getNumberOfTuples();
3995   int otherNbOfTuples=other->getNumberOfTuples();
3996   const double *inData=getConstPointer();
3997   const double *inDataOther=other->getConstPointer();
3998   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3999   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4000   double *outData=ret->getPointer();
4001   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4002     {
4003       for(int j=0;j<nbOfTuples;j++)
4004         {
4005           double dist=0.;
4006           for(int k=0;k<nbOfComp;k++)
4007             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4008           dist=sqrt(dist);
4009           outData[i*nbOfTuples+j]=dist;
4010         }
4011     }
4012   return ret.retn();
4013 }
4014
4015 /*!
4016  * Sorts value within every tuple of \a this array.
4017  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4018  *              in descending order.
4019  *  \throw If \a this is not allocated.
4020  */
4021 void DataArrayDouble::sortPerTuple(bool asc)
4022 {
4023   checkAllocated();
4024   double *pt=getPointer();
4025   int nbOfTuple=getNumberOfTuples();
4026   int nbOfComp=getNumberOfComponents();
4027   if(asc)
4028     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4029       std::sort(pt,pt+nbOfComp);
4030   else
4031     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4032       std::sort(pt,pt+nbOfComp,std::greater<double>());
4033   declareAsNew();
4034 }
4035
4036 /*!
4037  * Converts every value of \a this array to its absolute value.
4038  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4039  * should be called instead.
4040  *
4041  * \throw If \a this is not allocated.
4042  * \sa DataArrayDouble::computeAbs
4043  */
4044 void DataArrayDouble::abs()
4045 {
4046   checkAllocated();
4047   double *ptr(getPointer());
4048   std::size_t nbOfElems(getNbOfElems());
4049   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4050   declareAsNew();
4051 }
4052
4053 /*!
4054  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4055  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4056  *
4057  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4058  *         same number of tuples and component as \a this array.
4059  *         The caller is to delete this result array using decrRef() as it is no more
4060  *         needed.
4061  * \throw If \a this is not allocated.
4062  * \sa DataArrayDouble::abs
4063  */
4064 DataArrayDouble *DataArrayDouble::computeAbs() const
4065 {
4066   checkAllocated();
4067   DataArrayDouble *newArr(DataArrayDouble::New());
4068   int nbOfTuples(getNumberOfTuples());
4069   int nbOfComp(getNumberOfComponents());
4070   newArr->alloc(nbOfTuples,nbOfComp);
4071   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4072   newArr->copyStringInfoFrom(*this);
4073   return newArr;
4074 }
4075
4076 /*!
4077  * Apply a liner function to a given component of \a this array, so that
4078  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4079  *  \param [in] a - the first coefficient of the function.
4080  *  \param [in] b - the second coefficient of the function.
4081  *  \param [in] compoId - the index of component to modify.
4082  *  \throw If \a this is not allocated.
4083  */
4084 void DataArrayDouble::applyLin(double a, double b, int compoId)
4085 {
4086   checkAllocated();
4087   double *ptr=getPointer()+compoId;
4088   int nbOfComp=getNumberOfComponents();
4089   int nbOfTuple=getNumberOfTuples();
4090   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4091     *ptr=a*(*ptr)+b;
4092   declareAsNew();
4093 }
4094
4095 /*!
4096  * Apply a liner function to all elements of \a this array, so that
4097  * an element _x_ becomes \f$ a * x + b \f$.
4098  *  \param [in] a - the first coefficient of the function.
4099  *  \param [in] b - the second coefficient of the function.
4100  *  \throw If \a this is not allocated.
4101  */
4102 void DataArrayDouble::applyLin(double a, double b)
4103 {
4104   checkAllocated();
4105   double *ptr=getPointer();
4106   std::size_t nbOfElems=getNbOfElems();
4107   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4108     *ptr=a*(*ptr)+b;
4109   declareAsNew();
4110 }
4111
4112 /*!
4113  * Modify all elements of \a this array, so that
4114  * an element _x_ becomes \f$ numerator / x \f$.
4115  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4116  *           array, all elements processed before detection of the zero element remain
4117  *           modified.
4118  *  \param [in] numerator - the numerator used to modify array elements.
4119  *  \throw If \a this is not allocated.
4120  *  \throw If there is an element equal to 0.0 in \a this array.
4121  */
4122 void DataArrayDouble::applyInv(double numerator)
4123 {
4124   checkAllocated();
4125   double *ptr=getPointer();
4126   std::size_t nbOfElems=getNbOfElems();
4127   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4128     {
4129       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4130         {
4131           *ptr=numerator/(*ptr);
4132         }
4133       else
4134         {
4135           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4136           oss << " !";
4137           throw INTERP_KERNEL::Exception(oss.str().c_str());
4138         }
4139     }
4140   declareAsNew();
4141 }
4142
4143 /*!
4144  * Returns a full copy of \a this array except that sign of all elements is reversed.
4145  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4146  *          same number of tuples and component as \a this array.
4147  *          The caller is to delete this result array using decrRef() as it is no more
4148  *          needed.
4149  *  \throw If \a this is not allocated.
4150  */
4151 DataArrayDouble *DataArrayDouble::negate() const
4152 {
4153   checkAllocated();
4154   DataArrayDouble *newArr=DataArrayDouble::New();
4155   int nbOfTuples=getNumberOfTuples();
4156   int nbOfComp=getNumberOfComponents();
4157   newArr->alloc(nbOfTuples,nbOfComp);
4158   const double *cptr=getConstPointer();
4159   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4160   newArr->copyStringInfoFrom(*this);
4161   return newArr;
4162 }
4163
4164 /*!
4165  * Modify all elements of \a this array, so that
4166  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4167  * all values in \a this have to be >= 0 if val is \b not integer.
4168  *  \param [in] val - the value used to apply pow on all array elements.
4169  *  \throw If \a this is not allocated.
4170  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4171  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4172  *           modified.
4173  */
4174 void DataArrayDouble::applyPow(double val)
4175 {
4176   checkAllocated();
4177   double *ptr=getPointer();
4178   std::size_t nbOfElems=getNbOfElems();
4179   int val2=(int)val;
4180   bool isInt=((double)val2)==val;
4181   if(!isInt)
4182     {
4183       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4184         {
4185           if(*ptr>=0)
4186             *ptr=pow(*ptr,val);
4187           else
4188             {
4189               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4190               throw INTERP_KERNEL::Exception(oss.str().c_str());
4191             }
4192         }
4193     }
4194   else
4195     {
4196       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4197         *ptr=pow(*ptr,val2);
4198     }
4199   declareAsNew();
4200 }
4201
4202 /*!
4203  * Modify all elements of \a this array, so that
4204  * an element _x_ becomes \f$ val ^ x \f$.
4205  *  \param [in] val - the value used to apply pow on all array elements.
4206  *  \throw If \a this is not allocated.
4207  *  \throw If \a val < 0.
4208  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4209  *           array, all elements processed before detection of the zero element remain
4210  *           modified.
4211  */
4212 void DataArrayDouble::applyRPow(double val)
4213 {
4214   checkAllocated();
4215   if(val<0.)
4216     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4217   double *ptr=getPointer();
4218   std::size_t nbOfElems=getNbOfElems();
4219   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4220     *ptr=pow(val,*ptr);
4221   declareAsNew();
4222 }
4223
4224 /*!
4225  * Returns a new DataArrayDouble created from \a this one by applying \a
4226  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4227  * For more info see \ref MEDCouplingArrayApplyFunc
4228  *  \param [in] nbOfComp - number of components in the result array.
4229  *  \param [in] func - the \a FunctionToEvaluate declared as 
4230  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4231  *              where \a pos points to the first component of a tuple of \a this array
4232  *              and \a res points to the first component of a tuple of the result array.
4233  *              Note that length (number of components) of \a pos can differ from
4234  *              that of \a res.
4235  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4236  *          same number of tuples as \a this array.
4237  *          The caller is to delete this result array using decrRef() as it is no more
4238  *          needed.
4239  *  \throw If \a this is not allocated.
4240  *  \throw If \a func returns \a false.
4241  */
4242 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4243 {
4244   checkAllocated();
4245   DataArrayDouble *newArr=DataArrayDouble::New();
4246   int nbOfTuples=getNumberOfTuples();
4247   int oldNbOfComp=getNumberOfComponents();
4248   newArr->alloc(nbOfTuples,nbOfComp);
4249   const double *ptr=getConstPointer();
4250   double *ptrToFill=newArr->getPointer();
4251   for(int i=0;i<nbOfTuples;i++)
4252     {
4253       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4254         {
4255           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4256           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4257           oss << ") : Evaluation of function failed !";
4258           newArr->decrRef();
4259           throw INTERP_KERNEL::Exception(oss.str().c_str());
4260         }
4261     }
4262   return newArr;
4263 }
4264
4265 /*!
4266  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4267  * tuple of \a this array. Textual data is not copied.
4268  * For more info see \ref MEDCouplingArrayApplyFunc1.
4269  *  \param [in] nbOfComp - number of components in the result array.
4270  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4271  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4272  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4273  *          same number of tuples as \a this array and \a nbOfComp components.
4274  *          The caller is to delete this result array using decrRef() as it is no more
4275  *          needed.
4276  *  \throw If \a this is not allocated.
4277  *  \throw If computing \a func fails.
4278  */
4279 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const
4280 {
4281   checkAllocated();
4282   INTERP_KERNEL::ExprParser expr(func);
4283   expr.parse();
4284   std::set<std::string> vars;
4285   expr.getTrueSetOfVars(vars);
4286   int oldNbOfComp=getNumberOfComponents();
4287   if((int)vars.size()>oldNbOfComp)
4288     {
4289       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4290       oss << vars.size() << " variables : ";
4291       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4292       throw INTERP_KERNEL::Exception(oss.str().c_str());
4293     }
4294   std::vector<std::string> varsV(vars.begin(),vars.end());
4295   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4296   //
4297   DataArrayDouble *newArr=DataArrayDouble::New();
4298   int nbOfTuples=getNumberOfTuples();
4299   newArr->alloc(nbOfTuples,nbOfComp);
4300   const double *ptr=getConstPointer();
4301   double *ptrToFill=newArr->getPointer();
4302   for(int i=0;i<nbOfTuples;i++)
4303     {
4304       try
4305         {
4306           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4307         }
4308       catch(INTERP_KERNEL::Exception& e)
4309         {
4310           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4311           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4312           oss << ") : Evaluation of function failed !" << e.what();
4313           newArr->decrRef();
4314           throw INTERP_KERNEL::Exception(oss.str().c_str());
4315         }
4316     }
4317   return newArr;
4318 }
4319
4320 /*!
4321  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4322  * tuple of \a this array. Textual data is not copied.
4323  * For more info see \ref MEDCouplingArrayApplyFunc0.
4324  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4325  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4326  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4327  *          same number of tuples and components as \a this array.
4328  *          The caller is to delete this result array using decrRef() as it is no more
4329  *          needed.
4330  *  \throw If \a this is not allocated.
4331  *  \throw If computing \a func fails.
4332  */
4333 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const
4334 {
4335   checkAllocated();
4336   INTERP_KERNEL::ExprParser expr(func);
4337   expr.parse();
4338   expr.prepareExprEvaluationVec();
4339   //
4340   DataArrayDouble *newArr=DataArrayDouble::New();
4341   int nbOfTuples=getNumberOfTuples();
4342   int nbOfComp=getNumberOfComponents();
4343   newArr->alloc(nbOfTuples,nbOfComp);
4344   const double *ptr=getConstPointer();
4345   double *ptrToFill=newArr->getPointer();
4346   for(int i=0;i<nbOfTuples;i++)
4347     {
4348       try
4349         {
4350           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4351         }
4352       catch(INTERP_KERNEL::Exception& e)
4353         {
4354           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4355           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4356           oss << ") : Evaluation of function failed ! " << e.what();
4357           newArr->decrRef();
4358           throw INTERP_KERNEL::Exception(oss.str().c_str());
4359         }
4360     }
4361   return newArr;
4362 }
4363
4364 /*!
4365  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4366  * tuple of \a this array. Textual data is not copied.
4367  * For more info see \ref MEDCouplingArrayApplyFunc2.
4368  *  \param [in] nbOfComp - number of components in the result array.
4369  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4370  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4371  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4372  *          same number of tuples as \a this array.
4373  *          The caller is to delete this result array using decrRef() as it is no more
4374  *          needed.
4375  *  \throw If \a this is not allocated.
4376  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4377  *  \throw If computing \a func fails.
4378  */
4379 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const
4380 {
4381   checkAllocated();
4382   INTERP_KERNEL::ExprParser expr(func);
4383   expr.parse();
4384   std::set<std::string> vars;
4385   expr.getTrueSetOfVars(vars);
4386   int oldNbOfComp=getNumberOfComponents();
4387   if((int)vars.size()>oldNbOfComp)
4388     {
4389       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4390       oss << vars.size() << " variables : ";
4391       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4392       throw INTERP_KERNEL::Exception(oss.str().c_str());
4393     }
4394   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4395   //
4396   DataArrayDouble *newArr=DataArrayDouble::New();
4397   int nbOfTuples=getNumberOfTuples();
4398   newArr->alloc(nbOfTuples,nbOfComp);
4399   const double *ptr=getConstPointer();
4400   double *ptrToFill=newArr->getPointer();
4401   for(int i=0;i<nbOfTuples;i++)
4402     {
4403       try
4404         {
4405           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4406         }
4407       catch(INTERP_KERNEL::Exception& e)
4408         {
4409           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4410           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4411           oss << ") : Evaluation of function failed !" << e.what();
4412           newArr->decrRef();
4413           throw INTERP_KERNEL::Exception(oss.str().c_str());
4414         }
4415     }
4416   return newArr;
4417 }
4418
4419 /*!
4420  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4421  * tuple of \a this array. Textual data is not copied.
4422  * For more info see \ref MEDCouplingArrayApplyFunc3.
4423  *  \param [in] nbOfComp - number of components in the result array.
4424  *  \param [in] varsOrder - sequence of vars defining their order.
4425  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4426  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4427  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4428  *          same number of tuples as \a this array.
4429  *          The caller is to delete this result array using decrRef() as it is no more
4430  *          needed.
4431  *  \throw If \a this is not allocated.
4432  *  \throw If \a func contains vars not in \a varsOrder.
4433  *  \throw If computing \a func fails.
4434  */
4435 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
4436 {
4437   checkAllocated();
4438   INTERP_KERNEL::ExprParser expr(func);
4439   expr.parse();
4440   std::set<std::string> vars;
4441   expr.getTrueSetOfVars(vars);
4442   int oldNbOfComp=getNumberOfComponents();
4443   if((int)vars.size()>oldNbOfComp)
4444     {
4445       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4446       oss << vars.size() << " variables : ";
4447       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4448       throw INTERP_KERNEL::Exception(oss.str().c_str());
4449     }
4450   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4451   //
4452   DataArrayDouble *newArr=DataArrayDouble::New();
4453   int nbOfTuples=getNumberOfTuples();
4454   newArr->alloc(nbOfTuples,nbOfComp);
4455   const double *ptr=getConstPointer();
4456   double *ptrToFill=newArr->getPointer();
4457   for(int i=0;i<nbOfTuples;i++)
4458     {
4459       try
4460         {
4461           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4462         }
4463       catch(INTERP_KERNEL::Exception& e)
4464         {
4465           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4466           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4467           oss << ") : Evaluation of function failed !" << e.what();
4468           newArr->decrRef();
4469           throw INTERP_KERNEL::Exception(oss.str().c_str());
4470         }
4471     }
4472   return newArr;
4473 }
4474
4475 void DataArrayDouble::applyFuncFast32(const char *func)
4476 {
4477   checkAllocated();
4478   INTERP_KERNEL::ExprParser expr(func);
4479   expr.parse();
4480   char *funcStr=expr.compileX86();
4481   MYFUNCPTR funcPtr;
4482   *((void **)&funcPtr)=funcStr;//he he...
4483   //
4484   double *ptr=getPointer();
4485   int nbOfComp=getNumberOfComponents();
4486   int nbOfTuples=getNumberOfTuples();
4487   int nbOfElems=nbOfTuples*nbOfComp;
4488   for(int i=0;i<nbOfElems;i++,ptr++)
4489     *ptr=funcPtr(*ptr);
4490   declareAsNew();
4491 }
4492
4493 void DataArrayDouble::applyFuncFast64(const char *func)
4494 {
4495   checkAllocated();
4496   INTERP_KERNEL::ExprParser expr(func);
4497   expr.parse();
4498   char *funcStr=expr.compileX86_64();
4499   MYFUNCPTR funcPtr;
4500   *((void **)&funcPtr)=funcStr;//he he...
4501   //
4502   double *ptr=getPointer();
4503   int nbOfComp=getNumberOfComponents();
4504   int nbOfTuples=getNumberOfTuples();
4505   int nbOfElems=nbOfTuples*nbOfComp;
4506   for(int i=0;i<nbOfElems;i++,ptr++)
4507     *ptr=funcPtr(*ptr);
4508   declareAsNew();
4509 }
4510
4511 DataArrayDoubleIterator *DataArrayDouble::iterator()
4512 {
4513   return new DataArrayDoubleIterator(this);
4514 }
4515
4516 /*!
4517  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4518  * array whose values are within a given range. Textual data is not copied.
4519  *  \param [in] vmin - a lowest acceptable value (included).
4520  *  \param [in] vmax - a greatest acceptable value (included).
4521  *  \return DataArrayInt * - the new instance of DataArrayInt.
4522  *          The caller is to delete this result array using decrRef() as it is no more
4523  *          needed.
4524  *  \throw If \a this->getNumberOfComponents() != 1.
4525  *
4526  *  \sa DataArrayDouble::getIdsNotInRange
4527  *
4528  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4529  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4530  */
4531 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4532 {
4533   checkAllocated();
4534   if(getNumberOfComponents()!=1)
4535     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4536   const double *cptr(begin());
4537   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4538   int nbOfTuples(getNumberOfTuples());
4539   for(int i=0;i<nbOfTuples;i++,cptr++)
4540     if(*cptr>=vmin && *cptr<=vmax)
4541       ret->pushBackSilent(i);
4542   return ret.retn();
4543 }
4544
4545 /*!
4546  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4547  * array whose values are not within a given range. Textual data is not copied.
4548  *  \param [in] vmin - a lowest not acceptable value (excluded).
4549  *  \param [in] vmax - a greatest not acceptable value (excluded).
4550  *  \return DataArrayInt * - the new instance of DataArrayInt.
4551  *          The caller is to delete this result array using decrRef() as it is no more
4552  *          needed.
4553  *  \throw If \a this->getNumberOfComponents() != 1.
4554  *
4555  *  \sa DataArrayDouble::getIdsInRange
4556  */
4557 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4558 {
4559   checkAllocated();
4560   if(getNumberOfComponents()!=1)
4561     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4562   const double *cptr(begin());
4563   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4564   int nbOfTuples(getNumberOfTuples());
4565   for(int i=0;i<nbOfTuples;i++,cptr++)
4566     if(*cptr<vmin || *cptr>vmax)
4567       ret->pushBackSilent(i);
4568   return ret.retn();
4569 }
4570
4571 /*!
4572  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4573  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4574  * the number of component in the result array is same as that of each of given arrays.
4575  * Info on components is copied from the first of the given arrays. Number of components
4576  * in the given arrays must be  the same.
4577  *  \param [in] a1 - an array to include in the result array.
4578  *  \param [in] a2 - another array to include in the result array.
4579  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4580  *          The caller is to delete this result array using decrRef() as it is no more
4581  *          needed.
4582  *  \throw If both \a a1 and \a a2 are NULL.
4583  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4584  */
4585 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4586 {
4587   std::vector<const DataArrayDouble *> tmp(2);
4588   tmp[0]=a1; tmp[1]=a2;
4589   return Aggregate(tmp);
4590 }
4591
4592 /*!
4593  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4594  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4595  * the number of component in the result array is same as that of each of given arrays.
4596  * Info on components is copied from the first of the given arrays. Number of components
4597  * in the given arrays must be  the same.
4598  *  \param [in] arr - a sequence of arrays to include in the result array.
4599  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4600  *          The caller is to delete this result array using decrRef() as it is no more
4601  *          needed.
4602  *  \throw If all arrays within \a arr are NULL.
4603  *  \throw If getNumberOfComponents() of arrays within \a arr.
4604  */
4605 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4606 {
4607   std::vector<const DataArrayDouble *> a;
4608   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4609     if(*it4)
4610       a.push_back(*it4);
4611   if(a.empty())
4612     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4613   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4614   int nbOfComp=(*it)->getNumberOfComponents();
4615   int nbt=(*it++)->getNumberOfTuples();
4616   for(int i=1;it!=a.end();it++,i++)
4617     {
4618       if((*it)->getNumberOfComponents()!=nbOfComp)
4619         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4620       nbt+=(*it)->getNumberOfTuples();
4621     }
4622   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4623   ret->alloc(nbt,nbOfComp);
4624   double *pt=ret->getPointer();
4625   for(it=a.begin();it!=a.end();it++)
4626     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4627   ret->copyStringInfoFrom(*(a[0]));
4628   return ret.retn();
4629 }
4630
4631 /*!
4632  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4633  * of components in the result array is a sum of the number of components of given arrays
4634  * and (2) the number of tuples in the result array is same as that of each of given
4635  * arrays. In other words the i-th tuple of result array includes all components of
4636  * i-th tuples of all given arrays.
4637  * Number of tuples in the given arrays must be  the same.
4638  *  \param [in] a1 - an array to include in the result array.
4639  *  \param [in] a2 - another array to include in the result array.
4640  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4641  *          The caller is to delete this result array using decrRef() as it is no more
4642  *          needed.
4643  *  \throw If both \a a1 and \a a2 are NULL.
4644  *  \throw If any given array is not allocated.
4645  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4646  */
4647 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4648 {
4649   std::vector<const DataArrayDouble *> arr(2);
4650   arr[0]=a1; arr[1]=a2;
4651   return Meld(arr);
4652 }
4653
4654 /*!
4655  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4656  * of components in the result array is a sum of the number of components of given arrays
4657  * and (2) the number of tuples in the result array is same as that of each of given
4658  * arrays. In other words the i-th tuple of result array includes all components of
4659  * i-th tuples of all given arrays.
4660  * Number of tuples in the given arrays must be  the same.
4661  *  \param [in] arr - a sequence of arrays to include in the result array.
4662  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4663  *          The caller is to delete this result array using decrRef() as it is no more
4664  *          needed.
4665  *  \throw If all arrays within \a arr are NULL.
4666  *  \throw If any given array is not allocated.
4667  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4668  */
4669 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4670 {
4671   std::vector<const DataArrayDouble *> a;
4672   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4673     if(*it4)
4674       a.push_back(*it4);
4675   if(a.empty())
4676     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4677   std::vector<const DataArrayDouble *>::const_iterator it;
4678   for(it=a.begin();it!=a.end();it++)
4679     (*it)->checkAllocated();
4680   it=a.begin();
4681   int nbOfTuples=(*it)->getNumberOfTuples();
4682   std::vector<int> nbc(a.size());
4683   std::vector<const double *> pts(a.size());
4684   nbc[0]=(*it)->getNumberOfComponents();
4685   pts[0]=(*it++)->getConstPointer();
4686   for(int i=1;it!=a.end();it++,i++)
4687     {
4688       if(nbOfTuples!=(*it)->getNumberOfTuples())
4689         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4690       nbc[i]=(*it)->getNumberOfComponents();
4691       pts[i]=(*it)->getConstPointer();
4692     }
4693   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4694   DataArrayDouble *ret=DataArrayDouble::New();
4695   ret->alloc(nbOfTuples,totalNbOfComp);
4696   double *retPtr=ret->getPointer();
4697   for(int i=0;i<nbOfTuples;i++)
4698     for(int j=0;j<(int)a.size();j++)
4699       {
4700         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4701         pts[j]+=nbc[j];
4702       }
4703   int k=0;
4704   for(int i=0;i<(int)a.size();i++)
4705     for(int j=0;j<nbc[i];j++,k++)
4706       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4707   return ret;
4708 }
4709
4710 /*!
4711  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4712  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4713  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4714  * Info on components and name is copied from the first of the given arrays.
4715  * Number of tuples and components in the given arrays must be the same.
4716  *  \param [in] a1 - a given array.
4717  *  \param [in] a2 - another given array.
4718  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4719  *          The caller is to delete this result array using decrRef() as it is no more
4720  *          needed.
4721  *  \throw If either \a a1 or \a a2 is NULL.
4722  *  \throw If any given array is not allocated.
4723  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4724  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4725  */
4726 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4727 {
4728   if(!a1 || !a2)
4729     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4730   a1->checkAllocated();
4731   a2->checkAllocated();
4732   int nbOfComp=a1->getNumberOfComponents();
4733   if(nbOfComp!=a2->getNumberOfComponents())
4734     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4735   int nbOfTuple=a1->getNumberOfTuples();
4736   if(nbOfTuple!=a2->getNumberOfTuples())
4737     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4738   DataArrayDouble *ret=DataArrayDouble::New();
4739   ret->alloc(nbOfTuple,1);
4740   double *retPtr=ret->getPointer();
4741   const double *a1Ptr=a1->getConstPointer();
4742   const double *a2Ptr=a2->getConstPointer();
4743   for(int i=0;i<nbOfTuple;i++)
4744     {
4745       double sum=0.;
4746       for(int j=0;j<nbOfComp;j++)
4747         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4748       retPtr[i]=sum;
4749     }
4750   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4751   ret->setName(a1->getName().c_str());
4752   return ret;
4753 }
4754
4755 /*!
4756  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4757  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4758  * product of two vectors defined by the i-th tuples of given arrays.
4759  * Info on components is copied from the first of the given arrays.
4760  * Number of tuples in the given arrays must be the same.
4761  * Number of components in the given arrays must be 3.
4762  *  \param [in] a1 - a given array.
4763  *  \param [in] a2 - another given array.
4764  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4765  *          The caller is to delete this result array using decrRef() as it is no more
4766  *          needed.
4767  *  \throw If either \a a1 or \a a2 is NULL.
4768  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4769  *  \throw If \a a1->getNumberOfComponents() != 3
4770  *  \throw If \a a2->getNumberOfComponents() != 3
4771  */
4772 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4773 {
4774   if(!a1 || !a2)
4775     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4776   int nbOfComp=a1->getNumberOfComponents();
4777   if(nbOfComp!=a2->getNumberOfComponents())
4778     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4779   if(nbOfComp!=3)
4780     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4781   int nbOfTuple=a1->getNumberOfTuples();
4782   if(nbOfTuple!=a2->getNumberOfTuples())
4783     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4784   DataArrayDouble *ret=DataArrayDouble::New();
4785   ret->alloc(nbOfTuple,3);
4786   double *retPtr=ret->getPointer();
4787   const double *a1Ptr=a1->getConstPointer();
4788   const double *a2Ptr=a2->getConstPointer();
4789   for(int i=0;i<nbOfTuple;i++)
4790     {
4791       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4792       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4793       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4794     }
4795   ret->copyStringInfoFrom(*a1);
4796   return ret;
4797 }
4798
4799 /*!
4800  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4801  * Info on components is copied from the first of the given arrays.
4802  * Number of tuples and components in the given arrays must be the same.
4803  *  \param [in] a1 - an array to compare values with another one.
4804  *  \param [in] a2 - another array to compare values with the first one.
4805  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4806  *          The caller is to delete this result array using decrRef() as it is no more
4807  *          needed.
4808  *  \throw If either \a a1 or \a a2 is NULL.
4809  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4810  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4811  */
4812 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4813 {
4814   if(!a1 || !a2)
4815     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4816   int nbOfComp=a1->getNumberOfComponents();
4817   if(nbOfComp!=a2->getNumberOfComponents())
4818     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4819   int nbOfTuple=a1->getNumberOfTuples();
4820   if(nbOfTuple!=a2->getNumberOfTuples())
4821     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4822   DataArrayDouble *ret=DataArrayDouble::New();
4823   ret->alloc(nbOfTuple,nbOfComp);
4824   double *retPtr=ret->getPointer();
4825   const double *a1Ptr=a1->getConstPointer();
4826   const double *a2Ptr=a2->getConstPointer();
4827   int nbElem=nbOfTuple*nbOfComp;
4828   for(int i=0;i<nbElem;i++)
4829     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4830   ret->copyStringInfoFrom(*a1);
4831   return ret;
4832 }
4833
4834 /*!
4835  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4836  * Info on components is copied from the first of the given arrays.
4837  * Number of tuples and components in the given arrays must be the same.
4838  *  \param [in] a1 - an array to compare values with another one.
4839  *  \param [in] a2 - another array to compare values with the first one.
4840  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4841  *          The caller is to delete this result array using decrRef() as it is no more
4842  *          needed.
4843  *  \throw If either \a a1 or \a a2 is NULL.
4844  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4845  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4846  */
4847 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4848 {
4849   if(!a1 || !a2)
4850     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4851   int nbOfComp=a1->getNumberOfComponents();
4852   if(nbOfComp!=a2->getNumberOfComponents())
4853     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4854   int nbOfTuple=a1->getNumberOfTuples();
4855   if(nbOfTuple!=a2->getNumberOfTuples())
4856     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4857   DataArrayDouble *ret=DataArrayDouble::New();
4858   ret->alloc(nbOfTuple,nbOfComp);
4859   double *retPtr=ret->getPointer();
4860   const double *a1Ptr=a1->getConstPointer();
4861   const double *a2Ptr=a2->getConstPointer();
4862   int nbElem=nbOfTuple*nbOfComp;
4863   for(int i=0;i<nbElem;i++)
4864     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4865   ret->copyStringInfoFrom(*a1);
4866   return ret;
4867 }
4868
4869 /*!
4870  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4871  * valid cases.
4872  * 1.  The arrays have same number of tuples and components. Then each value of
4873  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4874  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4875  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4876  *   component. Then
4877  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4878  * 3.  The arrays have same number of components and one array, say _a2_, has one
4879  *   tuple. Then
4880  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4881  *
4882  * Info on components is copied either from the first array (in the first case) or from
4883  * the array with maximal number of elements (getNbOfElems()).
4884  *  \param [in] a1 - an array to sum up.
4885  *  \param [in] a2 - another array to sum up.
4886  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4887  *          The caller is to delete this result array using decrRef() as it is no more
4888  *          needed.
4889  *  \throw If either \a a1 or \a a2 is NULL.
4890  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4891  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4892  *         none of them has number of tuples or components equal to 1.
4893  */
4894 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4895 {
4896   if(!a1 || !a2)
4897     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4898   int nbOfTuple=a1->getNumberOfTuples();
4899   int nbOfTuple2=a2->getNumberOfTuples();
4900   int nbOfComp=a1->getNumberOfComponents();
4901   int nbOfComp2=a2->getNumberOfComponents();
4902   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4903   if(nbOfTuple==nbOfTuple2)
4904     {
4905       if(nbOfComp==nbOfComp2)
4906         {
4907           ret=DataArrayDouble::New();
4908           ret->alloc(nbOfTuple,nbOfComp);
4909           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4910           ret->copyStringInfoFrom(*a1);
4911         }
4912       else
4913         {
4914           int nbOfCompMin,nbOfCompMax;
4915           const DataArrayDouble *aMin, *aMax;
4916           if(nbOfComp>nbOfComp2)
4917             {
4918               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4919               aMin=a2; aMax=a1;
4920             }
4921           else
4922             {
4923               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4924               aMin=a1; aMax=a2;
4925             }
4926           if(nbOfCompMin==1)
4927             {
4928               ret=DataArrayDouble::New();
4929               ret->alloc(nbOfTuple,nbOfCompMax);
4930               const double *aMinPtr=aMin->getConstPointer();
4931               const double *aMaxPtr=aMax->getConstPointer();
4932               double *res=ret->getPointer();
4933               for(int i=0;i<nbOfTuple;i++)
4934                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4935               ret->copyStringInfoFrom(*aMax);
4936             }
4937           else
4938             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4939         }
4940     }
4941   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4942     {
4943       if(nbOfComp==nbOfComp2)
4944         {
4945           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4946           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4947           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4948           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4949           ret=DataArrayDouble::New();
4950           ret->alloc(nbOfTupleMax,nbOfComp);
4951           double *res=ret->getPointer();
4952           for(int i=0;i<nbOfTupleMax;i++)
4953             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4954           ret->copyStringInfoFrom(*aMax);
4955         }
4956       else
4957         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4958     }
4959   else
4960     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4961   return ret.retn();
4962 }
4963
4964 /*!
4965  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4966  * valid cases.
4967  * 1.  The arrays have same number of tuples and components. Then each value of
4968  *   \a other array is added to the corresponding value of \a this array, i.e.:
4969  *   _a_ [ i, j ] += _other_ [ i, j ].
4970  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4971  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4972  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4973  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4974  *
4975  *  \param [in] other - an array to add to \a this one.
4976  *  \throw If \a other is NULL.
4977  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4978  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4979  *         \a other has number of both tuples and components not equal to 1.
4980  */
4981 void DataArrayDouble::addEqual(const DataArrayDouble *other)
4982 {
4983   if(!other)
4984     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4985   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4986   checkAllocated();
4987   other->checkAllocated();
4988   int nbOfTuple=getNumberOfTuples();
4989   int nbOfTuple2=other->getNumberOfTuples();
4990   int nbOfComp=getNumberOfComponents();
4991   int nbOfComp2=other->getNumberOfComponents();
4992   if(nbOfTuple==nbOfTuple2)
4993     {
4994       if(nbOfComp==nbOfComp2)
4995         {
4996           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4997         }
4998       else if(nbOfComp2==1)
4999         {
5000           double *ptr=getPointer();
5001           const double *ptrc=other->getConstPointer();
5002           for(int i=0;i<nbOfTuple;i++)
5003             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5004         }
5005       else
5006         throw INTERP_KERNEL::Exception(msg);
5007     }
5008   else if(nbOfTuple2==1)
5009     {
5010       if(nbOfComp2==nbOfComp)
5011         {
5012           double *ptr=getPointer();
5013           const double *ptrc=other->getConstPointer();
5014           for(int i=0;i<nbOfTuple;i++)
5015             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5016         }
5017       else
5018         throw INTERP_KERNEL::Exception(msg);
5019     }
5020   else
5021     throw INTERP_KERNEL::Exception(msg);
5022   declareAsNew();
5023 }
5024
5025 /*!
5026  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5027  * valid cases.
5028  * 1.  The arrays have same number of tuples and components. Then each value of
5029  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5030  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5031  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5032  *   component. Then
5033  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5034  * 3.  The arrays have same number of components and one array, say _a2_, has one
5035  *   tuple. Then
5036  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5037  *
5038  * Info on components is copied either from the first array (in the first case) or from
5039  * the array with maximal number of elements (getNbOfElems()).
5040  *  \param [in] a1 - an array to subtract from.
5041  *  \param [in] a2 - an array to subtract.
5042  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5043  *          The caller is to delete this result array using decrRef() as it is no more
5044  *          needed.
5045  *  \throw If either \a a1 or \a a2 is NULL.
5046  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5047  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5048  *         none of them has number of tuples or components equal to 1.
5049  */
5050 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5051 {
5052   if(!a1 || !a2)
5053     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5054   int nbOfTuple1=a1->getNumberOfTuples();
5055   int nbOfTuple2=a2->getNumberOfTuples();
5056   int nbOfComp1=a1->getNumberOfComponents();
5057   int nbOfComp2=a2->getNumberOfComponents();
5058   if(nbOfTuple2==nbOfTuple1)
5059     {
5060       if(nbOfComp1==nbOfComp2)
5061         {
5062           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5063           ret->alloc(nbOfTuple2,nbOfComp1);
5064           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5065           ret->copyStringInfoFrom(*a1);
5066           return ret.retn();
5067         }
5068       else if(nbOfComp2==1)
5069         {
5070           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5071           ret->alloc(nbOfTuple1,nbOfComp1);
5072           const double *a2Ptr=a2->getConstPointer();
5073           const double *a1Ptr=a1->getConstPointer();
5074           double *res=ret->getPointer();
5075           for(int i=0;i<nbOfTuple1;i++)
5076             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5077           ret->copyStringInfoFrom(*a1);
5078           return ret.retn();
5079         }
5080       else
5081         {
5082           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5083           return 0;
5084         }
5085     }
5086   else if(nbOfTuple2==1)
5087     {
5088       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5089       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5090       ret->alloc(nbOfTuple1,nbOfComp1);
5091       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5092       double *pt=ret->getPointer();
5093       for(int i=0;i<nbOfTuple1;i++)
5094         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5095       ret->copyStringInfoFrom(*a1);
5096       return ret.retn();
5097     }
5098   else
5099     {
5100       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5101       return 0;
5102     }
5103 }
5104
5105 /*!
5106  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5107  * valid cases.
5108  * 1.  The arrays have same number of tuples and components. Then each value of
5109  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5110  *   _a_ [ i, j ] -= _other_ [ i, j ].
5111  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5112  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5113  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5114  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5115  *
5116  *  \param [in] other - an array to subtract from \a this one.
5117  *  \throw If \a other is NULL.
5118  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5119  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5120  *         \a other has number of both tuples and components not equal to 1.
5121  */
5122 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5123 {
5124   if(!other)
5125     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5126   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5127   checkAllocated();
5128   other->checkAllocated();
5129   int nbOfTuple=getNumberOfTuples();
5130   int nbOfTuple2=other->getNumberOfTuples();
5131   int nbOfComp=getNumberOfComponents();
5132   int nbOfComp2=other->getNumberOfComponents();
5133   if(nbOfTuple==nbOfTuple2)
5134     {
5135       if(nbOfComp==nbOfComp2)
5136         {
5137           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5138         }
5139       else if(nbOfComp2==1)
5140         {
5141           double *ptr=getPointer();
5142           const double *ptrc=other->getConstPointer();
5143           for(int i=0;i<nbOfTuple;i++)
5144             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5145         }
5146       else
5147         throw INTERP_KERNEL::Exception(msg);
5148     }
5149   else if(nbOfTuple2==1)
5150     {
5151       if(nbOfComp2==nbOfComp)
5152         {
5153           double *ptr=getPointer();
5154           const double *ptrc=other->getConstPointer();
5155           for(int i=0;i<nbOfTuple;i++)
5156             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5157         }
5158       else
5159         throw INTERP_KERNEL::Exception(msg);
5160     }
5161   else
5162     throw INTERP_KERNEL::Exception(msg);
5163   declareAsNew();
5164 }
5165
5166 /*!
5167  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5168  * valid cases.
5169  * 1.  The arrays have same number of tuples and components. Then each value of
5170  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5171  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5172  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5173  *   component. Then
5174  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5175  * 3.  The arrays have same number of components and one array, say _a2_, has one
5176  *   tuple. Then
5177  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5178  *
5179  * Info on components is copied either from the first array (in the first case) or from
5180  * the array with maximal number of elements (getNbOfElems()).
5181  *  \param [in] a1 - a factor array.
5182  *  \param [in] a2 - another factor array.
5183  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5184  *          The caller is to delete this result array using decrRef() as it is no more
5185  *          needed.
5186  *  \throw If either \a a1 or \a a2 is NULL.
5187  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5188  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5189  *         none of them has number of tuples or components equal to 1.
5190  */
5191 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5192 {
5193   if(!a1 || !a2)
5194     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5195   int nbOfTuple=a1->getNumberOfTuples();
5196   int nbOfTuple2=a2->getNumberOfTuples();
5197   int nbOfComp=a1->getNumberOfComponents();
5198   int nbOfComp2=a2->getNumberOfComponents();
5199   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5200   if(nbOfTuple==nbOfTuple2)
5201     {
5202       if(nbOfComp==nbOfComp2)
5203         {
5204           ret=DataArrayDouble::New();
5205           ret->alloc(nbOfTuple,nbOfComp);
5206           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5207           ret->copyStringInfoFrom(*a1);
5208         }
5209       else
5210         {
5211           int nbOfCompMin,nbOfCompMax;
5212           const DataArrayDouble *aMin, *aMax;
5213           if(nbOfComp>nbOfComp2)
5214             {
5215               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5216               aMin=a2; aMax=a1;
5217             }
5218           else
5219             {
5220               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5221               aMin=a1; aMax=a2;
5222             }
5223           if(nbOfCompMin==1)
5224             {
5225               ret=DataArrayDouble::New();
5226               ret->alloc(nbOfTuple,nbOfCompMax);
5227               const double *aMinPtr=aMin->getConstPointer();
5228               const double *aMaxPtr=aMax->getConstPointer();
5229               double *res=ret->getPointer();
5230               for(int i=0;i<nbOfTuple;i++)
5231                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5232               ret->copyStringInfoFrom(*aMax);
5233             }
5234           else
5235             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5236         }
5237     }
5238   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5239     {
5240       if(nbOfComp==nbOfComp2)
5241         {
5242           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5243           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5244           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5245           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5246           ret=DataArrayDouble::New();
5247           ret->alloc(nbOfTupleMax,nbOfComp);
5248           double *res=ret->getPointer();
5249           for(int i=0;i<nbOfTupleMax;i++)
5250             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5251           ret->copyStringInfoFrom(*aMax);
5252         }
5253       else
5254         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5255     }
5256   else
5257     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5258   return ret.retn();
5259 }
5260
5261 /*!
5262  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5263  * valid cases.
5264  * 1.  The arrays have same number of tuples and components. Then each value of
5265  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5266  *   _this_ [ i, j ] *= _other_ [ i, j ].
5267  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5268  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5269  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5270  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5271  *
5272  *  \param [in] other - an array to multiply to \a this one.
5273  *  \throw If \a other is NULL.
5274  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5275  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5276  *         \a other has number of both tuples and components not equal to 1.
5277  */
5278 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5279 {
5280   if(!other)
5281     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5282   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5283   checkAllocated();
5284   other->checkAllocated();
5285   int nbOfTuple=getNumberOfTuples();
5286   int nbOfTuple2=other->getNumberOfTuples();
5287   int nbOfComp=getNumberOfComponents();
5288   int nbOfComp2=other->getNumberOfComponents();
5289   if(nbOfTuple==nbOfTuple2)
5290     {
5291       if(nbOfComp==nbOfComp2)
5292         {
5293           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5294         }
5295       else if(nbOfComp2==1)
5296         {
5297           double *ptr=getPointer();
5298           const double *ptrc=other->getConstPointer();
5299           for(int i=0;i<nbOfTuple;i++)
5300             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5301         }
5302       else
5303         throw INTERP_KERNEL::Exception(msg);
5304     }
5305   else if(nbOfTuple2==1)
5306     {
5307       if(nbOfComp2==nbOfComp)
5308         {
5309           double *ptr=getPointer();
5310           const double *ptrc=other->getConstPointer();
5311           for(int i=0;i<nbOfTuple;i++)
5312             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5313         }
5314       else
5315         throw INTERP_KERNEL::Exception(msg);
5316     }
5317   else
5318     throw INTERP_KERNEL::Exception(msg);
5319   declareAsNew();
5320 }
5321
5322 /*!
5323  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5324  * valid cases.
5325  * 1.  The arrays have same number of tuples and components. Then each value of
5326  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5327  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5328  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5329  *   component. Then
5330  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5331  * 3.  The arrays have same number of components and one array, say _a2_, has one
5332  *   tuple. Then
5333  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5334  *
5335  * Info on components is copied either from the first array (in the first case) or from
5336  * the array with maximal number of elements (getNbOfElems()).
5337  *  \warning No check of division by zero is performed!
5338  *  \param [in] a1 - a numerator array.
5339  *  \param [in] a2 - a denominator array.
5340  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5341  *          The caller is to delete this result array using decrRef() as it is no more
5342  *          needed.
5343  *  \throw If either \a a1 or \a a2 is NULL.
5344  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5345  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5346  *         none of them has number of tuples or components equal to 1.
5347  */
5348 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5349 {
5350   if(!a1 || !a2)
5351     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5352   int nbOfTuple1=a1->getNumberOfTuples();
5353   int nbOfTuple2=a2->getNumberOfTuples();
5354   int nbOfComp1=a1->getNumberOfComponents();
5355   int nbOfComp2=a2->getNumberOfComponents();
5356   if(nbOfTuple2==nbOfTuple1)
5357     {
5358       if(nbOfComp1==nbOfComp2)
5359         {
5360           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5361           ret->alloc(nbOfTuple2,nbOfComp1);
5362           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5363           ret->copyStringInfoFrom(*a1);
5364           return ret.retn();
5365         }
5366       else if(nbOfComp2==1)
5367         {
5368           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5369           ret->alloc(nbOfTuple1,nbOfComp1);
5370           const double *a2Ptr=a2->getConstPointer();
5371           const double *a1Ptr=a1->getConstPointer();
5372           double *res=ret->getPointer();
5373           for(int i=0;i<nbOfTuple1;i++)
5374             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5375           ret->copyStringInfoFrom(*a1);
5376           return ret.retn();
5377         }
5378       else
5379         {
5380           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5381           return 0;
5382         }
5383     }
5384   else if(nbOfTuple2==1)
5385     {
5386       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5387       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5388       ret->alloc(nbOfTuple1,nbOfComp1);
5389       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5390       double *pt=ret->getPointer();
5391       for(int i=0;i<nbOfTuple1;i++)
5392         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5393       ret->copyStringInfoFrom(*a1);
5394       return ret.retn();
5395     }
5396   else
5397     {
5398       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5399       return 0;
5400     }
5401 }
5402
5403 /*!
5404  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5405  * valid cases.
5406  * 1.  The arrays have same number of tuples and components. Then each value of
5407  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5408  *   _a_ [ i, j ] /= _other_ [ i, j ].
5409  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5410  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5411  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5412  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5413  *
5414  *  \warning No check of division by zero is performed!
5415  *  \param [in] other - an array to divide \a this one by.
5416  *  \throw If \a other is NULL.
5417  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5418  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5419  *         \a other has number of both tuples and components not equal to 1.
5420  */
5421 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5422 {
5423   if(!other)
5424     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5425   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5426   checkAllocated();
5427   other->checkAllocated();
5428   int nbOfTuple=getNumberOfTuples();
5429   int nbOfTuple2=other->getNumberOfTuples();
5430   int nbOfComp=getNumberOfComponents();
5431   int nbOfComp2=other->getNumberOfComponents();
5432   if(nbOfTuple==nbOfTuple2)
5433     {
5434       if(nbOfComp==nbOfComp2)
5435         {
5436           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5437         }
5438       else if(nbOfComp2==1)
5439         {
5440           double *ptr=getPointer();
5441           const double *ptrc=other->getConstPointer();
5442           for(int i=0;i<nbOfTuple;i++)
5443             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5444         }
5445       else
5446         throw INTERP_KERNEL::Exception(msg);
5447     }
5448   else if(nbOfTuple2==1)
5449     {
5450       if(nbOfComp2==nbOfComp)
5451         {
5452           double *ptr=getPointer();
5453           const double *ptrc=other->getConstPointer();
5454           for(int i=0;i<nbOfTuple;i++)
5455             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5456         }
5457       else
5458         throw INTERP_KERNEL::Exception(msg);
5459     }
5460   else
5461     throw INTERP_KERNEL::Exception(msg);
5462   declareAsNew();
5463 }
5464
5465 /*!
5466  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5467  * valid cases.
5468  *
5469  *  \param [in] a1 - an array to pow up.
5470  *  \param [in] a2 - another array to sum up.
5471  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5472  *          The caller is to delete this result array using decrRef() as it is no more
5473  *          needed.
5474  *  \throw If either \a a1 or \a a2 is NULL.
5475  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5476  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5477  *  \throw If there is a negative value in \a a1.
5478  */
5479 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5480 {
5481   if(!a1 || !a2)
5482     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5483   int nbOfTuple=a1->getNumberOfTuples();
5484   int nbOfTuple2=a2->getNumberOfTuples();
5485   int nbOfComp=a1->getNumberOfComponents();
5486   int nbOfComp2=a2->getNumberOfComponents();
5487   if(nbOfTuple!=nbOfTuple2)
5488     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5489   if(nbOfComp!=1 || nbOfComp2!=1)
5490     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5491   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5492   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5493   double *ptr=ret->getPointer();
5494   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5495     {
5496       if(*ptr1>=0)
5497         {
5498           *ptr=pow(*ptr1,*ptr2);
5499         }
5500       else
5501         {
5502           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5503           throw INTERP_KERNEL::Exception(oss.str().c_str());
5504         }
5505     }
5506   return ret.retn();
5507 }
5508
5509 /*!
5510  * Apply pow on values of another DataArrayDouble to values of \a this one.
5511  *
5512  *  \param [in] other - an array to pow to \a this one.
5513  *  \throw If \a other is NULL.
5514  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5515  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5516  *  \throw If there is a negative value in \a this.
5517  */
5518 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5519 {
5520   if(!other)
5521     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5522   int nbOfTuple=getNumberOfTuples();
5523   int nbOfTuple2=other->getNumberOfTuples();
5524   int nbOfComp=getNumberOfComponents();
5525   int nbOfComp2=other->getNumberOfComponents();
5526   if(nbOfTuple!=nbOfTuple2)
5527     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5528   if(nbOfComp!=1 || nbOfComp2!=1)
5529     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5530   double *ptr=getPointer();
5531   const double *ptrc=other->begin();
5532   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5533     {
5534       if(*ptr>=0)
5535         *ptr=pow(*ptr,*ptrc);
5536       else
5537         {
5538           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5539           throw INTERP_KERNEL::Exception(oss.str().c_str());
5540         }
5541     }
5542   declareAsNew();
5543 }
5544
5545 /*!
5546  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5547  * Server side.
5548  */
5549 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5550 {
5551   tinyInfo.resize(2);
5552   if(isAllocated())
5553     {
5554       tinyInfo[0]=getNumberOfTuples();
5555       tinyInfo[1]=getNumberOfComponents();
5556     }
5557   else
5558     {
5559       tinyInfo[0]=-1;
5560       tinyInfo[1]=-1;
5561     }
5562 }
5563
5564 /*!
5565  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5566  * Server side.
5567  */
5568 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5569 {
5570   if(isAllocated())
5571     {
5572       int nbOfCompo=getNumberOfComponents();
5573       tinyInfo.resize(nbOfCompo+1);
5574       tinyInfo[0]=getName();
5575       for(int i=0;i<nbOfCompo;i++)
5576         tinyInfo[i+1]=getInfoOnComponent(i);
5577     }
5578   else
5579     {
5580       tinyInfo.resize(1);
5581       tinyInfo[0]=getName();
5582     }
5583 }
5584
5585 /*!
5586  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5587  * This method returns if a feeding is needed.
5588  */
5589 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5590 {
5591   int nbOfTuple=tinyInfoI[0];
5592   int nbOfComp=tinyInfoI[1];
5593   if(nbOfTuple!=-1 || nbOfComp!=-1)
5594     {
5595       alloc(nbOfTuple,nbOfComp);
5596       return true;
5597     }
5598   return false;
5599 }
5600
5601 /*!
5602  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5603  */
5604 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5605 {
5606   setName(tinyInfoS[0].c_str());
5607   if(isAllocated())
5608     {
5609       int nbOfCompo=getNumberOfComponents();
5610       for(int i=0;i<nbOfCompo;i++)
5611         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5612     }
5613 }
5614
5615 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5616 {
5617   if(_da)
5618     {
5619       _da->incrRef();
5620       if(_da->isAllocated())
5621         {
5622           _nb_comp=da->getNumberOfComponents();
5623           _nb_tuple=da->getNumberOfTuples();
5624           _pt=da->getPointer();
5625         }
5626     }
5627 }
5628
5629 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5630 {
5631   if(_da)
5632     _da->decrRef();
5633 }
5634
5635 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5636 {
5637   if(_tuple_id<_nb_tuple)
5638     {
5639       _tuple_id++;
5640       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5641       _pt+=_nb_comp;
5642       return ret;
5643     }
5644   else
5645     return 0;
5646 }
5647
5648 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5649 {
5650 }
5651
5652
5653 std::string DataArrayDoubleTuple::repr() const
5654 {
5655   std::ostringstream oss; oss.precision(17); oss << "(";
5656   for(int i=0;i<_nb_of_compo-1;i++)
5657     oss << _pt[i] << ", ";
5658   oss << _pt[_nb_of_compo-1] << ")";
5659   return oss.str();
5660 }
5661
5662 double DataArrayDoubleTuple::doubleValue() const
5663 {
5664   if(_nb_of_compo==1)
5665     return *_pt;
5666   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5667 }
5668
5669 /*!
5670  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5671  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5672  * 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
5673  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5674  */
5675 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5676 {
5677   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5678     {
5679       DataArrayDouble *ret=DataArrayDouble::New();
5680       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5681       return ret;
5682     }
5683   else
5684     {
5685       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5686       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5687       throw INTERP_KERNEL::Exception(oss.str().c_str());
5688     }
5689 }
5690
5691 /*!
5692  * Returns a new instance of DataArrayInt. The caller is to delete this array
5693  * using decrRef() as it is no more needed. 
5694  */
5695 DataArrayInt *DataArrayInt::New()
5696 {
5697   return new DataArrayInt;
5698 }
5699
5700 /*!
5701  * Checks if raw data is allocated. Read more on the raw data
5702  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5703  *  \return bool - \a true if the raw data is allocated, \a false else.
5704  */
5705 bool DataArrayInt::isAllocated() const
5706 {
5707   return getConstPointer()!=0;
5708 }
5709
5710 /*!
5711  * Checks if raw data is allocated and throws an exception if it is not the case.
5712  *  \throw If the raw data is not allocated.
5713  */
5714 void DataArrayInt::checkAllocated() const
5715 {
5716   if(!isAllocated())
5717     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5718 }
5719
5720 /*!
5721  * This method desallocated \a this without modification of informations relative to the components.
5722  * After call of this method, DataArrayInt::isAllocated will return false.
5723  * If \a this is already not allocated, \a this is let unchanged.
5724  */
5725 void DataArrayInt::desallocate()
5726 {
5727   _mem.destroy();
5728 }
5729
5730 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5731 {
5732   std::size_t sz(_mem.getNbOfElemAllocated());
5733   sz*=sizeof(int);
5734   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5735 }
5736
5737 /*!
5738  * Returns the only one value in \a this, if and only if number of elements
5739  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5740  *  \return double - the sole value stored in \a this array.
5741  *  \throw If at least one of conditions stated above is not fulfilled.
5742  */
5743 int DataArrayInt::intValue() const
5744 {
5745   if(isAllocated())
5746     {
5747       if(getNbOfElems()==1)
5748         {
5749           return *getConstPointer();
5750         }
5751       else
5752         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5753     }
5754   else
5755     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5756 }
5757
5758 /*!
5759  * Returns an integer value characterizing \a this array, which is useful for a quick
5760  * comparison of many instances of DataArrayInt.
5761  *  \return int - the hash value.
5762  *  \throw If \a this is not allocated.
5763  */
5764 int DataArrayInt::getHashCode() const
5765 {
5766   checkAllocated();
5767   std::size_t nbOfElems=getNbOfElems();
5768   int ret=nbOfElems*65536;
5769   int delta=3;
5770   if(nbOfElems>48)
5771     delta=nbOfElems/8;
5772   int ret0=0;
5773   const int *pt=begin();
5774   for(std::size_t i=0;i<nbOfElems;i+=delta)
5775     ret0+=pt[i] & 0x1FFF;
5776   return ret+ret0;
5777 }
5778
5779 /*!
5780  * Checks the number of tuples.
5781  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5782  *  \throw If \a this is not allocated.
5783  */
5784 bool DataArrayInt::empty() const
5785 {
5786   checkAllocated();
5787   return getNumberOfTuples()==0;
5788 }
5789
5790 /*!
5791  * Returns a full copy of \a this. For more info on copying data arrays see
5792  * \ref MEDCouplingArrayBasicsCopyDeep.
5793  *  \return DataArrayInt * - a new instance of DataArrayInt.
5794  */
5795 DataArrayInt *DataArrayInt::deepCpy() const
5796 {
5797   return new DataArrayInt(*this);
5798 }
5799
5800 /*!
5801  * Returns either a \a deep or \a shallow copy of this array. For more info see
5802  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5803  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5804  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5805  *          == \a true) or \a this instance (if \a dCpy == \a false).
5806  */
5807 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5808 {
5809   if(dCpy)
5810     return deepCpy();
5811   else
5812     {
5813       incrRef();
5814       return const_cast<DataArrayInt *>(this);
5815     }
5816 }
5817
5818 /*!
5819  * Copies all the data from another DataArrayInt. For more info see
5820  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5821  *  \param [in] other - another instance of DataArrayInt to copy data from.
5822  *  \throw If the \a other is not allocated.
5823  */
5824 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5825 {
5826   other.checkAllocated();
5827   int nbOfTuples=other.getNumberOfTuples();
5828   int nbOfComp=other.getNumberOfComponents();
5829   allocIfNecessary(nbOfTuples,nbOfComp);
5830   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5831   int *pt=getPointer();
5832   const int *ptI=other.getConstPointer();
5833   for(std::size_t i=0;i<nbOfElems;i++)
5834     pt[i]=ptI[i];
5835   copyStringInfoFrom(other);
5836 }
5837
5838 /*!
5839  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5840  * 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.
5841  * If \a this has not already been allocated, number of components is set to one.
5842  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5843  * 
5844  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5845  */
5846 void DataArrayInt::reserve(std::size_t nbOfElems)
5847 {
5848   int nbCompo=getNumberOfComponents();
5849   if(nbCompo==1)
5850     {
5851       _mem.reserve(nbOfElems);
5852     }
5853   else if(nbCompo==0)
5854     {
5855       _mem.reserve(nbOfElems);
5856       _info_on_compo.resize(1);
5857     }
5858   else
5859     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5860 }
5861
5862 /*!
5863  * 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
5864  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5865  *
5866  * \param [in] val the value to be added in \a this
5867  * \throw If \a this has already been allocated with number of components different from one.
5868  * \sa DataArrayInt::pushBackValsSilent
5869  */
5870 void DataArrayInt::pushBackSilent(int val)
5871 {
5872   int nbCompo=getNumberOfComponents();
5873   if(nbCompo==1)
5874     _mem.pushBack(val);
5875   else if(nbCompo==0)
5876     {
5877       _info_on_compo.resize(1);
5878       _mem.pushBack(val);
5879     }
5880   else
5881     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5882 }
5883
5884 /*!
5885  * 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
5886  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5887  *
5888  *  \param [in] valsBg - an array of values to push at the end of \this.
5889  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5890  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5891  * \throw If \a this has already been allocated with number of components different from one.
5892  * \sa DataArrayInt::pushBackSilent
5893  */
5894 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5895 {
5896   int nbCompo=getNumberOfComponents();
5897   if(nbCompo==1)
5898     _mem.insertAtTheEnd(valsBg,valsEnd);
5899   else if(nbCompo==0)
5900     {
5901       _info_on_compo.resize(1);
5902       _mem.insertAtTheEnd(valsBg,valsEnd);
5903     }
5904   else
5905     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5906 }
5907
5908 /*!
5909  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5910  * \throw If \a this is already empty.
5911  * \throw If \a this has number of components different from one.
5912  */
5913 int DataArrayInt::popBackSilent()
5914 {
5915   if(getNumberOfComponents()==1)
5916     return _mem.popBack();
5917   else
5918     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5919 }
5920
5921 /*!
5922  * 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.
5923  *
5924  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5925  */
5926 void DataArrayInt::pack() const
5927 {
5928   _mem.pack();
5929 }
5930
5931 /*!
5932  * Allocates the raw data in memory. If exactly as same memory as needed already
5933  * allocated, it is not re-allocated.
5934  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5935  *  \param [in] nbOfCompo - number of components of data to allocate.
5936  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5937  */
5938 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5939 {
5940   if(isAllocated())
5941     {
5942       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5943         alloc(nbOfTuple,nbOfCompo);
5944     }
5945   else
5946     alloc(nbOfTuple,nbOfCompo);
5947 }
5948
5949 /*!
5950  * Allocates the raw data in memory. If the memory was already allocated, then it is
5951  * freed and re-allocated. See an example of this method use
5952  * \ref MEDCouplingArraySteps1WC "here".
5953  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5954  *  \param [in] nbOfCompo - number of components of data to allocate.
5955  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5956  */
5957 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
5958 {
5959   if(nbOfTuple<0 || nbOfCompo<0)
5960     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5961   _info_on_compo.resize(nbOfCompo);
5962   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5963   declareAsNew();
5964 }
5965
5966 /*!
5967  * Assign zero to all values in \a this array. To know more on filling arrays see
5968  * \ref MEDCouplingArrayFill.
5969  * \throw If \a this is not allocated.
5970  */
5971 void DataArrayInt::fillWithZero()
5972 {
5973   checkAllocated();
5974   _mem.fillWithValue(0);
5975   declareAsNew();
5976 }
5977
5978 /*!
5979  * Assign \a val to all values in \a this array. To know more on filling arrays see
5980  * \ref MEDCouplingArrayFill.
5981  *  \param [in] val - the value to fill with.
5982  *  \throw If \a this is not allocated.
5983  */
5984 void DataArrayInt::fillWithValue(int val)
5985 {
5986   checkAllocated();
5987   _mem.fillWithValue(val);
5988   declareAsNew();
5989 }
5990
5991 /*!
5992  * Set all values in \a this array so that the i-th element equals to \a init + i
5993  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5994  *  \param [in] init - value to assign to the first element of array.
5995  *  \throw If \a this->getNumberOfComponents() != 1
5996  *  \throw If \a this is not allocated.
5997  */
5998 void DataArrayInt::iota(int init)
5999 {
6000   checkAllocated();
6001   if(getNumberOfComponents()!=1)
6002     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6003   int *ptr=getPointer();
6004   int ntuples=getNumberOfTuples();
6005   for(int i=0;i<ntuples;i++)
6006     ptr[i]=init+i;
6007   declareAsNew();
6008 }
6009
6010 /*!
6011  * Returns a textual and human readable representation of \a this instance of
6012  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6013  *  \return std::string - text describing \a this DataArrayInt.
6014  */
6015 std::string DataArrayInt::repr() const
6016 {
6017   std::ostringstream ret;
6018   reprStream(ret);
6019   return ret.str();
6020 }
6021
6022 std::string DataArrayInt::reprZip() const
6023 {
6024   std::ostringstream ret;
6025   reprZipStream(ret);
6026   return ret.str();
6027 }
6028
6029 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
6030 {
6031   static const char SPACE[4]={' ',' ',' ',' '};
6032   checkAllocated();
6033   std::string idt(indent,' ');
6034   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6035   if(byteArr)
6036     {
6037       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6038       if(std::string(type)=="Int32")
6039         {
6040           const char *data(reinterpret_cast<const char *>(begin()));
6041           std::size_t sz(getNbOfElems()*sizeof(int));
6042           byteArr->insertAtTheEnd(data,data+sz);
6043           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6044         }
6045       else if(std::string(type)=="Int8")
6046         {
6047           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6048           std::copy(begin(),end(),(char *)tmp);
6049           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6050           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6051         }
6052       else if(std::string(type)=="UInt8")
6053         {
6054           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6055           std::copy(begin(),end(),(unsigned char *)tmp);
6056           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6057           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6058         }
6059       else
6060         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6061     }
6062   else
6063     {
6064       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6065       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6066     }
6067   ofs << std::endl << idt << "</DataArray>\n";
6068 }
6069
6070 void DataArrayInt::reprStream(std::ostream& stream) const
6071 {
6072   stream << "Name of int array : \"" << _name << "\"\n";
6073   reprWithoutNameStream(stream);
6074 }
6075
6076 void DataArrayInt::reprZipStream(std::ostream& stream) const
6077 {
6078   stream << "Name of int array : \"" << _name << "\"\n";
6079   reprZipWithoutNameStream(stream);
6080 }
6081
6082 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6083 {
6084   DataArray::reprWithoutNameStream(stream);
6085   _mem.repr(getNumberOfComponents(),stream);
6086 }
6087
6088 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6089 {
6090   DataArray::reprWithoutNameStream(stream);
6091   _mem.reprZip(getNumberOfComponents(),stream);
6092 }
6093
6094 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
6095 {
6096   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6097   const int *data=getConstPointer();
6098   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6099   if(nbTuples*nbComp>=1)
6100     {
6101       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6102       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6103       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6104       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6105     }
6106   else
6107     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6108   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6109 }
6110
6111 /*!
6112  * Method that gives a quick overvien of \a this for python.
6113  */
6114 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6115 {
6116   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6117   stream << "DataArrayInt C++ instance at " << this << ". ";
6118   if(isAllocated())
6119     {
6120       int nbOfCompo=(int)_info_on_compo.size();
6121       if(nbOfCompo>=1)
6122         {
6123           int nbOfTuples=getNumberOfTuples();
6124           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6125           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6126         }
6127       else
6128         stream << "Number of components : 0.";
6129     }
6130   else
6131     stream << "*** No data allocated ****";
6132 }
6133
6134 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6135 {
6136   const int *data=begin();
6137   int nbOfTuples=getNumberOfTuples();
6138   int nbOfCompo=(int)_info_on_compo.size();
6139   std::ostringstream oss2; oss2 << "[";
6140   std::string oss2Str(oss2.str());
6141   bool isFinished=true;
6142   for(int i=0;i<nbOfTuples && isFinished;i++)
6143     {
6144       if(nbOfCompo>1)
6145         {
6146           oss2 << "(";
6147           for(int j=0;j<nbOfCompo;j++,data++)
6148             {
6149               oss2 << *data;
6150               if(j!=nbOfCompo-1) oss2 << ", ";
6151             }
6152           oss2 << ")";
6153         }
6154       else
6155         oss2 << *data++;
6156       if(i!=nbOfTuples-1) oss2 << ", ";
6157       std::string oss3Str(oss2.str());
6158       if(oss3Str.length()<maxNbOfByteInRepr)
6159         oss2Str=oss3Str;
6160       else
6161         isFinished=false;
6162     }
6163   stream << oss2Str;
6164   if(!isFinished)
6165     stream << "... ";
6166   stream << "]";
6167 }
6168
6169 /*!
6170  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6171  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6172  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6173  *         to \a this array.
6174  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6175  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6176  *  \throw If \a this->getNumberOfComponents() != 1
6177  *  \throw If any value of \a this can't be used as a valid index for 
6178  *         [\a indArrBg, \a indArrEnd).
6179  */
6180 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6181 {
6182   checkAllocated();
6183   if(getNumberOfComponents()!=1)
6184     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6185   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6186   int nbOfTuples=getNumberOfTuples();
6187   int *pt=getPointer();
6188   for(int i=0;i<nbOfTuples;i++,pt++)
6189     {
6190       if(*pt>=0 && *pt<nbElemsIn)
6191         *pt=indArrBg[*pt];
6192       else
6193         {
6194           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6195           throw INTERP_KERNEL::Exception(oss.str().c_str());
6196         }
6197     }
6198   declareAsNew();
6199 }
6200
6201 /*!
6202  * Computes distribution of values of \a this one-dimensional array between given value
6203  * ranges (casts). This method is typically useful for entity number spliting by types,
6204  * for example. 
6205  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6206  *           check of this is be done. If not, the result is not warranted. 
6207  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6208  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6209  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6210  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6211  *         should be more than every value in \a this array.
6212  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6213  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6214  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6215  *         (same number of tuples and components), the caller is to delete 
6216  *         using decrRef() as it is no more needed.
6217  *         This array contains indices of ranges for every value of \a this array. I.e.
6218  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6219  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6220  *         this in which cast it holds.
6221  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6222  *         array, the caller is to delete using decrRef() as it is no more needed.
6223  *         This array contains ranks of values of \a this array within ranges
6224  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6225  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6226  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6227  *         for each tuple its rank inside its cast. The rank is computed as difference
6228  *         between the value and the lowest value of range.
6229  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6230  *         ranges (casts) to which at least one value of \a this array belongs.
6231  *         Or, in other words, this param contains the casts that \a this contains.
6232  *         The caller is to delete this array using decrRef() as it is no more needed.
6233  *
6234  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6235  *            the output of this method will be : 
6236  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6237  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6238  * - \a castsPresent  : [0,1]
6239  *
6240  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6241  * range #1 and its rank within this range is 2; etc.
6242  *
6243  *  \throw If \a this->getNumberOfComponents() != 1.
6244  *  \throw If \a arrEnd - arrBg < 2.
6245  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6246  */
6247 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6248                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6249 {
6250   checkAllocated();
6251   if(getNumberOfComponents()!=1)
6252     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6253   int nbOfTuples=getNumberOfTuples();
6254   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6255   if(nbOfCast<2)
6256     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6257   nbOfCast--;
6258   const int *work=getConstPointer();
6259   typedef std::reverse_iterator<const int *> rintstart;
6260   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6261   rintstart end2(arrBg);
6262   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6263   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6264   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6265   ret1->alloc(nbOfTuples,1);
6266   ret2->alloc(nbOfTuples,1);
6267   int *ret1Ptr=ret1->getPointer();
6268   int *ret2Ptr=ret2->getPointer();
6269   std::set<std::size_t> castsDetected;
6270   for(int i=0;i<nbOfTuples;i++)
6271     {
6272       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6273       std::size_t pos=std::distance(bg,res);
6274       std::size_t pos2=nbOfCast-pos;
6275       if(pos2<nbOfCast)
6276         {
6277           ret1Ptr[i]=(int)pos2;
6278           ret2Ptr[i]=work[i]-arrBg[pos2];
6279           castsDetected.insert(pos2);
6280         }
6281       else
6282         {
6283           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6284           throw INTERP_KERNEL::Exception(oss.str().c_str());
6285         }
6286     }
6287   ret3->alloc((int)castsDetected.size(),1);
6288   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6289   castArr=ret1.retn();
6290   rankInsideCast=ret2.retn();
6291   castsPresent=ret3.retn();
6292 }
6293
6294 /*!
6295  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6296  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6297  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6298  * new value in place \a indArr[ \a v ] is i.
6299  *  \param [in] indArrBg - the array holding indices within the result array to assign
6300  *         indices of values of \a this array pointing to values of \a indArrBg.
6301  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6302  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6303  *  \return DataArrayInt * - the new instance of DataArrayInt.
6304  *          The caller is to delete this result array using decrRef() as it is no more
6305  *          needed.
6306  *  \throw If \a this->getNumberOfComponents() != 1.
6307  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6308  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6309  */
6310 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6311 {
6312   checkAllocated();
6313   if(getNumberOfComponents()!=1)
6314     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6315   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6316   int nbOfTuples=getNumberOfTuples();
6317   const int *pt=getConstPointer();
6318   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6319   ret->alloc(nbOfTuples,1);
6320   ret->fillWithValue(-1);
6321   int *tmp=ret->getPointer();
6322   for(int i=0;i<nbOfTuples;i++,pt++)
6323     {
6324       if(*pt>=0 && *pt<nbElemsIn)
6325         {
6326           int pos=indArrBg[*pt];
6327           if(pos>=0 && pos<nbOfTuples)
6328             tmp[pos]=i;
6329           else
6330             {
6331               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6332               throw INTERP_KERNEL::Exception(oss.str().c_str());
6333             }
6334         }
6335       else
6336         {
6337           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6338           throw INTERP_KERNEL::Exception(oss.str().c_str());
6339         }
6340     }
6341   return ret.retn();
6342 }
6343
6344 /*!
6345  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6346  * from values of \a this array, which is supposed to contain a renumbering map in 
6347  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6348  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6349  *  \param [in] newNbOfElem - the number of tuples in the result array.
6350  *  \return DataArrayInt * - the new instance of DataArrayInt.
6351  *          The caller is to delete this result array using decrRef() as it is no more
6352  *          needed.
6353  * 
6354  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6355  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6356  */
6357 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6358 {
6359   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6360   ret->alloc(newNbOfElem,1);
6361   int nbOfOldNodes=getNumberOfTuples();
6362   const int *old2New=getConstPointer();
6363   int *pt=ret->getPointer();
6364   for(int i=0;i!=nbOfOldNodes;i++)
6365     {
6366       int newp(old2New[i]);
6367       if(newp!=-1)
6368         {
6369           if(newp>=0 && newp<newNbOfElem)
6370             pt[newp]=i;
6371           else
6372             {
6373               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6374               throw INTERP_KERNEL::Exception(oss.str().c_str());
6375             }
6376         }
6377     }
6378   return ret.retn();
6379 }
6380
6381 /*!
6382  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6383  * 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]
6384  */
6385 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6386 {
6387   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6388   ret->alloc(newNbOfElem,1);
6389   int nbOfOldNodes=getNumberOfTuples();
6390   const int *old2New=getConstPointer();
6391   int *pt=ret->getPointer();
6392   for(int i=nbOfOldNodes-1;i>=0;i--)
6393     {
6394       int newp(old2New[i]);
6395       if(newp!=-1)
6396         {
6397           if(newp>=0 && newp<newNbOfElem)
6398             pt[newp]=i;
6399           else
6400             {
6401               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6402               throw INTERP_KERNEL::Exception(oss.str().c_str());
6403             }
6404         }
6405     }
6406   return ret.retn();
6407 }
6408
6409 /*!
6410  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6411  * from values of \a this array, which is supposed to contain a renumbering map in 
6412  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6413  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6414  *  \param [in] newNbOfElem - the number of tuples in the result array.
6415  *  \return DataArrayInt * - the new instance of DataArrayInt.
6416  *          The caller is to delete this result array using decrRef() as it is no more
6417  *          needed.
6418  * 
6419  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6420  *
6421  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6422  */
6423 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6424 {
6425   checkAllocated();
6426   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6427   ret->alloc(oldNbOfElem,1);
6428   const int *new2Old=getConstPointer();
6429   int *pt=ret->getPointer();
6430   std::fill(pt,pt+oldNbOfElem,-1);
6431   int nbOfNewElems=getNumberOfTuples();
6432   for(int i=0;i<nbOfNewElems;i++)
6433     {
6434       int v(new2Old[i]);
6435       if(v>=0 && v<oldNbOfElem)
6436          pt[v]=i;
6437       else
6438         {
6439           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6440           throw INTERP_KERNEL::Exception(oss.str().c_str());
6441         }
6442     }
6443   return ret.retn();
6444 }
6445
6446 /*!
6447  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6448  * mismatch is given.
6449  * 
6450  * \param [in] other the instance to be compared with \a this
6451  * \param [out] reason In case of inequality returns the reason.
6452  * \sa DataArrayInt::isEqual
6453  */
6454 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6455 {
6456   if(!areInfoEqualsIfNotWhy(other,reason))
6457     return false;
6458   return _mem.isEqual(other._mem,0,reason);
6459 }
6460
6461 /*!
6462  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6463  * \ref MEDCouplingArrayBasicsCompare.
6464  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6465  *  \return bool - \a true if the two arrays are equal, \a false else.
6466  */
6467 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6468 {
6469   std::string tmp;
6470   return isEqualIfNotWhy(other,tmp);
6471 }
6472
6473 /*!
6474  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6475  * \ref MEDCouplingArrayBasicsCompare.
6476  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6477  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6478  */
6479 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6480 {
6481   std::string tmp;
6482   return _mem.isEqual(other._mem,0,tmp);
6483 }
6484
6485 /*!
6486  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6487  * performed on sorted value sequences.
6488  * For more info see\ref MEDCouplingArrayBasicsCompare.
6489  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6490  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6491  */
6492 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6493 {
6494   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6495   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6496   a->sort();
6497   b->sort();
6498   return a->isEqualWithoutConsideringStr(*b);
6499 }
6500
6501 /*!
6502  * This method compares content of input vector \a v and \a this.
6503  * 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.
6504  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6505  *
6506  * \param [in] v - the vector of 'flags' to be compared with \a this.
6507  *
6508  * \throw If \a this is not sorted ascendingly.
6509  * \throw If \a this has not exactly one component.
6510  * \throw If \a this is not allocated.
6511  */
6512 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6513 {
6514   checkAllocated();
6515   if(getNumberOfComponents()!=1)
6516     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6517   const int *w(begin()),*end2(end());
6518   int refVal=-std::numeric_limits<int>::max();
6519   int i=0;
6520   std::vector<bool>::const_iterator it(v.begin());
6521   for(;it!=v.end();it++,i++)
6522     {
6523       if(*it)
6524         {
6525           if(w!=end2)
6526             {
6527               if(*w++==i)
6528                 {
6529                   if(i>refVal)
6530                     refVal=i;
6531                   else
6532                     {
6533                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6534                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6535                     }
6536                 }
6537               else
6538                 return false;
6539             }
6540           else
6541             return false;
6542         }
6543     }
6544   return w==end2;
6545 }
6546
6547 /*!
6548  * Sorts values of the array.
6549  *  \param [in] asc - \a true means ascending order, \a false, descending.
6550  *  \throw If \a this is not allocated.
6551  *  \throw If \a this->getNumberOfComponents() != 1.
6552  */
6553 void DataArrayInt::sort(bool asc)
6554 {
6555   checkAllocated();
6556   if(getNumberOfComponents()!=1)
6557     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6558   _mem.sort(asc);
6559   declareAsNew();
6560 }
6561
6562 /*!
6563  * Computes for each tuple the sum of number of components values in the tuple and return it.
6564  * 
6565  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6566  *          same number of tuples as \a this array and one component.
6567  *          The caller is to delete this result array using decrRef() as it is no more
6568  *          needed.
6569  *  \throw If \a this is not allocated.
6570  */
6571 DataArrayInt *DataArrayInt::sumPerTuple() const
6572 {
6573   checkAllocated();
6574   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6575   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6576   ret->alloc(nbOfTuple,1);
6577   const int *src(getConstPointer());
6578   int *dest(ret->getPointer());
6579   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6580     *dest=std::accumulate(src,src+nbOfComp,0);
6581   return ret.retn();
6582 }
6583
6584 /*!
6585  * Reverse the array values.
6586  *  \throw If \a this->getNumberOfComponents() < 1.
6587  *  \throw If \a this is not allocated.
6588  */
6589 void DataArrayInt::reverse()
6590 {
6591   checkAllocated();
6592   _mem.reverse(getNumberOfComponents());
6593   declareAsNew();
6594 }
6595
6596 /*!
6597  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6598  * If not an exception is thrown.
6599  *  \param [in] increasing - if \a true, the array values should be increasing.
6600  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6601  *         increasing arg.
6602  *  \throw If \a this->getNumberOfComponents() != 1.
6603  *  \throw If \a this is not allocated.
6604  */
6605 void DataArrayInt::checkMonotonic(bool increasing) const
6606 {
6607   if(!isMonotonic(increasing))
6608     {
6609       if (increasing)
6610         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6611       else
6612         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6613     }
6614 }
6615
6616 /*!
6617  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6618  *  \param [in] increasing - if \a true, array values should be increasing.
6619  *  \return bool - \a true if values change in accordance with \a increasing arg.
6620  *  \throw If \a this->getNumberOfComponents() != 1.
6621  *  \throw If \a this is not allocated.
6622  */
6623 bool DataArrayInt::isMonotonic(bool increasing) const
6624 {
6625   checkAllocated();
6626   if(getNumberOfComponents()!=1)
6627     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6628   int nbOfElements=getNumberOfTuples();
6629   const int *ptr=getConstPointer();
6630   if(nbOfElements==0)
6631     return true;
6632   int ref=ptr[0];
6633   if(increasing)
6634     {
6635       for(int i=1;i<nbOfElements;i++)
6636         {
6637           if(ptr[i]>=ref)
6638             ref=ptr[i];
6639           else
6640             return false;
6641         }
6642     }
6643   else
6644     {
6645       for(int i=1;i<nbOfElements;i++)
6646         {
6647           if(ptr[i]<=ref)
6648             ref=ptr[i];
6649           else
6650             return false;
6651         }
6652     }
6653   return true;
6654 }
6655
6656 /*!
6657  * This method check that array consistently INCREASING or DECREASING in value.
6658  */
6659 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6660 {
6661   checkAllocated();
6662   if(getNumberOfComponents()!=1)
6663     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6664   int nbOfElements=getNumberOfTuples();
6665   const int *ptr=getConstPointer();
6666   if(nbOfElements==0)
6667     return true;
6668   int ref=ptr[0];
6669   if(increasing)
6670     {
6671       for(int i=1;i<nbOfElements;i++)
6672         {
6673           if(ptr[i]>ref)
6674             ref=ptr[i];
6675           else
6676             return false;
6677         }
6678     }
6679   else
6680     {
6681       for(int i=1;i<nbOfElements;i++)
6682         {
6683           if(ptr[i]<ref)
6684             ref=ptr[i];
6685           else
6686             return false;
6687         }
6688     }
6689   return true;
6690 }
6691
6692 /*!
6693  * This method check that array consistently INCREASING or DECREASING in value.
6694  */
6695 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6696 {
6697   if(!isStrictlyMonotonic(increasing))
6698     {
6699       if (increasing)
6700         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6701       else
6702         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6703     }
6704 }
6705
6706 /*!
6707  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6708  * one-dimensional arrays that must be of the same length. The result array describes
6709  * correspondence between \a this and \a other arrays, so that 
6710  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6711  * not possible because some element in \a other is not in \a this, an exception is thrown.
6712  *  \param [in] other - an array to compute permutation to.
6713  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6714  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6715  * no more needed.
6716  *  \throw If \a this->getNumberOfComponents() != 1.
6717  *  \throw If \a other->getNumberOfComponents() != 1.
6718  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6719  *  \throw If \a other includes a value which is not in \a this array.
6720  * 
6721  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6722  *
6723  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6724  */
6725 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6726 {
6727   checkAllocated();
6728   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6729     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6730   int nbTuple=getNumberOfTuples();
6731   other.checkAllocated();
6732   if(nbTuple!=other.getNumberOfTuples())
6733     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6734   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6735   ret->alloc(nbTuple,1);
6736   ret->fillWithValue(-1);
6737   const int *pt=getConstPointer();
6738   std::map<int,int> mm;
6739   for(int i=0;i<nbTuple;i++)
6740     mm[pt[i]]=i;
6741   pt=other.getConstPointer();
6742   int *retToFill=ret->getPointer();
6743   for(int i=0;i<nbTuple;i++)
6744     {
6745       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6746       if(it==mm.end())
6747         {
6748           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6749           throw INTERP_KERNEL::Exception(oss.str().c_str());
6750         }
6751       retToFill[i]=(*it).second;
6752     }
6753   return ret.retn();
6754 }
6755
6756 /*!
6757  * Sets a C array to be used as raw data of \a this. The previously set info
6758  *  of components is retained and re-sized. 
6759  * For more info see \ref MEDCouplingArraySteps1.
6760  *  \param [in] array - the C array to be used as raw data of \a this.
6761  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6762  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6763  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6764  *                     \c free(\c array ) will be called.
6765  *  \param [in] nbOfTuple - new number of tuples in \a this.
6766  *  \param [in] nbOfCompo - new number of components in \a this.
6767  */
6768 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6769 {
6770   _info_on_compo.resize(nbOfCompo);
6771   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6772   declareAsNew();
6773 }
6774
6775 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6776 {
6777   _info_on_compo.resize(nbOfCompo);
6778   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6779   declareAsNew();
6780 }
6781
6782 /*!
6783  * Returns a new DataArrayInt holding the same values as \a this array but differently
6784  * arranged in memory. If \a this array holds 2 components of 3 values:
6785  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6786  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6787  *  \warning Do not confuse this method with transpose()!
6788  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6789  *          is to delete using decrRef() as it is no more needed.
6790  *  \throw If \a this is not allocated.
6791  */
6792 DataArrayInt *DataArrayInt::fromNoInterlace() const
6793 {
6794   checkAllocated();
6795   if(_mem.isNull())
6796     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6797   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6798   DataArrayInt *ret=DataArrayInt::New();
6799   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6800   return ret;
6801 }
6802
6803 /*!
6804  * Returns a new DataArrayInt holding the same values as \a this array but differently
6805  * arranged in memory. If \a this array holds 2 components of 3 values:
6806  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6807  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6808  *  \warning Do not confuse this method with transpose()!
6809  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6810  *          is to delete using decrRef() as it is no more needed.
6811  *  \throw If \a this is not allocated.
6812  */
6813 DataArrayInt *DataArrayInt::toNoInterlace() const
6814 {
6815   checkAllocated();
6816   if(_mem.isNull())
6817     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6818   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6819   DataArrayInt *ret=DataArrayInt::New();
6820   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6821   return ret;
6822 }
6823
6824 /*!
6825  * Permutes values of \a this array as required by \a old2New array. The values are
6826  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6827  * the same as in \this one.
6828  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6829  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6830  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6831  *     giving a new position for i-th old value.
6832  */
6833 void DataArrayInt::renumberInPlace(const int *old2New)
6834 {
6835   checkAllocated();
6836   int nbTuples=getNumberOfTuples();
6837   int nbOfCompo=getNumberOfComponents();
6838   int *tmp=new int[nbTuples*nbOfCompo];
6839   const int *iptr=getConstPointer();
6840   for(int i=0;i<nbTuples;i++)
6841     {
6842       int v=old2New[i];
6843       if(v>=0 && v<nbTuples)
6844         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6845       else
6846         {
6847           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6848           throw INTERP_KERNEL::Exception(oss.str().c_str());
6849         }
6850     }
6851   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6852   delete [] tmp;
6853   declareAsNew();
6854 }
6855
6856 /*!
6857  * Permutes values of \a this array as required by \a new2Old array. The values are
6858  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6859  * the same as in \this one.
6860  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6861  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6862  *     giving a previous position of i-th new value.
6863  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6864  *          is to delete using decrRef() as it is no more needed.
6865  */
6866 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6867 {
6868   checkAllocated();
6869   int nbTuples=getNumberOfTuples();
6870   int nbOfCompo=getNumberOfComponents();
6871   int *tmp=new int[nbTuples*nbOfCompo];
6872   const int *iptr=getConstPointer();
6873   for(int i=0;i<nbTuples;i++)
6874     {
6875       int v=new2Old[i];
6876       if(v>=0 && v<nbTuples)
6877         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6878       else
6879         {
6880           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6881           throw INTERP_KERNEL::Exception(oss.str().c_str());
6882         }
6883     }
6884   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6885   delete [] tmp;
6886   declareAsNew();
6887 }
6888
6889 /*!
6890  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6891  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6892  * Number of tuples in the result array remains the same as in \this one.
6893  * If a permutation reduction is needed, renumberAndReduce() should be used.
6894  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6895  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6896  *          giving a new position for i-th old value.
6897  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6898  *          is to delete using decrRef() as it is no more needed.
6899  *  \throw If \a this is not allocated.
6900  */
6901 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6902 {
6903   checkAllocated();
6904   int nbTuples=getNumberOfTuples();
6905   int nbOfCompo=getNumberOfComponents();
6906   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6907   ret->alloc(nbTuples,nbOfCompo);
6908   ret->copyStringInfoFrom(*this);
6909   const int *iptr=getConstPointer();
6910   int *optr=ret->getPointer();
6911   for(int i=0;i<nbTuples;i++)
6912     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6913   ret->copyStringInfoFrom(*this);
6914   return ret.retn();
6915 }
6916
6917 /*!
6918  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6919  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6920  * tuples in the result array remains the same as in \this one.
6921  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6922  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6923  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6924  *     giving a previous position of i-th new value.
6925  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6926  *          is to delete using decrRef() as it is no more needed.
6927  */
6928 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6929 {
6930   checkAllocated();
6931   int nbTuples=getNumberOfTuples();
6932   int nbOfCompo=getNumberOfComponents();
6933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6934   ret->alloc(nbTuples,nbOfCompo);
6935   ret->copyStringInfoFrom(*this);
6936   const int *iptr=getConstPointer();
6937   int *optr=ret->getPointer();
6938   for(int i=0;i<nbTuples;i++)
6939     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6940   ret->copyStringInfoFrom(*this);
6941   return ret.retn();
6942 }
6943
6944 /*!
6945  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6946  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6947  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6948  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6949  * \a old2New[ i ] is negative, is missing from the result array.
6950  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6951  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6952  *     giving a new position for i-th old tuple and giving negative position for
6953  *     for i-th old tuple that should be omitted.
6954  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6955  *          is to delete using decrRef() as it is no more needed.
6956  */
6957 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6958 {
6959   checkAllocated();
6960   int nbTuples=getNumberOfTuples();
6961   int nbOfCompo=getNumberOfComponents();
6962   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6963   ret->alloc(newNbOfTuple,nbOfCompo);
6964   const int *iptr=getConstPointer();
6965   int *optr=ret->getPointer();
6966   for(int i=0;i<nbTuples;i++)
6967     {
6968       int w=old2New[i];
6969       if(w>=0)
6970         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6971     }
6972   ret->copyStringInfoFrom(*this);
6973   return ret.retn();
6974 }
6975
6976 /*!
6977  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6978  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6979  * \a new2OldBg array.
6980  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6981  * This method is equivalent to renumberAndReduce() except that convention in input is
6982  * \c new2old and \b not \c old2new.
6983  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6984  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6985  *              tuple index in \a this array to fill the i-th tuple in the new array.
6986  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6987  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6988  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6989  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6990  *          is to delete using decrRef() as it is no more needed.
6991  */
6992 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6993 {
6994   checkAllocated();
6995   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6996   int nbComp=getNumberOfComponents();
6997   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6998   ret->copyStringInfoFrom(*this);
6999   int *pt=ret->getPointer();
7000   const int *srcPt=getConstPointer();
7001   int i=0;
7002   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7003     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7004   ret->copyStringInfoFrom(*this);
7005   return ret.retn();
7006 }
7007
7008 /*!
7009  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7010  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7011  * \a new2OldBg array.
7012  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7013  * This method is equivalent to renumberAndReduce() except that convention in input is
7014  * \c new2old and \b not \c old2new.
7015  * This method is equivalent to selectByTupleId() except that it prevents coping data
7016  * from behind the end of \a this array.
7017  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7018  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7019  *              tuple index in \a this array to fill the i-th tuple in the new array.
7020  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7021  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7022  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7023  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7024  *          is to delete using decrRef() as it is no more needed.
7025  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7026  */
7027 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7028 {
7029   checkAllocated();
7030   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7031   int nbComp=getNumberOfComponents();
7032   int oldNbOfTuples=getNumberOfTuples();
7033   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7034   ret->copyStringInfoFrom(*this);
7035   int *pt=ret->getPointer();
7036   const int *srcPt=getConstPointer();
7037   int i=0;
7038   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7039     if(*w>=0 && *w<oldNbOfTuples)
7040       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7041     else
7042       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7043   ret->copyStringInfoFrom(*this);
7044   return ret.retn();
7045 }
7046
7047 /*!
7048  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7049  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7050  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7051  * command \c range( \a bg, \a end2, \a step ).
7052  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7053  * not constructed explicitly.
7054  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7055  *  \param [in] bg - index of the first tuple to copy from \a this array.
7056  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7057  *  \param [in] step - index increment to get index of the next tuple to copy.
7058  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7059  *          is to delete using decrRef() as it is no more needed.
7060  *  \sa DataArrayInt::substr.
7061  */
7062 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7063 {
7064   checkAllocated();
7065   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7066   int nbComp=getNumberOfComponents();
7067   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7068   ret->alloc(newNbOfTuples,nbComp);
7069   int *pt=ret->getPointer();
7070   const int *srcPt=getConstPointer()+bg*nbComp;
7071   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7072     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7073   ret->copyStringInfoFrom(*this);
7074   return ret.retn();
7075 }
7076
7077 /*!
7078  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7079  * of tuples specified by \a ranges parameter.
7080  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7081  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7082  *              of tuples in [\c begin,\c end) format.
7083  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7084  *          is to delete using decrRef() as it is no more needed.
7085  *  \throw If \a end < \a begin.
7086  *  \throw If \a end > \a this->getNumberOfTuples().
7087  *  \throw If \a this is not allocated.
7088  */
7089 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7090 {
7091   checkAllocated();
7092   int nbOfComp=getNumberOfComponents();
7093   int nbOfTuplesThis=getNumberOfTuples();
7094   if(ranges.empty())
7095     {
7096       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7097       ret->alloc(0,nbOfComp);
7098       ret->copyStringInfoFrom(*this);
7099       return ret.retn();
7100     }
7101   int ref=ranges.front().first;
7102   int nbOfTuples=0;
7103   bool isIncreasing=true;
7104   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7105     {
7106       if((*it).first<=(*it).second)
7107         {
7108           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7109             {
7110               nbOfTuples+=(*it).second-(*it).first;
7111               if(isIncreasing)
7112                 isIncreasing=ref<=(*it).first;
7113               ref=(*it).second;
7114             }
7115           else
7116             {
7117               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7118               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7119               throw INTERP_KERNEL::Exception(oss.str().c_str());
7120             }
7121         }
7122       else
7123         {
7124           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7125           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7126           throw INTERP_KERNEL::Exception(oss.str().c_str());
7127         }
7128     }
7129   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7130     return deepCpy();
7131   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7132   ret->alloc(nbOfTuples,nbOfComp);
7133   ret->copyStringInfoFrom(*this);
7134   const int *src=getConstPointer();
7135   int *work=ret->getPointer();
7136   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7137     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7138   return ret.retn();
7139 }
7140
7141 /*!
7142  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7143  * This map, if applied to \a this array, would make it sorted. For example, if
7144  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7145  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7146  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7147  * This method is useful for renumbering (in MED file for example). For more info
7148  * on renumbering see \ref MEDCouplingArrayRenumbering.
7149  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7150  *          array using decrRef() as it is no more needed.
7151  *  \throw If \a this is not allocated.
7152  *  \throw If \a this->getNumberOfComponents() != 1.
7153  *  \throw If there are equal values in \a this array.
7154  */
7155 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7156 {
7157   checkAllocated();
7158   if(getNumberOfComponents()!=1)
7159     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7160   int nbTuples=getNumberOfTuples();
7161   const int *pt=getConstPointer();
7162   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7163   DataArrayInt *ret=DataArrayInt::New();
7164   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7165   return ret;
7166 }
7167
7168 /*!
7169  * 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
7170  * input array \a ids2.
7171  * \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.
7172  * 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
7173  * inversely.
7174  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7175  *
7176  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7177  *          array using decrRef() as it is no more needed.
7178  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7179  * 
7180  */
7181 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7182 {
7183   if(!ids1 || !ids2)
7184     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7185   if(!ids1->isAllocated() || !ids2->isAllocated())
7186     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7187   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7188     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7189   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7190     {
7191       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 !";
7192       throw INTERP_KERNEL::Exception(oss.str().c_str());
7193     }
7194   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7195   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7196   p1->sort(true); p2->sort(true);
7197   if(!p1->isEqualWithoutConsideringStr(*p2))
7198     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7199   p1=ids1->checkAndPreparePermutation();
7200   p2=ids2->checkAndPreparePermutation();
7201   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7202   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7203   return p2.retn();
7204 }
7205
7206 /*!
7207  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7208  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7209  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7210  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7211  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7212  * The first of out arrays returns indices of elements of \a this array, grouped by their
7213  * place in the set \a B. The second out array is the index of the first one; it shows how
7214  * many elements of \a A are mapped into each element of \a B. <br>
7215  * For more info on
7216  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7217  * \b Example:
7218  * - \a this: [0,3,2,3,2,2,1,2]
7219  * - \a targetNb: 4
7220  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7221  * - \a arrI: [0,1,2,6,8]
7222  *
7223  * This result means: <br>
7224  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7225  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7226  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7227  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7228  * \a arrI[ 2+1 ]]); <br> etc.
7229  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7230  *         than the maximal value of \a A.
7231  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7232  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7233  *         this array using decrRef() as it is no more needed.
7234  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7235  *         elements of \a this. The caller is to delete this array using decrRef() as it
7236  *         is no more needed.
7237  *  \throw If \a this is not allocated.
7238  *  \throw If \a this->getNumberOfComponents() != 1.
7239  *  \throw If any value in \a this is more or equal to \a targetNb.
7240  */
7241 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7242 {
7243   checkAllocated();
7244   if(getNumberOfComponents()!=1)
7245     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7246   int nbOfTuples=getNumberOfTuples();
7247   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7248   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7249   retI->alloc(targetNb+1,1);
7250   const int *input=getConstPointer();
7251   std::vector< std::vector<int> > tmp(targetNb);
7252   for(int i=0;i<nbOfTuples;i++)
7253     {
7254       int tmp2=input[i];
7255       if(tmp2>=0 && tmp2<targetNb)
7256         tmp[tmp2].push_back(i);
7257       else
7258         {
7259           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7260           throw INTERP_KERNEL::Exception(oss.str().c_str());
7261         }
7262     }
7263   int *retIPtr=retI->getPointer();
7264   *retIPtr=0;
7265   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7266     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7267   if(nbOfTuples!=retI->getIJ(targetNb,0))
7268     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7269   ret->alloc(nbOfTuples,1);
7270   int *retPtr=ret->getPointer();
7271   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7272     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7273   arr=ret.retn();
7274   arrI=retI.retn();
7275 }
7276
7277
7278 /*!
7279  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7280  * from a zip representation of a surjective format (returned e.g. by
7281  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7282  * for example). The result array minimizes the permutation. <br>
7283  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7284  * \b Example: <br>
7285  * - \a nbOfOldTuples: 10 
7286  * - \a arr          : [0,3, 5,7,9]
7287  * - \a arrIBg       : [0,2,5]
7288  * - \a newNbOfTuples: 7
7289  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7290  *
7291  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7292  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7293  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7294  *         (indices of) equal values. Its every element (except the last one) points to
7295  *         the first element of a group of equal values.
7296  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7297  *          arrIBg is \a arrIEnd[ -1 ].
7298  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7299  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7300  *          array using decrRef() as it is no more needed.
7301  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7302  */
7303 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7304 {
7305   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7306   ret->alloc(nbOfOldTuples,1);
7307   int *pt=ret->getPointer();
7308   std::fill(pt,pt+nbOfOldTuples,-1);
7309   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7310   const int *cIPtr=arrIBg;
7311   for(int i=0;i<nbOfGrps;i++)
7312     pt[arr[cIPtr[i]]]=-(i+2);
7313   int newNb=0;
7314   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7315     {
7316       if(pt[iNode]<0)
7317         {
7318           if(pt[iNode]==-1)
7319             pt[iNode]=newNb++;
7320           else
7321             {
7322               int grpId=-(pt[iNode]+2);
7323               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7324                 {
7325                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7326                     pt[arr[j]]=newNb;
7327                   else
7328                     {
7329                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7330                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7331                     }
7332                 }
7333               newNb++;
7334             }
7335         }
7336     }
7337   newNbOfTuples=newNb;
7338   return ret.retn();
7339 }
7340
7341 /*!
7342  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7343  * which if applied to \a this array would make it sorted ascendingly.
7344  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7345  * \b Example: <br>
7346  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7347  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7348  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7349  *
7350  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7351  *          array using decrRef() as it is no more needed.
7352  *  \throw If \a this is not allocated.
7353  *  \throw If \a this->getNumberOfComponents() != 1.
7354  */
7355 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7356 {
7357   checkAllocated();
7358   if(getNumberOfComponents()!=1)
7359     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7360   int nbOfTuples=getNumberOfTuples();
7361   const int *pt=getConstPointer();
7362   std::map<int,int> m;
7363   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7364   ret->alloc(nbOfTuples,1);
7365   int *opt=ret->getPointer();
7366   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7367     {
7368       int val=*pt;
7369       std::map<int,int>::iterator it=m.find(val);
7370       if(it!=m.end())
7371         {
7372           *opt=(*it).second;
7373           (*it).second++;
7374         }
7375       else
7376         {
7377           *opt=0;
7378           m.insert(std::pair<int,int>(val,1));
7379         }
7380     }
7381   int sum=0;
7382   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7383     {
7384       int vt=(*it).second;
7385       (*it).second=sum;
7386       sum+=vt;
7387     }
7388   pt=getConstPointer();
7389   opt=ret->getPointer();
7390   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7391     *opt+=m[*pt];
7392   //
7393   return ret.retn();
7394 }
7395
7396 /*!
7397  * Checks if contents of \a this array are equal to that of an array filled with
7398  * iota(). This method is particularly useful for DataArrayInt instances that represent
7399  * a renumbering array to check the real need in renumbering. 
7400  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7401  *  \throw If \a this is not allocated.
7402  *  \throw If \a this->getNumberOfComponents() != 1.
7403  */
7404 bool DataArrayInt::isIdentity() const
7405 {
7406   checkAllocated();
7407   if(getNumberOfComponents()!=1)
7408     return false;
7409   int nbOfTuples=getNumberOfTuples();
7410   const int *pt=getConstPointer();
7411   for(int i=0;i<nbOfTuples;i++,pt++)
7412     if(*pt!=i)
7413       return false;
7414   return true;
7415 }
7416
7417 /*!
7418  * Checks if all values in \a this array are equal to \a val.
7419  *  \param [in] val - value to check equality of array values to.
7420  *  \return bool - \a true if all values are \a val.
7421  *  \throw If \a this is not allocated.
7422  *  \throw If \a this->getNumberOfComponents() != 1
7423  */
7424 bool DataArrayInt::isUniform(int val) const
7425 {
7426   checkAllocated();
7427   if(getNumberOfComponents()!=1)
7428     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7429   int nbOfTuples=getNumberOfTuples();
7430   const int *w=getConstPointer();
7431   const int *end2=w+nbOfTuples;
7432   for(;w!=end2;w++)
7433     if(*w!=val)
7434       return false;
7435   return true;
7436 }
7437
7438 /*!
7439  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7440  * array to the new one.
7441  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7442  */
7443 DataArrayDouble *DataArrayInt::convertToDblArr() const
7444 {
7445   checkAllocated();
7446   DataArrayDouble *ret=DataArrayDouble::New();
7447   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7448   std::size_t nbOfVals=getNbOfElems();
7449   const int *src=getConstPointer();
7450   double *dest=ret->getPointer();
7451   std::copy(src,src+nbOfVals,dest);
7452   ret->copyStringInfoFrom(*this);
7453   return ret;
7454 }
7455
7456 /*!
7457  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7458  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7459  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7460  * This method is a specialization of selectByTupleId2().
7461  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7462  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7463  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7464  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7465  *          is to delete using decrRef() as it is no more needed.
7466  *  \throw If \a tupleIdBg < 0.
7467  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7468     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7469  *  \sa DataArrayInt::selectByTupleId2
7470  */
7471 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7472 {
7473   checkAllocated();
7474   int nbt=getNumberOfTuples();
7475   if(tupleIdBg<0)
7476     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7477   if(tupleIdBg>nbt)
7478     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7479   int trueEnd=tupleIdEnd;
7480   if(tupleIdEnd!=-1)
7481     {
7482       if(tupleIdEnd>nbt)
7483         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7484     }
7485   else
7486     trueEnd=nbt;
7487   int nbComp=getNumberOfComponents();
7488   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7489   ret->alloc(trueEnd-tupleIdBg,nbComp);
7490   ret->copyStringInfoFrom(*this);
7491   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7492   return ret.retn();
7493 }
7494
7495 /*!
7496  * Changes the number of components within \a this array so that its raw data **does
7497  * not** change, instead splitting this data into tuples changes.
7498  *  \warning This method erases all (name and unit) component info set before!
7499  *  \param [in] newNbOfComp - number of components for \a this array to have.
7500  *  \throw If \a this is not allocated
7501  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7502  *  \throw If \a newNbOfCompo is lower than 1.
7503  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7504  *  \warning This method erases all (name and unit) component info set before!
7505  */
7506 void DataArrayInt::rearrange(int newNbOfCompo)
7507 {
7508   checkAllocated();
7509   if(newNbOfCompo<1)
7510     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7511   std::size_t nbOfElems=getNbOfElems();
7512   if(nbOfElems%newNbOfCompo!=0)
7513     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7514   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7515     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7516   _info_on_compo.clear();
7517   _info_on_compo.resize(newNbOfCompo);
7518   declareAsNew();
7519 }
7520
7521 /*!
7522  * Changes the number of components within \a this array to be equal to its number
7523  * of tuples, and inversely its number of tuples to become equal to its number of 
7524  * components. So that its raw data **does not** change, instead splitting this
7525  * data into tuples changes.
7526  *  \warning This method erases all (name and unit) component info set before!
7527  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7528  *  \throw If \a this is not allocated.
7529  *  \sa rearrange()
7530  */
7531 void DataArrayInt::transpose()
7532 {
7533   checkAllocated();
7534   int nbOfTuples=getNumberOfTuples();
7535   rearrange(nbOfTuples);
7536 }
7537
7538 /*!
7539  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7540  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7541  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7542  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7543  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7544  * components.  
7545  *  \param [in] newNbOfComp - number of components for the new array to have.
7546  *  \param [in] dftValue - value assigned to new values added to the new array.
7547  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7548  *          is to delete using decrRef() as it is no more needed.
7549  *  \throw If \a this is not allocated.
7550  */
7551 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7552 {
7553   checkAllocated();
7554   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7555   ret->alloc(getNumberOfTuples(),newNbOfComp);
7556   const int *oldc=getConstPointer();
7557   int *nc=ret->getPointer();
7558   int nbOfTuples=getNumberOfTuples();
7559   int oldNbOfComp=getNumberOfComponents();
7560   int dim=std::min(oldNbOfComp,newNbOfComp);
7561   for(int i=0;i<nbOfTuples;i++)
7562     {
7563       int j=0;
7564       for(;j<dim;j++)
7565         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7566       for(;j<newNbOfComp;j++)
7567         nc[newNbOfComp*i+j]=dftValue;
7568     }
7569   ret->setName(getName().c_str());
7570   for(int i=0;i<dim;i++)
7571     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7572   ret->setName(getName().c_str());
7573   return ret.retn();
7574 }
7575
7576 /*!
7577  * Changes number of tuples in the array. If the new number of tuples is smaller
7578  * than the current number the array is truncated, otherwise the array is extended.
7579  *  \param [in] nbOfTuples - new number of tuples. 
7580  *  \throw If \a this is not allocated.
7581  *  \throw If \a nbOfTuples is negative.
7582  */
7583 void DataArrayInt::reAlloc(int nbOfTuples)
7584 {
7585   if(nbOfTuples<0)
7586     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7587   checkAllocated();
7588   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7589   declareAsNew();
7590 }
7591
7592
7593 /*!
7594  * Returns a copy of \a this array composed of selected components.
7595  * The new DataArrayInt has the same number of tuples but includes components
7596  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7597  * can be either less, same or more than \a this->getNbOfElems().
7598  *  \param [in] compoIds - sequence of zero based indices of components to include
7599  *              into the new array.
7600  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7601  *          is to delete using decrRef() as it is no more needed.
7602  *  \throw If \a this is not allocated.
7603  *  \throw If a component index (\a i) is not valid: 
7604  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7605  *
7606  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7607  */
7608 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7609 {
7610   checkAllocated();
7611   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7612   int newNbOfCompo=(int)compoIds.size();
7613   int oldNbOfCompo=getNumberOfComponents();
7614   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7615     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7616   int nbOfTuples=getNumberOfTuples();
7617   ret->alloc(nbOfTuples,newNbOfCompo);
7618   ret->copyPartOfStringInfoFrom(*this,compoIds);
7619   const int *oldc=getConstPointer();
7620   int *nc=ret->getPointer();
7621   for(int i=0;i<nbOfTuples;i++)
7622     for(int j=0;j<newNbOfCompo;j++,nc++)
7623       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7624   return ret.retn();
7625 }
7626
7627 /*!
7628  * Appends components of another array to components of \a this one, tuple by tuple.
7629  * So that the number of tuples of \a this array remains the same and the number of 
7630  * components increases.
7631  *  \param [in] other - the DataArrayInt to append to \a this one.
7632  *  \throw If \a this is not allocated.
7633  *  \throw If \a this and \a other arrays have different number of tuples.
7634  *
7635  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7636  *
7637  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7638  */
7639 void DataArrayInt::meldWith(const DataArrayInt *other)
7640 {
7641   if(!other)
7642     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7643   checkAllocated();
7644   other->checkAllocated();
7645   int nbOfTuples=getNumberOfTuples();
7646   if(nbOfTuples!=other->getNumberOfTuples())
7647     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7648   int nbOfComp1=getNumberOfComponents();
7649   int nbOfComp2=other->getNumberOfComponents();
7650   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7651   int *w=newArr;
7652   const int *inp1=getConstPointer();
7653   const int *inp2=other->getConstPointer();
7654   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7655     {
7656       w=std::copy(inp1,inp1+nbOfComp1,w);
7657       w=std::copy(inp2,inp2+nbOfComp2,w);
7658     }
7659   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7660   std::vector<int> compIds(nbOfComp2);
7661   for(int i=0;i<nbOfComp2;i++)
7662     compIds[i]=nbOfComp1+i;
7663   copyPartOfStringInfoFrom2(compIds,*other);
7664 }
7665
7666 /*!
7667  * Copy all components in a specified order from another DataArrayInt.
7668  * The specified components become the first ones in \a this array.
7669  * Both numerical and textual data is copied. The number of tuples in \a this and
7670  * the other array can be different.
7671  *  \param [in] a - the array to copy data from.
7672  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7673  *              to be copied.
7674  *  \throw If \a a is NULL.
7675  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7676  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7677  *
7678  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7679  */
7680 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7681 {
7682   if(!a)
7683     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7684   checkAllocated();
7685   a->checkAllocated();
7686   copyPartOfStringInfoFrom2(compoIds,*a);
7687   std::size_t partOfCompoSz=compoIds.size();
7688   int nbOfCompo=getNumberOfComponents();
7689   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7690   const int *ac=a->getConstPointer();
7691   int *nc=getPointer();
7692   for(int i=0;i<nbOfTuples;i++)
7693     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7694       nc[nbOfCompo*i+compoIds[j]]=*ac;
7695 }
7696
7697 /*!
7698  * Copy all values from another DataArrayInt into specified tuples and components
7699  * of \a this array. Textual data is not copied.
7700  * The tree parameters defining set of indices of tuples and components are similar to
7701  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7702  *  \param [in] a - the array to copy values from.
7703  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7704  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7705  *              are located.
7706  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7707  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7708  *  \param [in] endComp - index of the component before which the components to assign
7709  *              to are located.
7710  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7711  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7712  *              must be equal to the number of columns to assign to, else an
7713  *              exception is thrown; if \a false, then it is only required that \a
7714  *              a->getNbOfElems() equals to number of values to assign to (this condition
7715  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7716  *              values to assign to is given by following Python expression:
7717  *              \a nbTargetValues = 
7718  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7719  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7720  *  \throw If \a a is NULL.
7721  *  \throw If \a a is not allocated.
7722  *  \throw If \a this is not allocated.
7723  *  \throw If parameters specifying tuples and components to assign to do not give a
7724  *            non-empty range of increasing indices.
7725  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7726  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7727  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7728  *
7729  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7730  */
7731 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7732 {
7733   if(!a)
7734     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7735   const char msg[]="DataArrayInt::setPartOfValues1";
7736   checkAllocated();
7737   a->checkAllocated();
7738   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7739   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7740   int nbComp=getNumberOfComponents();
7741   int nbOfTuples=getNumberOfTuples();
7742   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7743   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7744   bool assignTech=true;
7745   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7746     {
7747       if(strictCompoCompare)
7748         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7749     }
7750   else
7751     {
7752       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7753       assignTech=false;
7754     }
7755   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7756   const int *srcPt=a->getConstPointer();
7757   if(assignTech)
7758     {
7759       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7760         for(int j=0;j<newNbOfComp;j++,srcPt++)
7761           pt[j*stepComp]=*srcPt;
7762     }
7763   else
7764     {
7765       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7766         {
7767           const int *srcPt2=srcPt;
7768           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7769             pt[j*stepComp]=*srcPt2;
7770         }
7771     }
7772 }
7773
7774 /*!
7775  * Assign a given value to values at specified tuples and components of \a this array.
7776  * The tree parameters defining set of indices of tuples and components are similar to
7777  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7778  *  \param [in] a - the value to assign.
7779  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7780  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7781  *              are located.
7782  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7783  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7784  *  \param [in] endComp - index of the component before which the components to assign
7785  *              to are located.
7786  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7787  *  \throw If \a this is not allocated.
7788  *  \throw If parameters specifying tuples and components to assign to, do not give a
7789  *            non-empty range of increasing indices or indices are out of a valid range
7790  *            for \this array.
7791  *
7792  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7793  */
7794 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7795 {
7796   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7797   checkAllocated();
7798   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7799   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7800   int nbComp=getNumberOfComponents();
7801   int nbOfTuples=getNumberOfTuples();
7802   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7803   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7804   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7805   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7806     for(int j=0;j<newNbOfComp;j++)
7807       pt[j*stepComp]=a;
7808 }
7809
7810
7811 /*!
7812  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7813  * components of \a this array. Textual data is not copied.
7814  * The tuples and components to assign to are defined by C arrays of indices.
7815  * There are two *modes of usage*:
7816  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7817  *   of \a a is assigned to its own location within \a this array. 
7818  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7819  *   components of every specified tuple of \a this array. In this mode it is required
7820  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7821  * 
7822  *  \param [in] a - the array to copy values from.
7823  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7824  *              assign values of \a a to.
7825  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7826  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7827  *              \a bgTuples <= \a pi < \a endTuples.
7828  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7829  *              assign values of \a a to.
7830  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7831  *              pointer to a component index <em>(pi)</em> varies as this: 
7832  *              \a bgComp <= \a pi < \a endComp.
7833  *  \param [in] strictCompoCompare - this parameter is checked only if the
7834  *               *mode of usage* is the first; if it is \a true (default), 
7835  *               then \a a->getNumberOfComponents() must be equal 
7836  *               to the number of specified columns, else this is not required.
7837  *  \throw If \a a is NULL.
7838  *  \throw If \a a is not allocated.
7839  *  \throw If \a this is not allocated.
7840  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7841  *         out of a valid range for \a this array.
7842  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7843  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7844  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7845  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7846  *
7847  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7848  */
7849 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7850 {
7851   if(!a)
7852     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7853   const char msg[]="DataArrayInt::setPartOfValues2";
7854   checkAllocated();
7855   a->checkAllocated();
7856   int nbComp=getNumberOfComponents();
7857   int nbOfTuples=getNumberOfTuples();
7858   for(const int *z=bgComp;z!=endComp;z++)
7859     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7860   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7861   int newNbOfComp=(int)std::distance(bgComp,endComp);
7862   bool assignTech=true;
7863   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7864     {
7865       if(strictCompoCompare)
7866         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7867     }
7868   else
7869     {
7870       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7871       assignTech=false;
7872     }
7873   int *pt=getPointer();
7874   const int *srcPt=a->getConstPointer();
7875   if(assignTech)
7876     {    
7877       for(const int *w=bgTuples;w!=endTuples;w++)
7878         {
7879           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7880           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7881             {    
7882               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7883             }
7884         }
7885     }
7886   else
7887     {
7888       for(const int *w=bgTuples;w!=endTuples;w++)
7889         {
7890           const int *srcPt2=srcPt;
7891           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7892           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7893             {    
7894               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7895             }
7896         }
7897     }
7898 }
7899
7900 /*!
7901  * Assign a given value to values at specified tuples and components of \a this array.
7902  * The tuples and components to assign to are defined by C arrays of indices.
7903  *  \param [in] a - the value to assign.
7904  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7905  *              assign \a a to.
7906  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7907  *              pointer to a tuple index (\a pi) varies as this: 
7908  *              \a bgTuples <= \a pi < \a endTuples.
7909  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7910  *              assign \a a to.
7911  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7912  *              pointer to a component index (\a pi) varies as this: 
7913  *              \a bgComp <= \a pi < \a endComp.
7914  *  \throw If \a this is not allocated.
7915  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7916  *         out of a valid range for \a this array.
7917  *
7918  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7919  */
7920 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7921 {
7922   checkAllocated();
7923   int nbComp=getNumberOfComponents();
7924   int nbOfTuples=getNumberOfTuples();
7925   for(const int *z=bgComp;z!=endComp;z++)
7926     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7927   int *pt=getPointer();
7928   for(const int *w=bgTuples;w!=endTuples;w++)
7929     for(const int *z=bgComp;z!=endComp;z++)
7930       {
7931         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7932         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7933       }
7934 }
7935
7936 /*!
7937  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7938  * components of \a this array. Textual data is not copied.
7939  * The tuples to assign to are defined by a C array of indices.
7940  * The components to assign to are defined by three values similar to parameters of
7941  * the Python function \c range(\c start,\c stop,\c step).
7942  * There are two *modes of usage*:
7943  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7944  *   of \a a is assigned to its own location within \a this array. 
7945  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7946  *   components of every specified tuple of \a this array. In this mode it is required
7947  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7948  *
7949  *  \param [in] a - the array to copy values from.
7950  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7951  *              assign values of \a a to.
7952  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7953  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7954  *              \a bgTuples <= \a pi < \a endTuples.
7955  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7956  *  \param [in] endComp - index of the component before which the components to assign
7957  *              to are located.
7958  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7959  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7960  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7961  *               then \a a->getNumberOfComponents() must be equal 
7962  *               to the number of specified columns, else this is not required.
7963  *  \throw If \a a is NULL.
7964  *  \throw If \a a is not allocated.
7965  *  \throw If \a this is not allocated.
7966  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7967  *         \a this array.
7968  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7969  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7970  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7971  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7972  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7973  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7974  *  \throw If parameters specifying components to assign to, do not give a
7975  *            non-empty range of increasing indices or indices are out of a valid range
7976  *            for \this array.
7977  *
7978  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7979  */
7980 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7981 {
7982   if(!a)
7983     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7984   const char msg[]="DataArrayInt::setPartOfValues3";
7985   checkAllocated();
7986   a->checkAllocated();
7987   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7988   int nbComp=getNumberOfComponents();
7989   int nbOfTuples=getNumberOfTuples();
7990   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7991   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7992   bool assignTech=true;
7993   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7994     {
7995       if(strictCompoCompare)
7996         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7997     }
7998   else
7999     {
8000       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8001       assignTech=false;
8002     }
8003   int *pt=getPointer()+bgComp;
8004   const int *srcPt=a->getConstPointer();
8005   if(assignTech)
8006     {
8007       for(const int *w=bgTuples;w!=endTuples;w++)
8008         for(int j=0;j<newNbOfComp;j++,srcPt++)
8009           {
8010             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8011             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8012           }
8013     }
8014   else
8015     {
8016       for(const int *w=bgTuples;w!=endTuples;w++)
8017         {
8018           const int *srcPt2=srcPt;
8019           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8020             {
8021               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8022               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8023             }
8024         }
8025     }
8026 }
8027
8028 /*!
8029  * Assign a given value to values at specified tuples and components of \a this array.
8030  * The tuples to assign to are defined by a C array of indices.
8031  * The components to assign to are defined by three values similar to parameters of
8032  * the Python function \c range(\c start,\c stop,\c step).
8033  *  \param [in] a - the value to assign.
8034  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8035  *              assign \a a to.
8036  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8037  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8038  *              \a bgTuples <= \a pi < \a endTuples.
8039  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8040  *  \param [in] endComp - index of the component before which the components to assign
8041  *              to are located.
8042  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8043  *  \throw If \a this is not allocated.
8044  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8045  *         \a this array.
8046  *  \throw If parameters specifying components to assign to, do not give a
8047  *            non-empty range of increasing indices or indices are out of a valid range
8048  *            for \this array.
8049  *
8050  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8051  */
8052 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8053 {
8054   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8055   checkAllocated();
8056   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8057   int nbComp=getNumberOfComponents();
8058   int nbOfTuples=getNumberOfTuples();
8059   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8060   int *pt=getPointer()+bgComp;
8061   for(const int *w=bgTuples;w!=endTuples;w++)
8062     for(int j=0;j<newNbOfComp;j++)
8063       {
8064         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8065         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8066       }
8067 }
8068
8069 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8070 {
8071   if(!a)
8072     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8073   const char msg[]="DataArrayInt::setPartOfValues4";
8074   checkAllocated();
8075   a->checkAllocated();
8076   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8077   int newNbOfComp=(int)std::distance(bgComp,endComp);
8078   int nbComp=getNumberOfComponents();
8079   for(const int *z=bgComp;z!=endComp;z++)
8080     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8081   int nbOfTuples=getNumberOfTuples();
8082   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8083   bool assignTech=true;
8084   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8085     {
8086       if(strictCompoCompare)
8087         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8088     }
8089   else
8090     {
8091       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8092       assignTech=false;
8093     }
8094   const int *srcPt=a->getConstPointer();
8095   int *pt=getPointer()+bgTuples*nbComp;
8096   if(assignTech)
8097     {
8098       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8099         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8100           pt[*z]=*srcPt;
8101     }
8102   else
8103     {
8104       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8105         {
8106           const int *srcPt2=srcPt;
8107           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8108             pt[*z]=*srcPt2;
8109         }
8110     }
8111 }
8112
8113 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8114 {
8115   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8116   checkAllocated();
8117   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8118   int nbComp=getNumberOfComponents();
8119   for(const int *z=bgComp;z!=endComp;z++)
8120     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8121   int nbOfTuples=getNumberOfTuples();
8122   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8123   int *pt=getPointer()+bgTuples*nbComp;
8124   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8125     for(const int *z=bgComp;z!=endComp;z++)
8126       pt[*z]=a;
8127 }
8128
8129 /*!
8130  * Copy some tuples from another DataArrayInt into specified tuples
8131  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8132  * components.
8133  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8134  * All components of selected tuples are copied.
8135  *  \param [in] a - the array to copy values from.
8136  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8137  *              target tuples of \a this. \a tuplesSelec has two components, and the
8138  *              first component specifies index of the source tuple and the second
8139  *              one specifies index of the target tuple.
8140  *  \throw If \a this is not allocated.
8141  *  \throw If \a a is NULL.
8142  *  \throw If \a a is not allocated.
8143  *  \throw If \a tuplesSelec is NULL.
8144  *  \throw If \a tuplesSelec is not allocated.
8145  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8146  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8147  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8148  *         the corresponding (\a this or \a a) array.
8149  */
8150 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8151 {
8152   if(!a || !tuplesSelec)
8153     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8154   checkAllocated();
8155   a->checkAllocated();
8156   tuplesSelec->checkAllocated();
8157   int nbOfComp=getNumberOfComponents();
8158   if(nbOfComp!=a->getNumberOfComponents())
8159     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8160   if(tuplesSelec->getNumberOfComponents()!=2)
8161     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8162   int thisNt=getNumberOfTuples();
8163   int aNt=a->getNumberOfTuples();
8164   int *valsToSet=getPointer();
8165   const int *valsSrc=a->getConstPointer();
8166   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8167     {
8168       if(tuple[1]>=0 && tuple[1]<aNt)
8169         {
8170           if(tuple[0]>=0 && tuple[0]<thisNt)
8171             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8172           else
8173             {
8174               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8175               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8176               throw INTERP_KERNEL::Exception(oss.str().c_str());
8177             }
8178         }
8179       else
8180         {
8181           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8182           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8183           throw INTERP_KERNEL::Exception(oss.str().c_str());
8184         }
8185     }
8186 }
8187
8188 /*!
8189  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8190  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8191  * components.
8192  * The tuples to assign to are defined by index of the first tuple, and
8193  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8194  * The tuples to copy are defined by values of a DataArrayInt.
8195  * All components of selected tuples are copied.
8196  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8197  *              values to.
8198  *  \param [in] aBase - the array to copy values from.
8199  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8200  *  \throw If \a this is not allocated.
8201  *  \throw If \a aBase is NULL.
8202  *  \throw If \a aBase is not allocated.
8203  *  \throw If \a tuplesSelec is NULL.
8204  *  \throw If \a tuplesSelec is not allocated.
8205  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8206  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8207  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8208  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8209  *         \a aBase array.
8210  */
8211 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8212 {
8213   if(!aBase || !tuplesSelec)
8214     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8215   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8216   if(!a)
8217     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8218   checkAllocated();
8219   a->checkAllocated();
8220   tuplesSelec->checkAllocated();
8221   int nbOfComp=getNumberOfComponents();
8222   if(nbOfComp!=a->getNumberOfComponents())
8223     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8224   if(tuplesSelec->getNumberOfComponents()!=1)
8225     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8226   int thisNt=getNumberOfTuples();
8227   int aNt=a->getNumberOfTuples();
8228   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8229   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8230   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8231     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8232   const int *valsSrc=a->getConstPointer();
8233   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8234     {
8235       if(*tuple>=0 && *tuple<aNt)
8236         {
8237           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8238         }
8239       else
8240         {
8241           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8242           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8243           throw INTERP_KERNEL::Exception(oss.str().c_str());
8244         }
8245     }
8246 }
8247
8248 /*!
8249  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8250  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8251  * components.
8252  * The tuples to copy are defined by three values similar to parameters of
8253  * the Python function \c range(\c start,\c stop,\c step).
8254  * The tuples to assign to are defined by index of the first tuple, and
8255  * their number is defined by number of tuples to copy.
8256  * All components of selected tuples are copied.
8257  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8258  *              values to.
8259  *  \param [in] aBase - the array to copy values from.
8260  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8261  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8262  *              are located.
8263  *  \param [in] step - index increment to get index of the next tuple to copy.
8264  *  \throw If \a this is not allocated.
8265  *  \throw If \a aBase is NULL.
8266  *  \throw If \a aBase is not allocated.
8267  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8268  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8269  *  \throw If parameters specifying tuples to copy, do not give a
8270  *            non-empty range of increasing indices or indices are out of a valid range
8271  *            for the array \a aBase.
8272  */
8273 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8274 {
8275   if(!aBase)
8276     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8277   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8278   if(!a)
8279     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8280   checkAllocated();
8281   a->checkAllocated();
8282   int nbOfComp=getNumberOfComponents();
8283   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8284   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8285   if(nbOfComp!=a->getNumberOfComponents())
8286     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8287   int thisNt=getNumberOfTuples();
8288   int aNt=a->getNumberOfTuples();
8289   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8290   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8291     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8292   if(end2>aNt)
8293     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8294   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8295   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8296     {
8297       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8298     }
8299 }
8300
8301 /*!
8302  * Returns a value located at specified tuple and component.
8303  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8304  * parameters is checked. So this method is safe but expensive if used to go through
8305  * all values of \a this.
8306  *  \param [in] tupleId - index of tuple of interest.
8307  *  \param [in] compoId - index of component of interest.
8308  *  \return double - value located by \a tupleId and \a compoId.
8309  *  \throw If \a this is not allocated.
8310  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8311  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8312  */
8313 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8314 {
8315   checkAllocated();
8316   if(tupleId<0 || tupleId>=getNumberOfTuples())
8317     {
8318       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8319       throw INTERP_KERNEL::Exception(oss.str().c_str());
8320     }
8321   if(compoId<0 || compoId>=getNumberOfComponents())
8322     {
8323       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8324       throw INTERP_KERNEL::Exception(oss.str().c_str());
8325     }
8326   return _mem[tupleId*_info_on_compo.size()+compoId];
8327 }
8328
8329 /*!
8330  * Returns the first value of \a this. 
8331  *  \return int - the last value of \a this array.
8332  *  \throw If \a this is not allocated.
8333  *  \throw If \a this->getNumberOfComponents() != 1.
8334  *  \throw If \a this->getNumberOfTuples() < 1.
8335  */
8336 int DataArrayInt::front() const
8337 {
8338   checkAllocated();
8339   if(getNumberOfComponents()!=1)
8340     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8341   int nbOfTuples=getNumberOfTuples();
8342   if(nbOfTuples<1)
8343     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8344   return *(getConstPointer());
8345 }
8346
8347 /*!
8348  * Returns the last value of \a this. 
8349  *  \return int - the last value of \a this array.
8350  *  \throw If \a this is not allocated.
8351  *  \throw If \a this->getNumberOfComponents() != 1.
8352  *  \throw If \a this->getNumberOfTuples() < 1.
8353  */
8354 int DataArrayInt::back() const
8355 {
8356   checkAllocated();
8357   if(getNumberOfComponents()!=1)
8358     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8359   int nbOfTuples=getNumberOfTuples();
8360   if(nbOfTuples<1)
8361     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8362   return *(getConstPointer()+nbOfTuples-1);
8363 }
8364
8365 /*!
8366  * Assign pointer to one array to a pointer to another appay. Reference counter of
8367  * \a arrayToSet is incremented / decremented.
8368  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8369  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8370  */
8371 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8372 {
8373   if(newArray!=arrayToSet)
8374     {
8375       if(arrayToSet)
8376         arrayToSet->decrRef();
8377       arrayToSet=newArray;
8378       if(arrayToSet)
8379         arrayToSet->incrRef();
8380     }
8381 }
8382
8383 DataArrayIntIterator *DataArrayInt::iterator()
8384 {
8385   return new DataArrayIntIterator(this);
8386 }
8387
8388 /*!
8389  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8390  * given one.
8391  *  \param [in] val - the value to find within \a this.
8392  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8393  *          array using decrRef() as it is no more needed.
8394  *  \throw If \a this is not allocated.
8395  *  \throw If \a this->getNumberOfComponents() != 1.
8396  */
8397 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8398 {
8399   checkAllocated();
8400   if(getNumberOfComponents()!=1)
8401     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8402   const int *cptr=getConstPointer();
8403   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8404   int nbOfTuples=getNumberOfTuples();
8405   for(int i=0;i<nbOfTuples;i++,cptr++)
8406     if(*cptr==val)
8407       ret->pushBackSilent(i);
8408   return ret.retn();
8409 }
8410
8411 /*!
8412  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8413  * equal to a given one. 
8414  *  \param [in] val - the value to ignore within \a this.
8415  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8416  *          array using decrRef() as it is no more needed.
8417  *  \throw If \a this is not allocated.
8418  *  \throw If \a this->getNumberOfComponents() != 1.
8419  */
8420 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8421 {
8422   checkAllocated();
8423   if(getNumberOfComponents()!=1)
8424     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8425   const int *cptr=getConstPointer();
8426   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8427   int nbOfTuples=getNumberOfTuples();
8428   for(int i=0;i<nbOfTuples;i++,cptr++)
8429     if(*cptr!=val)
8430       ret->pushBackSilent(i);
8431   return ret.retn();
8432 }
8433
8434
8435 /*!
8436  * Assigns \a newValue to all elements holding \a oldValue within \a this
8437  * one-dimensional array.
8438  *  \param [in] oldValue - the value to replace.
8439  *  \param [in] newValue - the value to assign.
8440  *  \return int - number of replacements performed.
8441  *  \throw If \a this is not allocated.
8442  *  \throw If \a this->getNumberOfComponents() != 1.
8443  */
8444 int DataArrayInt::changeValue(int oldValue, int newValue)
8445 {
8446   checkAllocated();
8447   if(getNumberOfComponents()!=1)
8448     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8449   int *start=getPointer();
8450   int *end2=start+getNbOfElems();
8451   int ret=0;
8452   for(int *val=start;val!=end2;val++)
8453     {
8454       if(*val==oldValue)
8455         {
8456           *val=newValue;
8457           ret++;
8458         }
8459     }
8460   return ret;
8461 }
8462
8463 /*!
8464  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8465  * one of given values.
8466  *  \param [in] valsBg - an array of values to find within \a this array.
8467  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8468  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8469  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8470  *          array using decrRef() as it is no more needed.
8471  *  \throw If \a this->getNumberOfComponents() != 1.
8472  */
8473 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8474 {
8475   if(getNumberOfComponents()!=1)
8476     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8477   std::set<int> vals2(valsBg,valsEnd);
8478   const int *cptr=getConstPointer();
8479   std::vector<int> res;
8480   int nbOfTuples=getNumberOfTuples();
8481   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8482   for(int i=0;i<nbOfTuples;i++,cptr++)
8483     if(vals2.find(*cptr)!=vals2.end())
8484       ret->pushBackSilent(i);
8485   return ret.retn();
8486 }
8487
8488 /*!
8489  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8490  * equal to any of given values.
8491  *  \param [in] valsBg - an array of values to ignore within \a this array.
8492  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8493  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8494  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8495  *          array using decrRef() as it is no more needed.
8496  *  \throw If \a this->getNumberOfComponents() != 1.
8497  */
8498 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8499 {
8500   if(getNumberOfComponents()!=1)
8501     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8502   std::set<int> vals2(valsBg,valsEnd);
8503   const int *cptr=getConstPointer();
8504   std::vector<int> res;
8505   int nbOfTuples=getNumberOfTuples();
8506   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8507   for(int i=0;i<nbOfTuples;i++,cptr++)
8508     if(vals2.find(*cptr)==vals2.end())
8509       ret->pushBackSilent(i);
8510   return ret.retn();
8511 }
8512
8513 /*!
8514  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8515  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8516  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8517  * If any the tuple id is returned. If not -1 is returned.
8518  * 
8519  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8520  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8521  *
8522  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8523  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8524  */
8525 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8526 {
8527   checkAllocated();
8528   int nbOfCompo=getNumberOfComponents();
8529   if(nbOfCompo==0)
8530     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8531   if(nbOfCompo!=(int)tupl.size())
8532     {
8533       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8534       throw INTERP_KERNEL::Exception(oss.str().c_str());
8535     }
8536   const int *cptr=getConstPointer();
8537   std::size_t nbOfVals=getNbOfElems();
8538   for(const int *work=cptr;work!=cptr+nbOfVals;)
8539     {
8540       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8541       if(work!=cptr+nbOfVals)
8542         {
8543           if(std::distance(cptr,work)%nbOfCompo!=0)
8544             work++;
8545           else
8546             return std::distance(cptr,work)/nbOfCompo;
8547         }
8548     }
8549   return -1;
8550 }
8551
8552 /*!
8553  * This method searches the sequence specified in input parameter \b vals in \b this.
8554  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8555  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8556  * \sa DataArrayInt::locateTuple
8557  */
8558 int DataArrayInt::search(const std::vector<int>& vals) const
8559 {
8560   checkAllocated();
8561   int nbOfCompo=getNumberOfComponents();
8562   if(nbOfCompo!=1)
8563     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8564   const int *cptr=getConstPointer();
8565   std::size_t nbOfVals=getNbOfElems();
8566   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8567   if(loc!=cptr+nbOfVals)
8568     return std::distance(cptr,loc);
8569   return -1;
8570 }
8571
8572 /*!
8573  * This method expects to be called when number of components of this is equal to one.
8574  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8575  * If not any tuple contains \b value -1 is returned.
8576  * \sa DataArrayInt::presenceOfValue
8577  */
8578 int DataArrayInt::locateValue(int value) const
8579 {
8580   checkAllocated();
8581   if(getNumberOfComponents()!=1)
8582     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8583   const int *cptr=getConstPointer();
8584   int nbOfTuples=getNumberOfTuples();
8585   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8586   if(ret!=cptr+nbOfTuples)
8587     return std::distance(cptr,ret);
8588   return -1;
8589 }
8590
8591 /*!
8592  * This method expects to be called when number of components of this is equal to one.
8593  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8594  * If not any tuple contains one of the values contained in 'vals' false is returned.
8595  * \sa DataArrayInt::presenceOfValue
8596  */
8597 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8598 {
8599   checkAllocated();
8600   if(getNumberOfComponents()!=1)
8601     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8602   std::set<int> vals2(vals.begin(),vals.end());
8603   const int *cptr=getConstPointer();
8604   int nbOfTuples=getNumberOfTuples();
8605   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8606     if(vals2.find(*w)!=vals2.end())
8607       return std::distance(cptr,w);
8608   return -1;
8609 }
8610
8611 /*!
8612  * This method returns the number of values in \a this that are equals to input parameter \a value.
8613  * This method only works for single component array.
8614  *
8615  * \return a value in [ 0, \c this->getNumberOfTuples() )
8616  *
8617  * \throw If \a this is not allocated
8618  *
8619  */
8620 int DataArrayInt::count(int value) const
8621 {
8622   int ret=0;
8623   checkAllocated();
8624   if(getNumberOfComponents()!=1)
8625     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8626   const int *vals=begin();
8627   int nbOfTuples=getNumberOfTuples();
8628   for(int i=0;i<nbOfTuples;i++,vals++)
8629     if(*vals==value)
8630       ret++;
8631   return ret;
8632 }
8633
8634 /*!
8635  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8636  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8637  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8638  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8639  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8640  * \sa DataArrayInt::locateTuple
8641  */
8642 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8643 {
8644   return locateTuple(tupl)!=-1;
8645 }
8646
8647
8648 /*!
8649  * Returns \a true if a given value is present within \a this one-dimensional array.
8650  *  \param [in] value - the value to find within \a this array.
8651  *  \return bool - \a true in case if \a value is present within \a this array.
8652  *  \throw If \a this is not allocated.
8653  *  \throw If \a this->getNumberOfComponents() != 1.
8654  *  \sa locateValue()
8655  */
8656 bool DataArrayInt::presenceOfValue(int value) const
8657 {
8658   return locateValue(value)!=-1;
8659 }
8660
8661 /*!
8662  * This method expects to be called when number of components of this is equal to one.
8663  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8664  * If not any tuple contains one of the values contained in 'vals' false is returned.
8665  * \sa DataArrayInt::locateValue
8666  */
8667 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8668 {
8669   return locateValue(vals)!=-1;
8670 }
8671
8672 /*!
8673  * Accumulates values of each component of \a this array.
8674  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8675  *         by the caller, that is filled by this method with sum value for each
8676  *         component.
8677  *  \throw If \a this is not allocated.
8678  */
8679 void DataArrayInt::accumulate(int *res) const
8680 {
8681   checkAllocated();
8682   const int *ptr=getConstPointer();
8683   int nbTuple=getNumberOfTuples();
8684   int nbComps=getNumberOfComponents();
8685   std::fill(res,res+nbComps,0);
8686   for(int i=0;i<nbTuple;i++)
8687     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8688 }
8689
8690 int DataArrayInt::accumulate(int compId) const
8691 {
8692   checkAllocated();
8693   const int *ptr=getConstPointer();
8694   int nbTuple=getNumberOfTuples();
8695   int nbComps=getNumberOfComponents();
8696   if(compId<0 || compId>=nbComps)
8697     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8698   int ret=0;
8699   for(int i=0;i<nbTuple;i++)
8700     ret+=ptr[i*nbComps+compId];
8701   return ret;
8702 }
8703
8704 /*!
8705  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8706  * The returned array will have same number of components than \a this and number of tuples equal to
8707  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8708  *
8709  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8710  *
8711  * \param [in] bgOfIndex - begin (included) of the input index array.
8712  * \param [in] endOfIndex - end (excluded) of the input index array.
8713  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8714  * 
8715  * \throw If bgOfIndex or end is NULL.
8716  * \throw If input index array is not ascendingly sorted.
8717  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8718  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8719  */
8720 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8721 {
8722   if(!bgOfIndex || !endOfIndex)
8723     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8724   checkAllocated();
8725   int nbCompo=getNumberOfComponents();
8726   int nbOfTuples=getNumberOfTuples();
8727   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8728   if(sz<1)
8729     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8730   sz--;
8731   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8732   const int *w=bgOfIndex;
8733   if(*w<0 || *w>=nbOfTuples)
8734     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8735   const int *srcPt=begin()+(*w)*nbCompo;
8736   int *tmp=ret->getPointer();
8737   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8738     {
8739       std::fill(tmp,tmp+nbCompo,0);
8740       if(w[1]>=w[0])
8741         {
8742           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8743             {
8744               if(j>=0 && j<nbOfTuples)
8745                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8746               else
8747                 {
8748                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8749                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8750                 }
8751             }
8752         }
8753       else
8754         {
8755           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8756           throw INTERP_KERNEL::Exception(oss.str().c_str());
8757         }
8758     }
8759   ret->copyStringInfoFrom(*this);
8760   return ret.retn();
8761 }
8762
8763 /*!
8764  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8765  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8766  * offsetA2</em> and (2)
8767  * the number of component in the result array is same as that of each of given arrays.
8768  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8769  * Info on components is copied from the first of the given arrays. Number of components
8770  * in the given arrays must be the same.
8771  *  \param [in] a1 - an array to include in the result array.
8772  *  \param [in] a2 - another array to include in the result array.
8773  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8774  *  \return DataArrayInt * - the new instance of DataArrayInt.
8775  *          The caller is to delete this result array using decrRef() as it is no more
8776  *          needed.
8777  *  \throw If either \a a1 or \a a2 is NULL.
8778  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8779  */
8780 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8781 {
8782   if(!a1 || !a2)
8783     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8784   int nbOfComp=a1->getNumberOfComponents();
8785   if(nbOfComp!=a2->getNumberOfComponents())
8786     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8787   int nbOfTuple1=a1->getNumberOfTuples();
8788   int nbOfTuple2=a2->getNumberOfTuples();
8789   DataArrayInt *ret=DataArrayInt::New();
8790   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8791   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8792   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8793   ret->copyStringInfoFrom(*a1);
8794   return ret;
8795 }
8796
8797 /*!
8798  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8799  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8800  * the number of component in the result array is same as that of each of given arrays.
8801  * Info on components is copied from the first of the given arrays. Number of components
8802  * in the given arrays must be  the same.
8803  *  \param [in] arr - a sequence of arrays to include in the result array.
8804  *  \return DataArrayInt * - the new instance of DataArrayInt.
8805  *          The caller is to delete this result array using decrRef() as it is no more
8806  *          needed.
8807  *  \throw If all arrays within \a arr are NULL.
8808  *  \throw If getNumberOfComponents() of arrays within \a arr.
8809  */
8810 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8811 {
8812   std::vector<const DataArrayInt *> a;
8813   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8814     if(*it4)
8815       a.push_back(*it4);
8816   if(a.empty())
8817     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8818   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8819   int nbOfComp=(*it)->getNumberOfComponents();
8820   int nbt=(*it++)->getNumberOfTuples();
8821   for(int i=1;it!=a.end();it++,i++)
8822     {
8823       if((*it)->getNumberOfComponents()!=nbOfComp)
8824         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8825       nbt+=(*it)->getNumberOfTuples();
8826     }
8827   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8828   ret->alloc(nbt,nbOfComp);
8829   int *pt=ret->getPointer();
8830   for(it=a.begin();it!=a.end();it++)
8831     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8832   ret->copyStringInfoFrom(*(a[0]));
8833   return ret.retn();
8834 }
8835
8836 /*!
8837  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8838  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8839  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8840  * 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.
8841  * 
8842  * \return DataArrayInt * - a new object to be managed by the caller.
8843  */
8844 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8845 {
8846   int retSz=1;
8847   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8848     {
8849       if(*it4)
8850         {
8851           (*it4)->checkAllocated();
8852           if((*it4)->getNumberOfComponents()!=1)
8853             {
8854               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8855               throw INTERP_KERNEL::Exception(oss.str().c_str());
8856             }
8857           int nbTupl=(*it4)->getNumberOfTuples();
8858           if(nbTupl<1)
8859             {
8860               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8861               throw INTERP_KERNEL::Exception(oss.str().c_str());
8862             }
8863           if((*it4)->front()!=0)
8864             {
8865               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8866               throw INTERP_KERNEL::Exception(oss.str().c_str());
8867             }
8868           retSz+=nbTupl-1;
8869         }
8870       else
8871         {
8872           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8873           throw INTERP_KERNEL::Exception(oss.str().c_str());
8874         }
8875     }
8876   if(arrs.empty())
8877     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8878   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8879   ret->alloc(retSz,1);
8880   int *pt=ret->getPointer(); *pt++=0;
8881   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8882     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8883   ret->copyStringInfoFrom(*(arrs[0]));
8884   return ret.retn();
8885 }
8886
8887 /*!
8888  * Returns the maximal value and its location within \a this one-dimensional array.
8889  *  \param [out] tupleId - index of the tuple holding the maximal value.
8890  *  \return int - the maximal value among all values of \a this array.
8891  *  \throw If \a this->getNumberOfComponents() != 1
8892  *  \throw If \a this->getNumberOfTuples() < 1
8893  */
8894 int DataArrayInt::getMaxValue(int& tupleId) const
8895 {
8896   checkAllocated();
8897   if(getNumberOfComponents()!=1)
8898     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8899   int nbOfTuples=getNumberOfTuples();
8900   if(nbOfTuples<=0)
8901     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8902   const int *vals=getConstPointer();
8903   const int *loc=std::max_element(vals,vals+nbOfTuples);
8904   tupleId=(int)std::distance(vals,loc);
8905   return *loc;
8906 }
8907
8908 /*!
8909  * Returns the maximal value within \a this array that is allowed to have more than
8910  *  one component.
8911  *  \return int - the maximal value among all values of \a this array.
8912  *  \throw If \a this is not allocated.
8913  */
8914 int DataArrayInt::getMaxValueInArray() const
8915 {
8916   checkAllocated();
8917   const int *loc=std::max_element(begin(),end());
8918   return *loc;
8919 }
8920
8921 /*!
8922  * Returns the minimal value and its location within \a this one-dimensional array.
8923  *  \param [out] tupleId - index of the tuple holding the minimal value.
8924  *  \return int - the minimal value among all values of \a this array.
8925  *  \throw If \a this->getNumberOfComponents() != 1
8926  *  \throw If \a this->getNumberOfTuples() < 1
8927  */
8928 int DataArrayInt::getMinValue(int& tupleId) const
8929 {
8930   checkAllocated();
8931   if(getNumberOfComponents()!=1)
8932     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8933   int nbOfTuples=getNumberOfTuples();
8934   if(nbOfTuples<=0)
8935     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8936   const int *vals=getConstPointer();
8937   const int *loc=std::min_element(vals,vals+nbOfTuples);
8938   tupleId=(int)std::distance(vals,loc);
8939   return *loc;
8940 }
8941
8942 /*!
8943  * Returns the minimal value within \a this array that is allowed to have more than
8944  *  one component.
8945  *  \return int - the minimal value among all values of \a this array.
8946  *  \throw If \a this is not allocated.
8947  */
8948 int DataArrayInt::getMinValueInArray() const
8949 {
8950   checkAllocated();
8951   const int *loc=std::min_element(begin(),end());
8952   return *loc;
8953 }
8954
8955 /*!
8956  * Converts every value of \a this array to its absolute value.
8957  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
8958  * should be called instead.
8959  *
8960  * \throw If \a this is not allocated.
8961  * \sa DataArrayInt::computeAbs
8962  */
8963 void DataArrayInt::abs()
8964 {
8965   checkAllocated();
8966   int *ptr(getPointer());
8967   std::size_t nbOfElems(getNbOfElems());
8968   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8969   declareAsNew();
8970 }
8971
8972 /*!
8973  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
8974  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
8975  *
8976  * \return DataArrayInt * - the new instance of DataArrayInt containing the
8977  *         same number of tuples and component as \a this array.
8978  *         The caller is to delete this result array using decrRef() as it is no more
8979  *         needed.
8980  * \throw If \a this is not allocated.
8981  * \sa DataArrayInt::abs
8982  */
8983 DataArrayInt *DataArrayInt::computeAbs() const
8984 {
8985   checkAllocated();
8986   DataArrayInt *newArr(DataArrayInt::New());
8987   int nbOfTuples(getNumberOfTuples());
8988   int nbOfComp(getNumberOfComponents());
8989   newArr->alloc(nbOfTuples,nbOfComp);
8990   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
8991   newArr->copyStringInfoFrom(*this);
8992   return newArr;
8993 }
8994
8995 /*!
8996  * Apply a liner function to a given component of \a this array, so that
8997  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8998  *  \param [in] a - the first coefficient of the function.
8999  *  \param [in] b - the second coefficient of the function.
9000  *  \param [in] compoId - the index of component to modify.
9001  *  \throw If \a this is not allocated.
9002  */
9003 void DataArrayInt::applyLin(int a, int b, int compoId)
9004 {
9005   checkAllocated();
9006   int *ptr=getPointer()+compoId;
9007   int nbOfComp=getNumberOfComponents();
9008   int nbOfTuple=getNumberOfTuples();
9009   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9010     *ptr=a*(*ptr)+b;
9011   declareAsNew();
9012 }
9013
9014 /*!
9015  * Apply a liner function to all elements of \a this array, so that
9016  * an element _x_ becomes \f$ a * x + b \f$.
9017  *  \param [in] a - the first coefficient of the function.
9018  *  \param [in] b - the second coefficient of the function.
9019  *  \throw If \a this is not allocated.
9020  */
9021 void DataArrayInt::applyLin(int a, int b)
9022 {
9023   checkAllocated();
9024   int *ptr=getPointer();
9025   std::size_t nbOfElems=getNbOfElems();
9026   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9027     *ptr=a*(*ptr)+b;
9028   declareAsNew();
9029 }
9030
9031 /*!
9032  * Returns a full copy of \a this array except that sign of all elements is reversed.
9033  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9034  *          same number of tuples and component as \a this array.
9035  *          The caller is to delete this result array using decrRef() as it is no more
9036  *          needed.
9037  *  \throw If \a this is not allocated.
9038  */
9039 DataArrayInt *DataArrayInt::negate() const
9040 {
9041   checkAllocated();
9042   DataArrayInt *newArr=DataArrayInt::New();
9043   int nbOfTuples=getNumberOfTuples();
9044   int nbOfComp=getNumberOfComponents();
9045   newArr->alloc(nbOfTuples,nbOfComp);
9046   const int *cptr=getConstPointer();
9047   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9048   newArr->copyStringInfoFrom(*this);
9049   return newArr;
9050 }
9051
9052 /*!
9053  * Modify all elements of \a this array, so that
9054  * an element _x_ becomes \f$ numerator / x \f$.
9055  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9056  *           array, all elements processed before detection of the zero element remain
9057  *           modified.
9058  *  \param [in] numerator - the numerator used to modify array elements.
9059  *  \throw If \a this is not allocated.
9060  *  \throw If there is an element equal to 0 in \a this array.
9061  */
9062 void DataArrayInt::applyInv(int numerator)
9063 {
9064   checkAllocated();
9065   int *ptr=getPointer();
9066   std::size_t nbOfElems=getNbOfElems();
9067   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9068     {
9069       if(*ptr!=0)
9070         {
9071           *ptr=numerator/(*ptr);
9072         }
9073       else
9074         {
9075           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9076           oss << " !";
9077           throw INTERP_KERNEL::Exception(oss.str().c_str());
9078         }
9079     }
9080   declareAsNew();
9081 }
9082
9083 /*!
9084  * Modify all elements of \a this array, so that
9085  * an element _x_ becomes \f$ x / val \f$.
9086  *  \param [in] val - the denominator used to modify array elements.
9087  *  \throw If \a this is not allocated.
9088  *  \throw If \a val == 0.
9089  */
9090 void DataArrayInt::applyDivideBy(int val)
9091 {
9092   if(val==0)
9093     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9094   checkAllocated();
9095   int *ptr=getPointer();
9096   std::size_t nbOfElems=getNbOfElems();
9097   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9098   declareAsNew();
9099 }
9100
9101 /*!
9102  * Modify all elements of \a this array, so that
9103  * an element _x_ becomes  <em> x % val </em>.
9104  *  \param [in] val - the divisor used to modify array elements.
9105  *  \throw If \a this is not allocated.
9106  *  \throw If \a val <= 0.
9107  */
9108 void DataArrayInt::applyModulus(int val)
9109 {
9110   if(val<=0)
9111     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9112   checkAllocated();
9113   int *ptr=getPointer();
9114   std::size_t nbOfElems=getNbOfElems();
9115   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9116   declareAsNew();
9117 }
9118
9119 /*!
9120  * This method works only on data array with one component.
9121  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9122  * this[*id] in [\b vmin,\b vmax)
9123  * 
9124  * \param [in] vmin begin of range. This value is included in range (included).
9125  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9126  * \return a newly allocated data array that the caller should deal with.
9127  *
9128  * \sa DataArrayInt::getIdsNotInRange
9129  */
9130 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9131 {
9132   checkAllocated();
9133   if(getNumberOfComponents()!=1)
9134     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9135   const int *cptr(begin());
9136   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9137   int nbOfTuples(getNumberOfTuples());
9138   for(int i=0;i<nbOfTuples;i++,cptr++)
9139     if(*cptr>=vmin && *cptr<vmax)
9140       ret->pushBackSilent(i);
9141   return ret.retn();
9142 }
9143
9144 /*!
9145  * This method works only on data array with one component.
9146  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9147  * this[*id] \b not in [\b vmin,\b vmax)
9148  * 
9149  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9150  * \param [in] vmax end of range. This value is included in range (included).
9151  * \return a newly allocated data array that the caller should deal with.
9152  * 
9153  * \sa DataArrayInt::getIdsInRange
9154  */
9155 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9156 {
9157   checkAllocated();
9158   if(getNumberOfComponents()!=1)
9159     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9160   const int *cptr(getConstPointer());
9161   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9162   int nbOfTuples(getNumberOfTuples());
9163   for(int i=0;i<nbOfTuples;i++,cptr++)
9164     if(*cptr<vmin || *cptr>=vmax)
9165       ret->pushBackSilent(i);
9166   return ret.retn();
9167 }
9168
9169 /*!
9170  * This method works only on data array with one component.
9171  * 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.
9172  * 
9173  * \param [in] vmin begin of range. This value is included in range (included).
9174  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9175  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9176 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9177 {
9178   checkAllocated();
9179   if(getNumberOfComponents()!=1)
9180     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9181   int nbOfTuples=getNumberOfTuples();
9182   bool ret=true;
9183   const int *cptr=getConstPointer();
9184   for(int i=0;i<nbOfTuples;i++,cptr++)
9185     {
9186       if(*cptr>=vmin && *cptr<vmax)
9187         { ret=ret && *cptr==i; }
9188       else
9189         {
9190           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9191           throw INTERP_KERNEL::Exception(oss.str().c_str());
9192         }
9193     }
9194   return ret;
9195 }
9196
9197 /*!
9198  * Modify all elements of \a this array, so that
9199  * an element _x_ becomes <em> val % x </em>.
9200  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9201  *           array, all elements processed before detection of the zero element remain
9202  *           modified.
9203  *  \param [in] val - the divident used to modify array elements.
9204  *  \throw If \a this is not allocated.
9205  *  \throw If there is an element equal to or less than 0 in \a this array.
9206  */
9207 void DataArrayInt::applyRModulus(int val)
9208 {
9209   checkAllocated();
9210   int *ptr=getPointer();
9211   std::size_t nbOfElems=getNbOfElems();
9212   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9213     {
9214       if(*ptr>0)
9215         {
9216           *ptr=val%(*ptr);
9217         }
9218       else
9219         {
9220           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9221           oss << " !";
9222           throw INTERP_KERNEL::Exception(oss.str().c_str());
9223         }
9224     }
9225   declareAsNew();
9226 }
9227
9228 /*!
9229  * Modify all elements of \a this array, so that
9230  * an element _x_ becomes <em> val ^ x </em>.
9231  *  \param [in] val - the value used to apply pow on all array elements.
9232  *  \throw If \a this is not allocated.
9233  *  \throw If \a val < 0.
9234  */
9235 void DataArrayInt::applyPow(int val)
9236 {
9237   checkAllocated();
9238   if(val<0)
9239     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9240   int *ptr=getPointer();
9241   std::size_t nbOfElems=getNbOfElems();
9242   if(val==0)
9243     {
9244       std::fill(ptr,ptr+nbOfElems,1);
9245       return ;
9246     }
9247   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9248     {
9249       int tmp=1;
9250       for(int j=0;j<val;j++)
9251         tmp*=*ptr;
9252       *ptr=tmp;
9253     }
9254   declareAsNew();
9255 }
9256
9257 /*!
9258  * Modify all elements of \a this array, so that
9259  * an element _x_ becomes \f$ val ^ x \f$.
9260  *  \param [in] val - the value used to apply pow on all array elements.
9261  *  \throw If \a this is not allocated.
9262  *  \throw If there is an element < 0 in \a this array.
9263  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9264  *           array, all elements processed before detection of the zero element remain
9265  *           modified.
9266  */
9267 void DataArrayInt::applyRPow(int val)
9268 {
9269   checkAllocated();
9270   int *ptr=getPointer();
9271   std::size_t nbOfElems=getNbOfElems();
9272   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9273     {
9274       if(*ptr>=0)
9275         {
9276           int tmp=1;
9277           for(int j=0;j<*ptr;j++)
9278             tmp*=val;
9279           *ptr=tmp;
9280         }
9281       else
9282         {
9283           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9284           oss << " !";
9285           throw INTERP_KERNEL::Exception(oss.str().c_str());
9286         }
9287     }
9288   declareAsNew();
9289 }
9290
9291 /*!
9292  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9293  * of components in the result array is a sum of the number of components of given arrays
9294  * and (2) the number of tuples in the result array is same as that of each of given
9295  * arrays. In other words the i-th tuple of result array includes all components of
9296  * i-th tuples of all given arrays.
9297  * Number of tuples in the given arrays must be the same.
9298  *  \param [in] a1 - an array to include in the result array.
9299  *  \param [in] a2 - another array to include in the result array.
9300  *  \return DataArrayInt * - the new instance of DataArrayInt.
9301  *          The caller is to delete this result array using decrRef() as it is no more
9302  *          needed.
9303  *  \throw If both \a a1 and \a a2 are NULL.
9304  *  \throw If any given array is not allocated.
9305  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9306  */
9307 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9308 {
9309   std::vector<const DataArrayInt *> arr(2);
9310   arr[0]=a1; arr[1]=a2;
9311   return Meld(arr);
9312 }
9313
9314 /*!
9315  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9316  * of components in the result array is a sum of the number of components of given arrays
9317  * and (2) the number of tuples in the result array is same as that of each of given
9318  * arrays. In other words the i-th tuple of result array includes all components of
9319  * i-th tuples of all given arrays.
9320  * Number of tuples in the given arrays must be  the same.
9321  *  \param [in] arr - a sequence of arrays to include in the result array.
9322  *  \return DataArrayInt * - the new instance of DataArrayInt.
9323  *          The caller is to delete this result array using decrRef() as it is no more
9324  *          needed.
9325  *  \throw If all arrays within \a arr are NULL.
9326  *  \throw If any given array is not allocated.
9327  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9328  */
9329 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9330 {
9331   std::vector<const DataArrayInt *> a;
9332   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9333     if(*it4)
9334       a.push_back(*it4);
9335   if(a.empty())
9336     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9337   std::vector<const DataArrayInt *>::const_iterator it;
9338   for(it=a.begin();it!=a.end();it++)
9339     (*it)->checkAllocated();
9340   it=a.begin();
9341   int nbOfTuples=(*it)->getNumberOfTuples();
9342   std::vector<int> nbc(a.size());
9343   std::vector<const int *> pts(a.size());
9344   nbc[0]=(*it)->getNumberOfComponents();
9345   pts[0]=(*it++)->getConstPointer();
9346   for(int i=1;it!=a.end();it++,i++)
9347     {
9348       if(nbOfTuples!=(*it)->getNumberOfTuples())
9349         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9350       nbc[i]=(*it)->getNumberOfComponents();
9351       pts[i]=(*it)->getConstPointer();
9352     }
9353   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9354   DataArrayInt *ret=DataArrayInt::New();
9355   ret->alloc(nbOfTuples,totalNbOfComp);
9356   int *retPtr=ret->getPointer();
9357   for(int i=0;i<nbOfTuples;i++)
9358     for(int j=0;j<(int)a.size();j++)
9359       {
9360         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9361         pts[j]+=nbc[j];
9362       }
9363   int k=0;
9364   for(int i=0;i<(int)a.size();i++)
9365     for(int j=0;j<nbc[i];j++,k++)
9366       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9367   return ret;
9368 }
9369
9370 /*!
9371  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9372  * The i-th item of the result array is an ID of a set of elements belonging to a
9373  * unique set of groups, which the i-th element is a part of. This set of elements
9374  * belonging to a unique set of groups is called \a family, so the result array contains
9375  * IDs of families each element belongs to.
9376  *
9377  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9378  * then there are 3 families:
9379  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9380  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9381  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9382  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9383  * stands for the element #3 which is in none of groups.
9384  *
9385  *  \param [in] groups - sequence of groups of element IDs.
9386  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9387  *         in \a groups.
9388  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9389  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9390  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9391  *         delete this array using decrRef() as it is no more needed.
9392  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9393  */
9394 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9395 {
9396   std::vector<const DataArrayInt *> groups2;
9397   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9398     if(*it4)
9399       groups2.push_back(*it4);
9400   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9401   ret->alloc(newNb,1);
9402   int *retPtr=ret->getPointer();
9403   std::fill(retPtr,retPtr+newNb,0);
9404   int fid=1;
9405   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9406     {
9407       const int *ptr=(*iter)->getConstPointer();
9408       std::size_t nbOfElem=(*iter)->getNbOfElems();
9409       int sfid=fid;
9410       for(int j=0;j<sfid;j++)
9411         {
9412           bool found=false;
9413           for(std::size_t i=0;i<nbOfElem;i++)
9414             {
9415               if(ptr[i]>=0 && ptr[i]<newNb)
9416                 {
9417                   if(retPtr[ptr[i]]==j)
9418                     {
9419                       retPtr[ptr[i]]=fid;
9420                       found=true;
9421                     }
9422                 }
9423               else
9424                 {
9425                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9426                   oss << ") !";
9427                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9428                 }
9429             }
9430           if(found)
9431             fid++;
9432         }
9433     }
9434   fidsOfGroups.clear();
9435   fidsOfGroups.resize(groups2.size());
9436   int grId=0;
9437   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9438     {
9439       std::set<int> tmp;
9440       const int *ptr=(*iter)->getConstPointer();
9441       std::size_t nbOfElem=(*iter)->getNbOfElems();
9442       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9443         tmp.insert(retPtr[*p]);
9444       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9445     }
9446   return ret.retn();
9447 }
9448
9449 /*!
9450  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9451  * arrays. The result array does not contain any duplicates and its values
9452  * are sorted in ascending order.
9453  *  \param [in] arr - sequence of DataArrayInt's to unite.
9454  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9455  *         array using decrRef() as it is no more needed.
9456  *  \throw If any \a arr[i] is not allocated.
9457  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9458  */
9459 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9460 {
9461   std::vector<const DataArrayInt *> a;
9462   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9463     if(*it4)
9464       a.push_back(*it4);
9465   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9466     {
9467       (*it)->checkAllocated();
9468       if((*it)->getNumberOfComponents()!=1)
9469         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9470     }
9471   //
9472   std::set<int> r;
9473   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9474     {
9475       const int *pt=(*it)->getConstPointer();
9476       int nbOfTuples=(*it)->getNumberOfTuples();
9477       r.insert(pt,pt+nbOfTuples);
9478     }
9479   DataArrayInt *ret=DataArrayInt::New();
9480   ret->alloc((int)r.size(),1);
9481   std::copy(r.begin(),r.end(),ret->getPointer());
9482   return ret;
9483 }
9484
9485 /*!
9486  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9487  * arrays. The result array does not contain any duplicates and its values
9488  * are sorted in ascending order.
9489  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9490  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9491  *         array using decrRef() as it is no more needed.
9492  *  \throw If any \a arr[i] is not allocated.
9493  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9494  */
9495 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9496 {
9497   std::vector<const DataArrayInt *> a;
9498   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9499     if(*it4)
9500       a.push_back(*it4);
9501   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9502     {
9503       (*it)->checkAllocated();
9504       if((*it)->getNumberOfComponents()!=1)
9505         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9506     }
9507   //
9508   std::set<int> r;
9509   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9510     {
9511       const int *pt=(*it)->getConstPointer();
9512       int nbOfTuples=(*it)->getNumberOfTuples();
9513       std::set<int> s1(pt,pt+nbOfTuples);
9514       if(it!=a.begin())
9515         {
9516           std::set<int> r2;
9517           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9518           r=r2;
9519         }
9520       else
9521         r=s1;
9522     }
9523   DataArrayInt *ret=DataArrayInt::New();
9524   ret->alloc((int)r.size(),1);
9525   std::copy(r.begin(),r.end(),ret->getPointer());
9526   return ret;
9527 }
9528
9529 /*!
9530  * Returns a new DataArrayInt which contains a complement of elements of \a this
9531  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9532  * \a nbOfElement) not present in \a this array.
9533  *  \param [in] nbOfElement - maximal size of the result array.
9534  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9535  *         array using decrRef() as it is no more needed.
9536  *  \throw If \a this is not allocated.
9537  *  \throw If \a this->getNumberOfComponents() != 1.
9538  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9539  *         nbOfElement ).
9540  */
9541 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9542 {
9543    checkAllocated();
9544    if(getNumberOfComponents()!=1)
9545      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9546    std::vector<bool> tmp(nbOfElement);
9547    const int *pt=getConstPointer();
9548    int nbOfTuples=getNumberOfTuples();
9549    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9550      if(*w>=0 && *w<nbOfElement)
9551        tmp[*w]=true;
9552      else
9553        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9554    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9555    DataArrayInt *ret=DataArrayInt::New();
9556    ret->alloc(nbOfRetVal,1);
9557    int j=0;
9558    int *retPtr=ret->getPointer();
9559    for(int i=0;i<nbOfElement;i++)
9560      if(!tmp[i])
9561        retPtr[j++]=i;
9562    return ret;
9563 }
9564
9565 /*!
9566  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9567  * from an \a other one-dimensional array.
9568  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9569  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9570  *         caller is to delete this array using decrRef() as it is no more needed.
9571  *  \throw If \a other is NULL.
9572  *  \throw If \a other is not allocated.
9573  *  \throw If \a other->getNumberOfComponents() != 1.
9574  *  \throw If \a this is not allocated.
9575  *  \throw If \a this->getNumberOfComponents() != 1.
9576  *  \sa DataArrayInt::buildSubstractionOptimized()
9577  */
9578 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9579 {
9580   if(!other)
9581     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9582   checkAllocated();
9583   other->checkAllocated();
9584   if(getNumberOfComponents()!=1)
9585      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9586   if(other->getNumberOfComponents()!=1)
9587      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9588   const int *pt=getConstPointer();
9589   int nbOfTuples=getNumberOfTuples();
9590   std::set<int> s1(pt,pt+nbOfTuples);
9591   pt=other->getConstPointer();
9592   nbOfTuples=other->getNumberOfTuples();
9593   std::set<int> s2(pt,pt+nbOfTuples);
9594   std::vector<int> r;
9595   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9596   DataArrayInt *ret=DataArrayInt::New();
9597   ret->alloc((int)r.size(),1);
9598   std::copy(r.begin(),r.end(),ret->getPointer());
9599   return ret;
9600 }
9601
9602 /*!
9603  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9604  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9605  * 
9606  * \param [in] other an array with one component and expected to be sorted ascendingly.
9607  * \ret list of ids in \a this but not in \a other.
9608  * \sa DataArrayInt::buildSubstraction
9609  */
9610 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9611 {
9612   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9613   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9614   checkAllocated(); other->checkAllocated();
9615   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9616   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9617   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9618   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9619   for(;work1!=pt1End;work1++)
9620     {
9621       if(work2!=pt2End && *work1==*work2)
9622         work2++;
9623       else
9624         ret->pushBackSilent(*work1);
9625     }
9626   return ret.retn();
9627 }
9628
9629
9630 /*!
9631  * Returns a new DataArrayInt which contains all elements of \a this and a given
9632  * one-dimensional arrays. The result array does not contain any duplicates
9633  * and its values are sorted in ascending order.
9634  *  \param [in] other - an array to unite with \a this one.
9635  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9636  *         array using decrRef() as it is no more needed.
9637  *  \throw If \a this or \a other is not allocated.
9638  *  \throw If \a this->getNumberOfComponents() != 1.
9639  *  \throw If \a other->getNumberOfComponents() != 1.
9640  */
9641 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9642 {
9643   std::vector<const DataArrayInt *>arrs(2);
9644   arrs[0]=this; arrs[1]=other;
9645   return BuildUnion(arrs);
9646 }
9647
9648
9649 /*!
9650  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9651  * one-dimensional arrays. The result array does not contain any duplicates
9652  * and its values are sorted in ascending order.
9653  *  \param [in] other - an array to intersect with \a this one.
9654  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9655  *         array using decrRef() as it is no more needed.
9656  *  \throw If \a this or \a other is not allocated.
9657  *  \throw If \a this->getNumberOfComponents() != 1.
9658  *  \throw If \a other->getNumberOfComponents() != 1.
9659  */
9660 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9661 {
9662   std::vector<const DataArrayInt *>arrs(2);
9663   arrs[0]=this; arrs[1]=other;
9664   return BuildIntersection(arrs);
9665 }
9666
9667 /*!
9668  * This method can be applied on allocated with one component DataArrayInt instance.
9669  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9670  * 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]
9671  * 
9672  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9673  * \throw if \a this is not allocated or if \a this has not exactly one component.
9674  */
9675 DataArrayInt *DataArrayInt::buildUnique() const
9676 {
9677   checkAllocated();
9678   if(getNumberOfComponents()!=1)
9679      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9680   int nbOfTuples=getNumberOfTuples();
9681   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9682   int *data=tmp->getPointer();
9683   int *last=std::unique(data,data+nbOfTuples);
9684   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9685   ret->alloc(std::distance(data,last),1);
9686   std::copy(data,last,ret->getPointer());
9687   return ret.retn();
9688 }
9689
9690 /*!
9691  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9692  * "index" array. Such "index" array is returned for example by 
9693  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9694  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9695  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9696  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9697  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9698  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9699  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9700  *          The caller is to delete this array using decrRef() as it is no more needed. 
9701  *  \throw If \a this is not allocated.
9702  *  \throw If \a this->getNumberOfComponents() != 1.
9703  *  \throw If \a this->getNumberOfTuples() < 2.
9704  *
9705  *  \b Example: <br> 
9706  *         - this contains [1,3,6,7,7,9,15]
9707  *         - result array contains [2,3,1,0,2,6],
9708  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9709  *
9710  * \sa DataArrayInt::computeOffsets2
9711  */
9712 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9713 {
9714   checkAllocated();
9715   if(getNumberOfComponents()!=1)
9716      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9717   int nbOfTuples=getNumberOfTuples();
9718   if(nbOfTuples<2)
9719     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9720   const int *ptr=getConstPointer();
9721   DataArrayInt *ret=DataArrayInt::New();
9722   ret->alloc(nbOfTuples-1,1);
9723   int *out=ret->getPointer();
9724   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9725   return ret;
9726 }
9727
9728 /*!
9729  * Modifies \a this one-dimensional array so that value of each element \a x
9730  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9731  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9732  * and components remains the same.<br>
9733  * This method is useful for allToAllV in MPI with contiguous policy. This method
9734  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9735  * this one.
9736  *  \throw If \a this is not allocated.
9737  *  \throw If \a this->getNumberOfComponents() != 1.
9738  *
9739  *  \b Example: <br>
9740  *          - Before \a this contains [3,5,1,2,0,8]
9741  *          - After \a this contains  [0,3,8,9,11,11]<br>
9742  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9743  *          array is retained and thus there is no space to store the last element.
9744  */
9745 void DataArrayInt::computeOffsets()
9746 {
9747   checkAllocated();
9748   if(getNumberOfComponents()!=1)
9749      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9750   int nbOfTuples=getNumberOfTuples();
9751   if(nbOfTuples==0)
9752     return ;
9753   int *work=getPointer();
9754   int tmp=work[0];
9755   work[0]=0;
9756   for(int i=1;i<nbOfTuples;i++)
9757     {
9758       int tmp2=work[i];
9759       work[i]=work[i-1]+tmp;
9760       tmp=tmp2;
9761     }
9762   declareAsNew();
9763 }
9764
9765
9766 /*!
9767  * Modifies \a this one-dimensional array so that value of each element \a x
9768  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9769  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9770  * components remains the same and number of tuples is inceamented by one.<br>
9771  * This method is useful for allToAllV in MPI with contiguous policy. This method
9772  * differs from computeOffsets() in that the number of tuples is changed by this one.
9773  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9774  *  \throw If \a this is not allocated.
9775  *  \throw If \a this->getNumberOfComponents() != 1.
9776  *
9777  *  \b Example: <br>
9778  *          - Before \a this contains [3,5,1,2,0,8]
9779  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9780  * \sa DataArrayInt::deltaShiftIndex
9781  */
9782 void DataArrayInt::computeOffsets2()
9783 {
9784   checkAllocated();
9785   if(getNumberOfComponents()!=1)
9786     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9787   int nbOfTuples=getNumberOfTuples();
9788   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9789   if(nbOfTuples==0)
9790     return ;
9791   const int *work=getConstPointer();
9792   ret[0]=0;
9793   for(int i=0;i<nbOfTuples;i++)
9794     ret[i+1]=work[i]+ret[i];
9795   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9796   declareAsNew();
9797 }
9798
9799 /*!
9800  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9801  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9802  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9803  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9804  * filling completely one of the ranges in \a this.
9805  *
9806  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9807  * \param [out] rangeIdsFetched the range ids fetched
9808  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9809  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9810  *
9811  * \sa DataArrayInt::computeOffsets2
9812  *
9813  *  \b Example: <br>
9814  *          - \a this : [0,3,7,9,15,18]
9815  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9816  *          - \a rangeIdsFetched result array: [0,2,4]
9817  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9818  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9819  * <br>
9820  */
9821 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9822 {
9823   if(!listOfIds)
9824     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9825   listOfIds->checkAllocated(); checkAllocated();
9826   if(listOfIds->getNumberOfComponents()!=1)
9827     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9828   if(getNumberOfComponents()!=1)
9829     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9830   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9831   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9832   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9833   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9834   while(tupPtr!=tupEnd && offPtr!=offEnd)
9835     {
9836       if(*tupPtr==*offPtr)
9837         {
9838           int i=offPtr[0];
9839           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9840           if(i==offPtr[1])
9841             {
9842               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9843               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9844               offPtr++;
9845             }
9846         }
9847       else
9848         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9849     }
9850   rangeIdsFetched=ret0.retn();
9851   idsInInputListThatFetch=ret1.retn();
9852 }
9853
9854 /*!
9855  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9856  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9857  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9858  * beginning within the "iota" array. And \a this is a one-dimensional array
9859  * considered as a selector of groups described by \a offsets to include into the result array.
9860  *  \throw If \a offsets is NULL.
9861  *  \throw If \a offsets is not allocated.
9862  *  \throw If \a offsets->getNumberOfComponents() != 1.
9863  *  \throw If \a offsets is not monotonically increasing.
9864  *  \throw If \a this is not allocated.
9865  *  \throw If \a this->getNumberOfComponents() != 1.
9866  *  \throw If any element of \a this is not a valid index for \a offsets array.
9867  *
9868  *  \b Example: <br>
9869  *          - \a this: [0,2,3]
9870  *          - \a offsets: [0,3,6,10,14,20]
9871  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9872  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9873  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9874  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9875  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9876  */
9877 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
9878 {
9879   if(!offsets)
9880     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9881   checkAllocated();
9882   if(getNumberOfComponents()!=1)
9883      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9884   offsets->checkAllocated();
9885   if(offsets->getNumberOfComponents()!=1)
9886      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9887   int othNbTuples=offsets->getNumberOfTuples()-1;
9888   int nbOfTuples=getNumberOfTuples();
9889   int retNbOftuples=0;
9890   const int *work=getConstPointer();
9891   const int *offPtr=offsets->getConstPointer();
9892   for(int i=0;i<nbOfTuples;i++)
9893     {
9894       int val=work[i];
9895       if(val>=0 && val<othNbTuples)
9896         {
9897           int delta=offPtr[val+1]-offPtr[val];
9898           if(delta>=0)
9899             retNbOftuples+=delta;
9900           else
9901             {
9902               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9903               throw INTERP_KERNEL::Exception(oss.str().c_str());
9904             }
9905         }
9906       else
9907         {
9908           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9909           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9910           throw INTERP_KERNEL::Exception(oss.str().c_str());
9911         }
9912     }
9913   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9914   ret->alloc(retNbOftuples,1);
9915   int *retPtr=ret->getPointer();
9916   for(int i=0;i<nbOfTuples;i++)
9917     {
9918       int val=work[i];
9919       int start=offPtr[val];
9920       int off=offPtr[val+1]-start;
9921       for(int j=0;j<off;j++,retPtr++)
9922         *retPtr=start+j;
9923     }
9924   return ret.retn();
9925 }
9926
9927 /*!
9928  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9929  * scaled array (monotonically increasing).
9930 from that of \a this and \a
9931  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9932  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9933  * beginning within the "iota" array. And \a this is a one-dimensional array
9934  * considered as a selector of groups described by \a offsets to include into the result array.
9935  *  \throw If \a  is NULL.
9936  *  \throw If \a this is not allocated.
9937  *  \throw If \a this->getNumberOfComponents() != 1.
9938  *  \throw If \a this->getNumberOfTuples() == 0.
9939  *  \throw If \a this is not monotonically increasing.
9940  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
9941  *
9942  *  \b Example: <br>
9943  *          - \a bg , \a stop and \a step : (0,5,2)
9944  *          - \a this: [0,3,6,10,14,20]
9945  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9946  */
9947 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
9948 {
9949   if(!isAllocated())
9950     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9951   if(getNumberOfComponents()!=1)
9952     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9953   int nbOfTuples(getNumberOfTuples());
9954   if(nbOfTuples==0)
9955     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9956   const int *ids(begin());
9957   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9958   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9959     {
9960       if(pos>=0 && pos<nbOfTuples-1)
9961         {
9962           int delta(ids[pos+1]-ids[pos]);
9963           sz+=delta;
9964           if(delta<0)
9965             {
9966               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9967               throw INTERP_KERNEL::Exception(oss.str().c_str());
9968             }          
9969         }
9970       else
9971         {
9972           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9973           throw INTERP_KERNEL::Exception(oss.str().c_str());
9974         }
9975     }
9976   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9977   int *retPtr(ret->getPointer());
9978   pos=bg;
9979   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9980     {
9981       int delta(ids[pos+1]-ids[pos]);
9982       for(int j=0;j<delta;j++,retPtr++)
9983         *retPtr=pos;
9984     }
9985   return ret.retn();
9986 }
9987
9988 /*!
9989  * 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.
9990  * 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
9991  * in tuple **i** of returned DataArrayInt.
9992  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9993  *
9994  * 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)]
9995  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9996  * 
9997  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9998  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9999  * \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
10000  *        is thrown if no ranges in \a ranges contains value in \a this.
10001  * 
10002  * \sa DataArrayInt::findIdInRangeForEachTuple
10003  */
10004 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10005 {
10006   if(!ranges)
10007     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10008   if(ranges->getNumberOfComponents()!=2)
10009     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10010   checkAllocated();
10011   if(getNumberOfComponents()!=1)
10012     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10013   int nbTuples=getNumberOfTuples();
10014   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10015   int nbOfRanges=ranges->getNumberOfTuples();
10016   const int *rangesPtr=ranges->getConstPointer();
10017   int *retPtr=ret->getPointer();
10018   const int *inPtr=getConstPointer();
10019   for(int i=0;i<nbTuples;i++,retPtr++)
10020     {
10021       int val=inPtr[i];
10022       bool found=false;
10023       for(int j=0;j<nbOfRanges && !found;j++)
10024         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10025           { *retPtr=j; found=true; }
10026       if(found)
10027         continue;
10028       else
10029         {
10030           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10031           throw INTERP_KERNEL::Exception(oss.str().c_str());
10032         }
10033     }
10034   return ret.retn();
10035 }
10036
10037 /*!
10038  * 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.
10039  * 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
10040  * in tuple **i** of returned DataArrayInt.
10041  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10042  *
10043  * 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)]
10044  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10045  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10046  * 
10047  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10048  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10049  * \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
10050  *        is thrown if no ranges in \a ranges contains value in \a this.
10051  * \sa DataArrayInt::findRangeIdForEachTuple
10052  */
10053 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10054 {
10055   if(!ranges)
10056     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10057   if(ranges->getNumberOfComponents()!=2)
10058     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10059   checkAllocated();
10060   if(getNumberOfComponents()!=1)
10061     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10062   int nbTuples=getNumberOfTuples();
10063   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10064   int nbOfRanges=ranges->getNumberOfTuples();
10065   const int *rangesPtr=ranges->getConstPointer();
10066   int *retPtr=ret->getPointer();
10067   const int *inPtr=getConstPointer();
10068   for(int i=0;i<nbTuples;i++,retPtr++)
10069     {
10070       int val=inPtr[i];
10071       bool found=false;
10072       for(int j=0;j<nbOfRanges && !found;j++)
10073         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10074           { *retPtr=val-rangesPtr[2*j]; found=true; }
10075       if(found)
10076         continue;
10077       else
10078         {
10079           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10080           throw INTERP_KERNEL::Exception(oss.str().c_str());
10081         }
10082     }
10083   return ret.retn();
10084 }
10085
10086 /*!
10087  * 
10088  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10089  *             \a nbTimes  should be at least equal to 1.
10090  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10091  * \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.
10092  */
10093 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10094 {
10095   checkAllocated();
10096   if(getNumberOfComponents()!=1)
10097     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10098   if(nbTimes<1)
10099     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10100   int nbTuples=getNumberOfTuples();
10101   const int *inPtr=getConstPointer();
10102   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10103   int *retPtr=ret->getPointer();
10104   for(int i=0;i<nbTuples;i++,inPtr++)
10105     {
10106       int val=*inPtr;
10107       for(int j=0;j<nbTimes;j++,retPtr++)
10108         *retPtr=val;
10109     }
10110   ret->copyStringInfoFrom(*this);
10111   return ret.retn();
10112 }
10113
10114 /*!
10115  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10116  * But the number of components can be different from one.
10117  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10118  */
10119 DataArrayInt *DataArrayInt::getDifferentValues() const
10120 {
10121   checkAllocated();
10122   std::set<int> ret;
10123   ret.insert(begin(),end());
10124   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10125   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10126   return ret2.retn();
10127 }
10128
10129 /*!
10130  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10131  * them it tells which tuple id have this id.
10132  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10133  * This method returns two arrays having same size.
10134  * 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.
10135  * 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]]
10136  */
10137 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10138 {
10139   checkAllocated();
10140   if(getNumberOfComponents()!=1)
10141     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10142   int id=0;
10143   std::map<int,int> m,m2,m3;
10144   for(const int *w=begin();w!=end();w++)
10145     m[*w]++;
10146   differentIds.resize(m.size());
10147   std::vector<DataArrayInt *> ret(m.size());
10148   std::vector<int *> retPtr(m.size());
10149   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10150     {
10151       m2[(*it).first]=id;
10152       ret[id]=DataArrayInt::New();
10153       ret[id]->alloc((*it).second,1);
10154       retPtr[id]=ret[id]->getPointer();
10155       differentIds[id]=(*it).first;
10156     }
10157   id=0;
10158   for(const int *w=begin();w!=end();w++,id++)
10159     {
10160       retPtr[m2[*w]][m3[*w]++]=id;
10161     }
10162   return ret;
10163 }
10164
10165 /*!
10166  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10167  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10168  *
10169  * \param [in] nbOfSlices - number of slices expected.
10170  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10171  * 
10172  * \sa DataArray::GetSlice
10173  * \throw If \a this is not allocated or not with exactly one component.
10174  * \throw If an element in \a this if < 0.
10175  */
10176 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10177 {
10178   if(!isAllocated() || getNumberOfComponents()!=1)
10179     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10180   if(nbOfSlices<=0)
10181     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10182   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10183   int sumPerSlc(sum/nbOfSlices),pos(0);
10184   const int *w(begin());
10185   std::vector< std::pair<int,int> > ret(nbOfSlices);
10186   for(int i=0;i<nbOfSlices;i++)
10187     {
10188       std::pair<int,int> p(pos,-1);
10189       int locSum(0);
10190       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10191       if(i!=nbOfSlices-1)
10192         p.second=pos;
10193       else
10194         p.second=nbOfTuples;
10195       ret[i]=p;
10196     }
10197   return ret;
10198 }
10199
10200 /*!
10201  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10202  * valid cases.
10203  * 1.  The arrays have same number of tuples and components. Then each value of
10204  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10205  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10206  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10207  *   component. Then
10208  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10209  * 3.  The arrays have same number of components and one array, say _a2_, has one
10210  *   tuple. Then
10211  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10212  *
10213  * Info on components is copied either from the first array (in the first case) or from
10214  * the array with maximal number of elements (getNbOfElems()).
10215  *  \param [in] a1 - an array to sum up.
10216  *  \param [in] a2 - another array to sum up.
10217  *  \return DataArrayInt * - the new instance of DataArrayInt.
10218  *          The caller is to delete this result array using decrRef() as it is no more
10219  *          needed.
10220  *  \throw If either \a a1 or \a a2 is NULL.
10221  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10222  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10223  *         none of them has number of tuples or components equal to 1.
10224  */
10225 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10226 {
10227   if(!a1 || !a2)
10228     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10229   int nbOfTuple=a1->getNumberOfTuples();
10230   int nbOfTuple2=a2->getNumberOfTuples();
10231   int nbOfComp=a1->getNumberOfComponents();
10232   int nbOfComp2=a2->getNumberOfComponents();
10233   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10234   if(nbOfTuple==nbOfTuple2)
10235     {
10236       if(nbOfComp==nbOfComp2)
10237         {
10238           ret=DataArrayInt::New();
10239           ret->alloc(nbOfTuple,nbOfComp);
10240           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10241           ret->copyStringInfoFrom(*a1);
10242         }
10243       else
10244         {
10245           int nbOfCompMin,nbOfCompMax;
10246           const DataArrayInt *aMin, *aMax;
10247           if(nbOfComp>nbOfComp2)
10248             {
10249               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10250               aMin=a2; aMax=a1;
10251             }
10252           else
10253             {
10254               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10255               aMin=a1; aMax=a2;
10256             }
10257           if(nbOfCompMin==1)
10258             {
10259               ret=DataArrayInt::New();
10260               ret->alloc(nbOfTuple,nbOfCompMax);
10261               const int *aMinPtr=aMin->getConstPointer();
10262               const int *aMaxPtr=aMax->getConstPointer();
10263               int *res=ret->getPointer();
10264               for(int i=0;i<nbOfTuple;i++)
10265                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10266               ret->copyStringInfoFrom(*aMax);
10267             }
10268           else
10269             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10270         }
10271     }
10272   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10273     {
10274       if(nbOfComp==nbOfComp2)
10275         {
10276           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10277           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10278           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10279           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10280           ret=DataArrayInt::New();
10281           ret->alloc(nbOfTupleMax,nbOfComp);
10282           int *res=ret->getPointer();
10283           for(int i=0;i<nbOfTupleMax;i++)
10284             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10285           ret->copyStringInfoFrom(*aMax);
10286         }
10287       else
10288         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10289     }
10290   else
10291     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10292   return ret.retn();
10293 }
10294
10295 /*!
10296  * Adds values of another DataArrayInt to values of \a this one. There are 3
10297  * valid cases.
10298  * 1.  The arrays have same number of tuples and components. Then each value of
10299  *   \a other array is added to the corresponding value of \a this array, i.e.:
10300  *   _a_ [ i, j ] += _other_ [ i, j ].
10301  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10302  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10303  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10304  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10305  *
10306  *  \param [in] other - an array to add to \a this one.
10307  *  \throw If \a other is NULL.
10308  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10309  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10310  *         \a other has number of both tuples and components not equal to 1.
10311  */
10312 void DataArrayInt::addEqual(const DataArrayInt *other)
10313 {
10314   if(!other)
10315     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10316   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10317   checkAllocated(); other->checkAllocated();
10318   int nbOfTuple=getNumberOfTuples();
10319   int nbOfTuple2=other->getNumberOfTuples();
10320   int nbOfComp=getNumberOfComponents();
10321   int nbOfComp2=other->getNumberOfComponents();
10322   if(nbOfTuple==nbOfTuple2)
10323     {
10324       if(nbOfComp==nbOfComp2)
10325         {
10326           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10327         }
10328       else if(nbOfComp2==1)
10329         {
10330           int *ptr=getPointer();
10331           const int *ptrc=other->getConstPointer();
10332           for(int i=0;i<nbOfTuple;i++)
10333             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10334         }
10335       else
10336         throw INTERP_KERNEL::Exception(msg);
10337     }
10338   else if(nbOfTuple2==1)
10339     {
10340       if(nbOfComp2==nbOfComp)
10341         {
10342           int *ptr=getPointer();
10343           const int *ptrc=other->getConstPointer();
10344           for(int i=0;i<nbOfTuple;i++)
10345             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10346         }
10347       else
10348         throw INTERP_KERNEL::Exception(msg);
10349     }
10350   else
10351     throw INTERP_KERNEL::Exception(msg);
10352   declareAsNew();
10353 }
10354
10355 /*!
10356  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10357  * valid cases.
10358  * 1.  The arrays have same number of tuples and components. Then each value of
10359  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10360  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10361  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10362  *   component. Then
10363  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10364  * 3.  The arrays have same number of components and one array, say _a2_, has one
10365  *   tuple. Then
10366  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10367  *
10368  * Info on components is copied either from the first array (in the first case) or from
10369  * the array with maximal number of elements (getNbOfElems()).
10370  *  \param [in] a1 - an array to subtract from.
10371  *  \param [in] a2 - an array to subtract.
10372  *  \return DataArrayInt * - the new instance of DataArrayInt.
10373  *          The caller is to delete this result array using decrRef() as it is no more
10374  *          needed.
10375  *  \throw If either \a a1 or \a a2 is NULL.
10376  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10377  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10378  *         none of them has number of tuples or components equal to 1.
10379  */
10380 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10381 {
10382   if(!a1 || !a2)
10383     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10384   int nbOfTuple1=a1->getNumberOfTuples();
10385   int nbOfTuple2=a2->getNumberOfTuples();
10386   int nbOfComp1=a1->getNumberOfComponents();
10387   int nbOfComp2=a2->getNumberOfComponents();
10388   if(nbOfTuple2==nbOfTuple1)
10389     {
10390       if(nbOfComp1==nbOfComp2)
10391         {
10392           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10393           ret->alloc(nbOfTuple2,nbOfComp1);
10394           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10395           ret->copyStringInfoFrom(*a1);
10396           return ret.retn();
10397         }
10398       else if(nbOfComp2==1)
10399         {
10400           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10401           ret->alloc(nbOfTuple1,nbOfComp1);
10402           const int *a2Ptr=a2->getConstPointer();
10403           const int *a1Ptr=a1->getConstPointer();
10404           int *res=ret->getPointer();
10405           for(int i=0;i<nbOfTuple1;i++)
10406             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10407           ret->copyStringInfoFrom(*a1);
10408           return ret.retn();
10409         }
10410       else
10411         {
10412           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10413           return 0;
10414         }
10415     }
10416   else if(nbOfTuple2==1)
10417     {
10418       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10419       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10420       ret->alloc(nbOfTuple1,nbOfComp1);
10421       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10422       int *pt=ret->getPointer();
10423       for(int i=0;i<nbOfTuple1;i++)
10424         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10425       ret->copyStringInfoFrom(*a1);
10426       return ret.retn();
10427     }
10428   else
10429     {
10430       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10431       return 0;
10432     }
10433 }
10434
10435 /*!
10436  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10437  * valid cases.
10438  * 1.  The arrays have same number of tuples and components. Then each value of
10439  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10440  *   _a_ [ i, j ] -= _other_ [ i, j ].
10441  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10442  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10443  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10444  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10445  *
10446  *  \param [in] other - an array to subtract from \a this one.
10447  *  \throw If \a other is NULL.
10448  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10449  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10450  *         \a other has number of both tuples and components not equal to 1.
10451  */
10452 void DataArrayInt::substractEqual(const DataArrayInt *other)
10453 {
10454   if(!other)
10455     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10456   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10457   checkAllocated(); other->checkAllocated();
10458   int nbOfTuple=getNumberOfTuples();
10459   int nbOfTuple2=other->getNumberOfTuples();
10460   int nbOfComp=getNumberOfComponents();
10461   int nbOfComp2=other->getNumberOfComponents();
10462   if(nbOfTuple==nbOfTuple2)
10463     {
10464       if(nbOfComp==nbOfComp2)
10465         {
10466           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10467         }
10468       else if(nbOfComp2==1)
10469         {
10470           int *ptr=getPointer();
10471           const int *ptrc=other->getConstPointer();
10472           for(int i=0;i<nbOfTuple;i++)
10473             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10474         }
10475       else
10476         throw INTERP_KERNEL::Exception(msg);
10477     }
10478   else if(nbOfTuple2==1)
10479     {
10480       int *ptr=getPointer();
10481       const int *ptrc=other->getConstPointer();
10482       for(int i=0;i<nbOfTuple;i++)
10483         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10484     }
10485   else
10486     throw INTERP_KERNEL::Exception(msg);
10487   declareAsNew();
10488 }
10489
10490 /*!
10491  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10492  * valid cases.
10493  * 1.  The arrays have same number of tuples and components. Then each value of
10494  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10495  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10496  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10497  *   component. Then
10498  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10499  * 3.  The arrays have same number of components and one array, say _a2_, has one
10500  *   tuple. Then
10501  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10502  *
10503  * Info on components is copied either from the first array (in the first case) or from
10504  * the array with maximal number of elements (getNbOfElems()).
10505  *  \param [in] a1 - a factor array.
10506  *  \param [in] a2 - another factor array.
10507  *  \return DataArrayInt * - the new instance of DataArrayInt.
10508  *          The caller is to delete this result array using decrRef() as it is no more
10509  *          needed.
10510  *  \throw If either \a a1 or \a a2 is NULL.
10511  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10512  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10513  *         none of them has number of tuples or components equal to 1.
10514  */
10515 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10516 {
10517   if(!a1 || !a2)
10518     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10519   int nbOfTuple=a1->getNumberOfTuples();
10520   int nbOfTuple2=a2->getNumberOfTuples();
10521   int nbOfComp=a1->getNumberOfComponents();
10522   int nbOfComp2=a2->getNumberOfComponents();
10523   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10524   if(nbOfTuple==nbOfTuple2)
10525     {
10526       if(nbOfComp==nbOfComp2)
10527         {
10528           ret=DataArrayInt::New();
10529           ret->alloc(nbOfTuple,nbOfComp);
10530           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10531           ret->copyStringInfoFrom(*a1);
10532         }
10533       else
10534         {
10535           int nbOfCompMin,nbOfCompMax;
10536           const DataArrayInt *aMin, *aMax;
10537           if(nbOfComp>nbOfComp2)
10538             {
10539               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10540               aMin=a2; aMax=a1;
10541             }
10542           else
10543             {
10544               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10545               aMin=a1; aMax=a2;
10546             }
10547           if(nbOfCompMin==1)
10548             {
10549               ret=DataArrayInt::New();
10550               ret->alloc(nbOfTuple,nbOfCompMax);
10551               const int *aMinPtr=aMin->getConstPointer();
10552               const int *aMaxPtr=aMax->getConstPointer();
10553               int *res=ret->getPointer();
10554               for(int i=0;i<nbOfTuple;i++)
10555                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10556               ret->copyStringInfoFrom(*aMax);
10557             }
10558           else
10559             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10560         }
10561     }
10562   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10563     {
10564       if(nbOfComp==nbOfComp2)
10565         {
10566           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10567           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10568           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10569           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10570           ret=DataArrayInt::New();
10571           ret->alloc(nbOfTupleMax,nbOfComp);
10572           int *res=ret->getPointer();
10573           for(int i=0;i<nbOfTupleMax;i++)
10574             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10575           ret->copyStringInfoFrom(*aMax);
10576         }
10577       else
10578         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10579     }
10580   else
10581     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10582   return ret.retn();
10583 }
10584
10585
10586 /*!
10587  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10588  * valid cases.
10589  * 1.  The arrays have same number of tuples and components. Then each value of
10590  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10591  *   _a_ [ i, j ] *= _other_ [ i, j ].
10592  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10593  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10594  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10595  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10596  *
10597  *  \param [in] other - an array to multiply to \a this one.
10598  *  \throw If \a other is NULL.
10599  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10600  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10601  *         \a other has number of both tuples and components not equal to 1.
10602  */
10603 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10604 {
10605   if(!other)
10606     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10607   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10608   checkAllocated(); other->checkAllocated();
10609   int nbOfTuple=getNumberOfTuples();
10610   int nbOfTuple2=other->getNumberOfTuples();
10611   int nbOfComp=getNumberOfComponents();
10612   int nbOfComp2=other->getNumberOfComponents();
10613   if(nbOfTuple==nbOfTuple2)
10614     {
10615       if(nbOfComp==nbOfComp2)
10616         {
10617           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10618         }
10619       else if(nbOfComp2==1)
10620         {
10621           int *ptr=getPointer();
10622           const int *ptrc=other->getConstPointer();
10623           for(int i=0;i<nbOfTuple;i++)
10624             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10625         }
10626       else
10627         throw INTERP_KERNEL::Exception(msg);
10628     }
10629   else if(nbOfTuple2==1)
10630     {
10631       if(nbOfComp2==nbOfComp)
10632         {
10633           int *ptr=getPointer();
10634           const int *ptrc=other->getConstPointer();
10635           for(int i=0;i<nbOfTuple;i++)
10636             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10637         }
10638       else
10639         throw INTERP_KERNEL::Exception(msg);
10640     }
10641   else
10642     throw INTERP_KERNEL::Exception(msg);
10643   declareAsNew();
10644 }
10645
10646
10647 /*!
10648  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10649  * valid cases.
10650  * 1.  The arrays have same number of tuples and components. Then each value of
10651  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10652  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10653  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10654  *   component. Then
10655  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10656  * 3.  The arrays have same number of components and one array, say _a2_, has one
10657  *   tuple. Then
10658  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10659  *
10660  * Info on components is copied either from the first array (in the first case) or from
10661  * the array with maximal number of elements (getNbOfElems()).
10662  *  \warning No check of division by zero is performed!
10663  *  \param [in] a1 - a numerator array.
10664  *  \param [in] a2 - a denominator array.
10665  *  \return DataArrayInt * - the new instance of DataArrayInt.
10666  *          The caller is to delete this result array using decrRef() as it is no more
10667  *          needed.
10668  *  \throw If either \a a1 or \a a2 is NULL.
10669  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10670  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10671  *         none of them has number of tuples or components equal to 1.
10672  */
10673 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10674 {
10675   if(!a1 || !a2)
10676     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10677   int nbOfTuple1=a1->getNumberOfTuples();
10678   int nbOfTuple2=a2->getNumberOfTuples();
10679   int nbOfComp1=a1->getNumberOfComponents();
10680   int nbOfComp2=a2->getNumberOfComponents();
10681   if(nbOfTuple2==nbOfTuple1)
10682     {
10683       if(nbOfComp1==nbOfComp2)
10684         {
10685           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10686           ret->alloc(nbOfTuple2,nbOfComp1);
10687           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10688           ret->copyStringInfoFrom(*a1);
10689           return ret.retn();
10690         }
10691       else if(nbOfComp2==1)
10692         {
10693           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10694           ret->alloc(nbOfTuple1,nbOfComp1);
10695           const int *a2Ptr=a2->getConstPointer();
10696           const int *a1Ptr=a1->getConstPointer();
10697           int *res=ret->getPointer();
10698           for(int i=0;i<nbOfTuple1;i++)
10699             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10700           ret->copyStringInfoFrom(*a1);
10701           return ret.retn();
10702         }
10703       else
10704         {
10705           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10706           return 0;
10707         }
10708     }
10709   else if(nbOfTuple2==1)
10710     {
10711       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10712       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10713       ret->alloc(nbOfTuple1,nbOfComp1);
10714       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10715       int *pt=ret->getPointer();
10716       for(int i=0;i<nbOfTuple1;i++)
10717         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10718       ret->copyStringInfoFrom(*a1);
10719       return ret.retn();
10720     }
10721   else
10722     {
10723       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10724       return 0;
10725     }
10726 }
10727
10728 /*!
10729  * Divide values of \a this array by values of another DataArrayInt. There are 3
10730  * valid cases.
10731  * 1.  The arrays have same number of tuples and components. Then each value of
10732  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10733  *   _a_ [ i, j ] /= _other_ [ i, j ].
10734  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10735  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10736  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10737  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10738  *
10739  *  \warning No check of division by zero is performed!
10740  *  \param [in] other - an array to divide \a this one by.
10741  *  \throw If \a other is NULL.
10742  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10743  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10744  *         \a other has number of both tuples and components not equal to 1.
10745  */
10746 void DataArrayInt::divideEqual(const DataArrayInt *other)
10747 {
10748   if(!other)
10749     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10750   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10751   checkAllocated(); other->checkAllocated();
10752   int nbOfTuple=getNumberOfTuples();
10753   int nbOfTuple2=other->getNumberOfTuples();
10754   int nbOfComp=getNumberOfComponents();
10755   int nbOfComp2=other->getNumberOfComponents();
10756   if(nbOfTuple==nbOfTuple2)
10757     {
10758       if(nbOfComp==nbOfComp2)
10759         {
10760           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10761         }
10762       else if(nbOfComp2==1)
10763         {
10764           int *ptr=getPointer();
10765           const int *ptrc=other->getConstPointer();
10766           for(int i=0;i<nbOfTuple;i++)
10767             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10768         }
10769       else
10770         throw INTERP_KERNEL::Exception(msg);
10771     }
10772   else if(nbOfTuple2==1)
10773     {
10774       if(nbOfComp2==nbOfComp)
10775         {
10776           int *ptr=getPointer();
10777           const int *ptrc=other->getConstPointer();
10778           for(int i=0;i<nbOfTuple;i++)
10779             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10780         }
10781       else
10782         throw INTERP_KERNEL::Exception(msg);
10783     }
10784   else
10785     throw INTERP_KERNEL::Exception(msg);
10786   declareAsNew();
10787 }
10788
10789
10790 /*!
10791  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10792  * valid cases.
10793  * 1.  The arrays have same number of tuples and components. Then each value of
10794  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10795  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10796  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10797  *   component. Then
10798  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10799  * 3.  The arrays have same number of components and one array, say _a2_, has one
10800  *   tuple. Then
10801  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10802  *
10803  * Info on components is copied either from the first array (in the first case) or from
10804  * the array with maximal number of elements (getNbOfElems()).
10805  *  \warning No check of division by zero is performed!
10806  *  \param [in] a1 - a dividend array.
10807  *  \param [in] a2 - a divisor array.
10808  *  \return DataArrayInt * - the new instance of DataArrayInt.
10809  *          The caller is to delete this result array using decrRef() as it is no more
10810  *          needed.
10811  *  \throw If either \a a1 or \a a2 is NULL.
10812  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10813  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10814  *         none of them has number of tuples or components equal to 1.
10815  */
10816 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10817 {
10818     if(!a1 || !a2)
10819     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10820   int nbOfTuple1=a1->getNumberOfTuples();
10821   int nbOfTuple2=a2->getNumberOfTuples();
10822   int nbOfComp1=a1->getNumberOfComponents();
10823   int nbOfComp2=a2->getNumberOfComponents();
10824   if(nbOfTuple2==nbOfTuple1)
10825     {
10826       if(nbOfComp1==nbOfComp2)
10827         {
10828           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10829           ret->alloc(nbOfTuple2,nbOfComp1);
10830           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10831           ret->copyStringInfoFrom(*a1);
10832           return ret.retn();
10833         }
10834       else if(nbOfComp2==1)
10835         {
10836           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10837           ret->alloc(nbOfTuple1,nbOfComp1);
10838           const int *a2Ptr=a2->getConstPointer();
10839           const int *a1Ptr=a1->getConstPointer();
10840           int *res=ret->getPointer();
10841           for(int i=0;i<nbOfTuple1;i++)
10842             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10843           ret->copyStringInfoFrom(*a1);
10844           return ret.retn();
10845         }
10846       else
10847         {
10848           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10849           return 0;
10850         }
10851     }
10852   else if(nbOfTuple2==1)
10853     {
10854       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10855       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10856       ret->alloc(nbOfTuple1,nbOfComp1);
10857       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10858       int *pt=ret->getPointer();
10859       for(int i=0;i<nbOfTuple1;i++)
10860         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10861       ret->copyStringInfoFrom(*a1);
10862       return ret.retn();
10863     }
10864   else
10865     {
10866       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10867       return 0;
10868     }
10869 }
10870
10871 /*!
10872  * Modify \a this array so that each value becomes a modulus of division of this value by
10873  * a value of another DataArrayInt. There are 3 valid cases.
10874  * 1.  The arrays have same number of tuples and components. Then each value of
10875  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10876  *   _a_ [ i, j ] %= _other_ [ i, j ].
10877  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10878  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10879  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10880  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10881  *
10882  *  \warning No check of division by zero is performed!
10883  *  \param [in] other - a divisor array.
10884  *  \throw If \a other is NULL.
10885  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10886  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10887  *         \a other has number of both tuples and components not equal to 1.
10888  */
10889 void DataArrayInt::modulusEqual(const DataArrayInt *other)
10890 {
10891   if(!other)
10892     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10893   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10894   checkAllocated(); other->checkAllocated();
10895   int nbOfTuple=getNumberOfTuples();
10896   int nbOfTuple2=other->getNumberOfTuples();
10897   int nbOfComp=getNumberOfComponents();
10898   int nbOfComp2=other->getNumberOfComponents();
10899   if(nbOfTuple==nbOfTuple2)
10900     {
10901       if(nbOfComp==nbOfComp2)
10902         {
10903           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10904         }
10905       else if(nbOfComp2==1)
10906         {
10907           if(nbOfComp2==nbOfComp)
10908             {
10909               int *ptr=getPointer();
10910               const int *ptrc=other->getConstPointer();
10911               for(int i=0;i<nbOfTuple;i++)
10912                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10913             }
10914           else
10915             throw INTERP_KERNEL::Exception(msg);
10916         }
10917       else
10918         throw INTERP_KERNEL::Exception(msg);
10919     }
10920   else if(nbOfTuple2==1)
10921     {
10922       int *ptr=getPointer();
10923       const int *ptrc=other->getConstPointer();
10924       for(int i=0;i<nbOfTuple;i++)
10925         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10926     }
10927   else
10928     throw INTERP_KERNEL::Exception(msg);
10929   declareAsNew();
10930 }
10931
10932 /*!
10933  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10934  * valid cases.
10935  *
10936  *  \param [in] a1 - an array to pow up.
10937  *  \param [in] a2 - another array to sum up.
10938  *  \return DataArrayInt * - the new instance of DataArrayInt.
10939  *          The caller is to delete this result array using decrRef() as it is no more
10940  *          needed.
10941  *  \throw If either \a a1 or \a a2 is NULL.
10942  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10943  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10944  *  \throw If there is a negative value in \a a2.
10945  */
10946 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
10947 {
10948   if(!a1 || !a2)
10949     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10950   int nbOfTuple=a1->getNumberOfTuples();
10951   int nbOfTuple2=a2->getNumberOfTuples();
10952   int nbOfComp=a1->getNumberOfComponents();
10953   int nbOfComp2=a2->getNumberOfComponents();
10954   if(nbOfTuple!=nbOfTuple2)
10955     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10956   if(nbOfComp!=1 || nbOfComp2!=1)
10957     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10958   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10959   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10960   int *ptr=ret->getPointer();
10961   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10962     {
10963       if(*ptr2>=0)
10964         {
10965           int tmp=1;
10966           for(int j=0;j<*ptr2;j++)
10967             tmp*=*ptr1;
10968           *ptr=tmp;
10969         }
10970       else
10971         {
10972           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10973           throw INTERP_KERNEL::Exception(oss.str().c_str());
10974         }
10975     }
10976   return ret.retn();
10977 }
10978
10979 /*!
10980  * Apply pow on values of another DataArrayInt to values of \a this one.
10981  *
10982  *  \param [in] other - an array to pow to \a this one.
10983  *  \throw If \a other is NULL.
10984  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10985  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10986  *  \throw If there is a negative value in \a other.
10987  */
10988 void DataArrayInt::powEqual(const DataArrayInt *other)
10989 {
10990   if(!other)
10991     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10992   int nbOfTuple=getNumberOfTuples();
10993   int nbOfTuple2=other->getNumberOfTuples();
10994   int nbOfComp=getNumberOfComponents();
10995   int nbOfComp2=other->getNumberOfComponents();
10996   if(nbOfTuple!=nbOfTuple2)
10997     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10998   if(nbOfComp!=1 || nbOfComp2!=1)
10999     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11000   int *ptr=getPointer();
11001   const int *ptrc=other->begin();
11002   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11003     {
11004       if(*ptrc>=0)
11005         {
11006           int tmp=1;
11007           for(int j=0;j<*ptrc;j++)
11008             tmp*=*ptr;
11009           *ptr=tmp;
11010         }
11011       else
11012         {
11013           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11014           throw INTERP_KERNEL::Exception(oss.str().c_str());
11015         }
11016     }
11017   declareAsNew();
11018 }
11019
11020 /*!
11021  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11022  * This map, if applied to \a start array, would make it sorted. For example, if
11023  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11024  * [5,6,0,3,2,7,1,4].
11025  *  \param [in] start - pointer to the first element of the array for which the
11026  *         permutation map is computed.
11027  *  \param [in] end - pointer specifying the end of the array \a start, so that
11028  *         the last value of \a start is \a end[ -1 ].
11029  *  \return int * - the result permutation array that the caller is to delete as it is no
11030  *         more needed.
11031  *  \throw If there are equal values in the input array.
11032  */
11033 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11034 {
11035   std::size_t sz=std::distance(start,end);
11036   int *ret=(int *)malloc(sz*sizeof(int));
11037   int *work=new int[sz];
11038   std::copy(start,end,work);
11039   std::sort(work,work+sz);
11040   if(std::unique(work,work+sz)!=work+sz)
11041     {
11042       delete [] work;
11043       free(ret);
11044       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11045     }
11046   std::map<int,int> m;
11047   for(int *workPt=work;workPt!=work+sz;workPt++)
11048     m[*workPt]=(int)std::distance(work,workPt);
11049   int *iter2=ret;
11050   for(const int *iter=start;iter!=end;iter++,iter2++)
11051     *iter2=m[*iter];
11052   delete [] work;
11053   return ret;
11054 }
11055
11056 /*!
11057  * Returns a new DataArrayInt containing an arithmetic progression
11058  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11059  * function.
11060  *  \param [in] begin - the start value of the result sequence.
11061  *  \param [in] end - limiting value, so that every value of the result array is less than
11062  *              \a end.
11063  *  \param [in] step - specifies the increment or decrement.
11064  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11065  *          array using decrRef() as it is no more needed.
11066  *  \throw If \a step == 0.
11067  *  \throw If \a end < \a begin && \a step > 0.
11068  *  \throw If \a end > \a begin && \a step < 0.
11069  */
11070 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11071 {
11072   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11073   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11074   ret->alloc(nbOfTuples,1);
11075   int *ptr=ret->getPointer();
11076   if(step>0)
11077     {
11078       for(int i=begin;i<end;i+=step,ptr++)
11079         *ptr=i;
11080     }
11081   else
11082     {
11083       for(int i=begin;i>end;i+=step,ptr++)
11084         *ptr=i;
11085     }
11086   return ret.retn();
11087 }
11088
11089 /*!
11090  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11091  * Server side.
11092  */
11093 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11094 {
11095   tinyInfo.resize(2);
11096   if(isAllocated())
11097     {
11098       tinyInfo[0]=getNumberOfTuples();
11099       tinyInfo[1]=getNumberOfComponents();
11100     }
11101   else
11102     {
11103       tinyInfo[0]=-1;
11104       tinyInfo[1]=-1;
11105     }
11106 }
11107
11108 /*!
11109  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11110  * Server side.
11111  */
11112 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11113 {
11114   if(isAllocated())
11115     {
11116       int nbOfCompo=getNumberOfComponents();
11117       tinyInfo.resize(nbOfCompo+1);
11118       tinyInfo[0]=getName();
11119       for(int i=0;i<nbOfCompo;i++)
11120         tinyInfo[i+1]=getInfoOnComponent(i);
11121     }
11122   else
11123     {
11124       tinyInfo.resize(1);
11125       tinyInfo[0]=getName();
11126     }
11127 }
11128
11129 /*!
11130  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11131  * This method returns if a feeding is needed.
11132  */
11133 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11134 {
11135   int nbOfTuple=tinyInfoI[0];
11136   int nbOfComp=tinyInfoI[1];
11137   if(nbOfTuple!=-1 || nbOfComp!=-1)
11138     {
11139       alloc(nbOfTuple,nbOfComp);
11140       return true;
11141     }
11142   return false;
11143 }
11144
11145 /*!
11146  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11147  * This method returns if a feeding is needed.
11148  */
11149 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11150 {
11151   setName(tinyInfoS[0].c_str());
11152   if(isAllocated())
11153     {
11154       int nbOfCompo=tinyInfoI[1];
11155       for(int i=0;i<nbOfCompo;i++)
11156         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
11157     }
11158 }
11159
11160 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11161 {
11162   if(_da)
11163     {
11164       _da->incrRef();
11165       if(_da->isAllocated())
11166         {
11167           _nb_comp=da->getNumberOfComponents();
11168           _nb_tuple=da->getNumberOfTuples();
11169           _pt=da->getPointer();
11170         }
11171     }
11172 }
11173
11174 DataArrayIntIterator::~DataArrayIntIterator()
11175 {
11176   if(_da)
11177     _da->decrRef();
11178 }
11179
11180 DataArrayIntTuple *DataArrayIntIterator::nextt()
11181 {
11182   if(_tuple_id<_nb_tuple)
11183     {
11184       _tuple_id++;
11185       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11186       _pt+=_nb_comp;
11187       return ret;
11188     }
11189   else
11190     return 0;
11191 }
11192
11193 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11194 {
11195 }
11196
11197 std::string DataArrayIntTuple::repr() const
11198 {
11199   std::ostringstream oss; oss << "(";
11200   for(int i=0;i<_nb_of_compo-1;i++)
11201     oss << _pt[i] << ", ";
11202   oss << _pt[_nb_of_compo-1] << ")";
11203   return oss.str();
11204 }
11205
11206 int DataArrayIntTuple::intValue() const
11207 {
11208   if(_nb_of_compo==1)
11209     return *_pt;
11210   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11211 }
11212
11213 /*!
11214  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11215  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11216  * 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
11217  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11218  */
11219 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11220 {
11221   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11222     {
11223       DataArrayInt *ret=DataArrayInt::New();
11224       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11225       return ret;
11226     }
11227   else
11228     {
11229       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11230       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11231       throw INTERP_KERNEL::Exception(oss.str().c_str());
11232     }
11233 }