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