Salome HOME
Get relevant changes from V7_dev branch (copyright update, adm files etc)
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MCAuto.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 MEDCoupling;
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::getDirectChildrenWithNull() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const std::string& name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const std::string& varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * This method put in info format the result of the merge of \a var and \a unit.
427  * The standard format for that is "var [unit]".
428  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
429  */
430 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
431 {
432   std::ostringstream oss;
433   oss << var << " [" << unit << "]";
434   return oss.str();
435 }
436
437 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
438 {
439   switch(at)
440     {
441     case AX_CART:
442       return std::string("AX_CART");
443     case AX_CYL:
444       return std::string("AX_CYL");
445     case AX_SPHER:
446       return std::string("AX_SPHER");
447     default:
448       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
449     }
450 }
451
452 /*!
453  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
454  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
455  * the number of component in the result array is same as that of each of given arrays.
456  * Info on components is copied from the first of the given arrays. Number of components
457  * in the given arrays must be  the same.
458  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
459  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
460  *          The caller is to delete this result array using decrRef() as it is no more
461  *          needed.
462  *  \throw If all arrays within \a arrs are NULL.
463  *  \throw If all not null arrays in \a arrs have not the same type.
464  *  \throw If getNumberOfComponents() of arrays within \a arrs.
465  */
466 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
467 {
468   std::vector<const DataArray *> arr2;
469   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
470     if(*it)
471       arr2.push_back(*it);
472   if(arr2.empty())
473     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
474   std::vector<const DataArrayDouble *> arrd;
475   std::vector<const DataArrayInt *> arri;
476   std::vector<const DataArrayChar *> arrc;
477   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
478     {
479       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
480       if(a)
481         { arrd.push_back(a); continue; }
482       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
483       if(b)
484         { arri.push_back(b); continue; }
485       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
486       if(c)
487         { arrc.push_back(c); continue; }
488       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
489     }
490   if(arr2.size()==arrd.size())
491     return DataArrayDouble::Aggregate(arrd);
492   if(arr2.size()==arri.size())
493     return DataArrayInt::Aggregate(arri);
494   if(arr2.size()==arrc.size())
495     return DataArrayChar::Aggregate(arrc);
496   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
497 }
498
499 /*!
500  * Sets information on a component specified by an index.
501  * To know more on format of this information
502  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
503  *  \warning Don't pass NULL as \a info!
504  *  \param [in] i - the index (zero based) of the component of interest.
505  *  \param [in] info - the string containing the information.
506  *  \throw If \a i is not a valid component index.
507  */
508 void DataArray::setInfoOnComponent(int i, const std::string& info)
509 {
510   if(i<(int)_info_on_compo.size() && i>=0)
511     _info_on_compo[i]=info;
512   else
513     {
514       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();
515       throw INTERP_KERNEL::Exception(oss.str().c_str());
516     }
517 }
518
519 /*!
520  * Sets information on all components. This method can change number of components
521  * at certain conditions; if the conditions are not respected, an exception is thrown.
522  * The number of components can be changed in \a this only if \a this is not allocated.
523  * The condition of number of components must not be changed.
524  *
525  * To know more on format of the component information see
526  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
527  *  \param [in] info - a vector of component infos.
528  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
529  */
530 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
531 {
532   if(getNumberOfComponents()!=(int)info.size())
533     {
534       if(!isAllocated())
535         _info_on_compo=info;
536       else
537         {
538           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 !";
539           throw INTERP_KERNEL::Exception(oss.str().c_str());
540         }
541     }
542   else
543     _info_on_compo=info;
544 }
545
546 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
547 {
548   if(getNumberOfTuples()!=nbOfTuples)
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553 }
554
555 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
556 {
557   if(getNumberOfComponents()!=nbOfCompo)
558     {
559       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
560       throw INTERP_KERNEL::Exception(oss.str().c_str());
561     }
562 }
563
564 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
565 {
566   if(getNbOfElems()!=nbOfElems)
567     {
568       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
569       throw INTERP_KERNEL::Exception(oss.str().c_str());
570     }
571 }
572
573 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
574 {
575   if(getNumberOfTuples()!=other.getNumberOfTuples())
576     {
577       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
578       throw INTERP_KERNEL::Exception(oss.str().c_str());
579     }
580   if(getNumberOfComponents()!=other.getNumberOfComponents())
581     {
582       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
583       throw INTERP_KERNEL::Exception(oss.str().c_str());
584     }
585 }
586
587 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
588 {
589   checkNbOfTuples(nbOfTuples,msg);
590   checkNbOfComps(nbOfCompo,msg);
591 }
592
593 /*!
594  * Simply this method checks that \b value is in [0,\b ref).
595  */
596 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
597 {
598   if(value<0 || value>=ref)
599     {
600       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
601       throw INTERP_KERNEL::Exception(oss.str().c_str());
602     }
603 }
604
605 /*!
606  * This method checks that [\b start, \b end) is compliant with ref length \b value.
607  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
608  */
609 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
610 {
611   if(start<0 || start>=value)
612     {
613       if(value!=start || end!=start)
614         {
615           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
616           throw INTERP_KERNEL::Exception(oss.str().c_str());
617         }
618     }
619   if(end<0 || end>value)
620     {
621       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
622       throw INTERP_KERNEL::Exception(oss.str().c_str());
623     }
624 }
625
626 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
627 {
628   if(value<0 || value>ref)
629     {
630       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633 }
634
635 /*!
636  * 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, 
637  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
638  *
639  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
640  *
641  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
642  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
643  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
644  * \param [in] sliceId - the slice id considered
645  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
646  * \param [out] startSlice - the start of the slice considered
647  * \param [out] stopSlice - the stop of the slice consided
648  * 
649  * \throw If \a step == 0
650  * \throw If \a nbOfSlices not > 0
651  * \throw If \a sliceId not in [0,nbOfSlices)
652  */
653 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
654 {
655   if(nbOfSlices<=0)
656     {
657       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
658       throw INTERP_KERNEL::Exception(oss.str().c_str());
659     }
660   if(sliceId<0 || sliceId>=nbOfSlices)
661     {
662       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
663       throw INTERP_KERNEL::Exception(oss.str().c_str());
664     }
665   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
666   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
667   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
668   if(sliceId<nbOfSlices-1)
669     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
670   else
671     stopSlice=stop;
672 }
673
674 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
675 {
676   if(end<begin)
677     {
678       std::ostringstream oss; oss << msg << " : end before begin !";
679       throw INTERP_KERNEL::Exception(oss.str().c_str());
680     }
681   if(end==begin)
682     return 0;
683   if(step<=0)
684     {
685       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
686       throw INTERP_KERNEL::Exception(oss.str().c_str());
687     }
688   return (end-1-begin)/step+1;
689 }
690
691 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
692 {
693   if(step==0)
694     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
695   if(end<begin && step>0)
696     {
697       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
698       throw INTERP_KERNEL::Exception(oss.str().c_str());
699     }
700   if(begin<end && step<0)
701     {
702       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
703       throw INTERP_KERNEL::Exception(oss.str().c_str());
704     }
705   if(begin!=end)
706     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
707   else
708     return 0;
709 }
710
711 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
712 {
713   if(step!=0)
714     {
715       if(step>0)
716         {
717           if(begin<=value && value<end)
718             {
719               if((value-begin)%step==0)
720                 return (value-begin)/step;
721               else
722                 return -1;
723             }
724           else
725             return -1;
726         }
727       else
728         {
729           if(begin>=value && value>end)
730             {
731               if((begin-value)%(-step)==0)
732                 return (begin-value)/(-step);
733               else
734                 return -1;
735             }
736           else
737             return -1;
738         }
739     }
740   else
741     return -1;
742 }
743
744 /*!
745  * Returns a new instance of DataArrayDouble. The caller is to delete this array
746  * using decrRef() as it is no more needed. 
747  */
748 DataArrayDouble *DataArrayDouble::New()
749 {
750   return new DataArrayDouble;
751 }
752
753 /*!
754  * Checks if raw data is allocated. Read more on the raw data
755  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
756  *  \return bool - \a true if the raw data is allocated, \a false else.
757  */
758 bool DataArrayDouble::isAllocated() const
759 {
760   return getConstPointer()!=0;
761 }
762
763 /*!
764  * Checks if raw data is allocated and throws an exception if it is not the case.
765  *  \throw If the raw data is not allocated.
766  */
767 void DataArrayDouble::checkAllocated() const
768 {
769   if(!isAllocated())
770     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
771 }
772
773 /*!
774  * This method desallocated \a this without modification of informations relative to the components.
775  * After call of this method, DataArrayDouble::isAllocated will return false.
776  * If \a this is already not allocated, \a this is let unchanged.
777  */
778 void DataArrayDouble::desallocate()
779 {
780   _mem.destroy();
781 }
782
783 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
784 {
785   std::size_t sz(_mem.getNbOfElemAllocated());
786   sz*=sizeof(double);
787   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
788 }
789
790 /*!
791  * Returns the only one value in \a this, if and only if number of elements
792  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
793  *  \return double - the sole value stored in \a this array.
794  *  \throw If at least one of conditions stated above is not fulfilled.
795  */
796 double DataArrayDouble::doubleValue() const
797 {
798   if(isAllocated())
799     {
800       if(getNbOfElems()==1)
801         {
802           return *getConstPointer();
803         }
804       else
805         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
806     }
807   else
808     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
809 }
810
811 /*!
812  * Checks the number of tuples.
813  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
814  *  \throw If \a this is not allocated.
815  */
816 bool DataArrayDouble::empty() const
817 {
818   checkAllocated();
819   return getNumberOfTuples()==0;
820 }
821
822 /*!
823  * Returns a full copy of \a this. For more info on copying data arrays see
824  * \ref MEDCouplingArrayBasicsCopyDeep.
825  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
826  *          delete this array using decrRef() as it is no more needed. 
827  */
828 DataArrayDouble *DataArrayDouble::deepCopy() const
829 {
830   return new DataArrayDouble(*this);
831 }
832
833 /*!
834  * Returns either a \a deep or \a shallow copy of this array. For more info see
835  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
836  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
837  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
838  *          == \a true) or \a this instance (if \a dCpy == \a false).
839  */
840 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
841 {
842   if(dCpy)
843     return deepCopy();
844   else
845     {
846       incrRef();
847       return const_cast<DataArrayDouble *>(this);
848     }
849 }
850
851 /*!
852  * Copies all the data from another DataArrayDouble. For more info see
853  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
854  *  \param [in] other - another instance of DataArrayDouble to copy data from.
855  *  \throw If the \a other is not allocated.
856  */
857 void DataArrayDouble::deepCopyFrom(const DataArrayDouble& other)
858 {
859   other.checkAllocated();
860   int nbOfTuples=other.getNumberOfTuples();
861   int nbOfComp=other.getNumberOfComponents();
862   allocIfNecessary(nbOfTuples,nbOfComp);
863   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
864   double *pt=getPointer();
865   const double *ptI=other.getConstPointer();
866   for(std::size_t i=0;i<nbOfElems;i++)
867     pt[i]=ptI[i];
868   copyStringInfoFrom(other);
869 }
870
871 /*!
872  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
873  * 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.
874  * If \a this has not already been allocated, number of components is set to one.
875  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
876  * 
877  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
878  */
879 void DataArrayDouble::reserve(std::size_t nbOfElems)
880 {
881   int nbCompo=getNumberOfComponents();
882   if(nbCompo==1)
883     {
884       _mem.reserve(nbOfElems);
885     }
886   else if(nbCompo==0)
887     {
888       _mem.reserve(nbOfElems);
889       _info_on_compo.resize(1);
890     }
891   else
892     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
893 }
894
895 /*!
896  * 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
897  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
898  *
899  * \param [in] val the value to be added in \a this
900  * \throw If \a this has already been allocated with number of components different from one.
901  * \sa DataArrayDouble::pushBackValsSilent
902  */
903 void DataArrayDouble::pushBackSilent(double val)
904 {
905   int nbCompo=getNumberOfComponents();
906   if(nbCompo==1)
907     _mem.pushBack(val);
908   else if(nbCompo==0)
909     {
910       _info_on_compo.resize(1);
911       _mem.pushBack(val);
912     }
913   else
914     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
915 }
916
917 /*!
918  * 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
919  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
920  *
921  *  \param [in] valsBg - an array of values to push at the end of \c this.
922  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
923  *              the last value of \a valsBg is \a valsEnd[ -1 ].
924  * \throw If \a this has already been allocated with number of components different from one.
925  * \sa DataArrayDouble::pushBackSilent
926  */
927 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
928 {
929   int nbCompo=getNumberOfComponents();
930   if(nbCompo==1)
931     _mem.insertAtTheEnd(valsBg,valsEnd);
932   else if(nbCompo==0)
933     {
934       _info_on_compo.resize(1);
935       _mem.insertAtTheEnd(valsBg,valsEnd);
936     }
937   else
938     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
939 }
940
941 /*!
942  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
943  * \throw If \a this is already empty.
944  * \throw If \a this has number of components different from one.
945  */
946 double DataArrayDouble::popBackSilent()
947 {
948   if(getNumberOfComponents()==1)
949     return _mem.popBack();
950   else
951     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
952 }
953
954 /*!
955  * 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.
956  *
957  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
958  */
959 void DataArrayDouble::pack() const
960 {
961   _mem.pack();
962 }
963
964 /*!
965  * Allocates the raw data in memory. If exactly same memory as needed already
966  * allocated, it is not re-allocated.
967  *  \param [in] nbOfTuple - number of tuples of data to allocate.
968  *  \param [in] nbOfCompo - number of components of data to allocate.
969  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
970  */
971 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
972 {
973   if(isAllocated())
974     {
975       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
976         alloc(nbOfTuple,nbOfCompo);
977     }
978   else
979     alloc(nbOfTuple,nbOfCompo);
980 }
981
982 /*!
983  * Allocates the raw data in memory. If the memory was already allocated, then it is
984  * freed and re-allocated. See an example of this method use
985  * \ref MEDCouplingArraySteps1WC "here".
986  *  \param [in] nbOfTuple - number of tuples of data to allocate.
987  *  \param [in] nbOfCompo - number of components of data to allocate.
988  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
989  */
990 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
991 {
992   if(nbOfTuple<0 || nbOfCompo<0)
993     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
994   _info_on_compo.resize(nbOfCompo);
995   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
996   declareAsNew();
997 }
998
999 /*!
1000  * Assign zero to all values in \a this array. To know more on filling arrays see
1001  * \ref MEDCouplingArrayFill.
1002  * \throw If \a this is not allocated.
1003  */
1004 void DataArrayDouble::fillWithZero()
1005 {
1006   checkAllocated();
1007   _mem.fillWithValue(0.);
1008   declareAsNew();
1009 }
1010
1011 /*!
1012  * Assign \a val to all values in \a this array. To know more on filling arrays see
1013  * \ref MEDCouplingArrayFill.
1014  *  \param [in] val - the value to fill with.
1015  *  \throw If \a this is not allocated.
1016  */
1017 void DataArrayDouble::fillWithValue(double val)
1018 {
1019   checkAllocated();
1020   _mem.fillWithValue(val);
1021   declareAsNew();
1022 }
1023
1024 /*!
1025  * Set all values in \a this array so that the i-th element equals to \a init + i
1026  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1027  *  \param [in] init - value to assign to the first element of array.
1028  *  \throw If \a this->getNumberOfComponents() != 1
1029  *  \throw If \a this is not allocated.
1030  */
1031 void DataArrayDouble::iota(double init)
1032 {
1033   checkAllocated();
1034   if(getNumberOfComponents()!=1)
1035     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1036   double *ptr=getPointer();
1037   int ntuples=getNumberOfTuples();
1038   for(int i=0;i<ntuples;i++)
1039     ptr[i]=init+double(i);
1040   declareAsNew();
1041 }
1042
1043 /*!
1044  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1045  *  \param [in] val - value to check equality of array values to.
1046  *  \param [in] eps - precision to check the equality.
1047  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1048  *                 \a false else.
1049  *  \throw If \a this->getNumberOfComponents() != 1
1050  *  \throw If \a this is not allocated.
1051  */
1052 bool DataArrayDouble::isUniform(double val, double eps) const
1053 {
1054   checkAllocated();
1055   if(getNumberOfComponents()!=1)
1056     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1057   int nbOfTuples=getNumberOfTuples();
1058   const double *w=getConstPointer();
1059   const double *end2=w+nbOfTuples;
1060   const double vmin=val-eps;
1061   const double vmax=val+eps;
1062   for(;w!=end2;w++)
1063     if(*w<vmin || *w>vmax)
1064       return false;
1065   return true;
1066 }
1067
1068 /*!
1069  * Sorts values of the array.
1070  *  \param [in] asc - \a true means ascending order, \a false, descending.
1071  *  \throw If \a this is not allocated.
1072  *  \throw If \a this->getNumberOfComponents() != 1.
1073  */
1074 void DataArrayDouble::sort(bool asc)
1075 {
1076   checkAllocated();
1077   if(getNumberOfComponents()!=1)
1078     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1079   _mem.sort(asc);
1080   declareAsNew();
1081 }
1082
1083 /*!
1084  * Reverse the array values.
1085  *  \throw If \a this->getNumberOfComponents() < 1.
1086  *  \throw If \a this is not allocated.
1087  */
1088 void DataArrayDouble::reverse()
1089 {
1090   checkAllocated();
1091   _mem.reverse(getNumberOfComponents());
1092   declareAsNew();
1093 }
1094
1095 /*!
1096  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1097  * with at least absolute difference value of |\a eps| at each step.
1098  * If not an exception is thrown.
1099  *  \param [in] increasing - if \a true, the array values should be increasing.
1100  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1101  *                    the values are considered different.
1102  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1103  *         increasing arg.
1104  *  \throw If \a this->getNumberOfComponents() != 1.
1105  *  \throw If \a this is not allocated.
1106  */
1107 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1108 {
1109   if(!isMonotonic(increasing,eps))
1110     {
1111       if (increasing)
1112         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1113       else
1114         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1115     }
1116 }
1117
1118 /*!
1119  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1120  * with at least absolute difference value of |\a eps| at each step.
1121  *  \param [in] increasing - if \a true, array values should be increasing.
1122  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1123  *                    the values are considered different.
1124  *  \return bool - \a true if values change in accordance with \a increasing arg.
1125  *  \throw If \a this->getNumberOfComponents() != 1.
1126  *  \throw If \a this is not allocated.
1127  */
1128 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1129 {
1130   checkAllocated();
1131   if(getNumberOfComponents()!=1)
1132     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1133   int nbOfElements=getNumberOfTuples();
1134   const double *ptr=getConstPointer();
1135   if(nbOfElements==0)
1136     return true;
1137   double ref=ptr[0];
1138   double absEps=fabs(eps);
1139   if(increasing)
1140     {
1141       for(int i=1;i<nbOfElements;i++)
1142         {
1143           if(ptr[i]<(ref+absEps))
1144             return false;
1145           ref=ptr[i];
1146         }
1147       return true;
1148     }
1149   else
1150     {
1151       for(int i=1;i<nbOfElements;i++)
1152         {
1153           if(ptr[i]>(ref-absEps))
1154             return false;
1155           ref=ptr[i];
1156         }
1157       return true;
1158     }
1159 }
1160
1161 /*!
1162  * Returns a textual and human readable representation of \a this instance of
1163  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1164  * \return std::string - text describing \a this DataArrayDouble.
1165  *
1166  * \sa reprNotTooLong, reprZip
1167  */
1168 std::string DataArrayDouble::repr() const
1169 {
1170   std::ostringstream ret;
1171   reprStream(ret);
1172   return ret.str();
1173 }
1174
1175 std::string DataArrayDouble::reprZip() const
1176 {
1177   std::ostringstream ret;
1178   reprZipStream(ret);
1179   return ret.str();
1180 }
1181
1182 /*!
1183  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
1184  * printed out to avoid to consume too much space in interpretor.
1185  * \sa repr
1186  */
1187 std::string DataArrayDouble::reprNotTooLong() const
1188 {
1189   std::ostringstream ret;
1190   reprNotTooLongStream(ret);
1191   return ret.str();
1192 }
1193
1194 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1195 {
1196   static const char SPACE[4]={' ',' ',' ',' '};
1197   checkAllocated();
1198   std::string idt(indent,' ');
1199   ofs.precision(17);
1200   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1201   //
1202   bool areAllEmpty(true);
1203   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
1204     if(!(*it).empty())
1205       areAllEmpty=false;
1206   if(!areAllEmpty)
1207     for(std::size_t i=0;i<_info_on_compo.size();i++)
1208       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
1209   //
1210   if(byteArr)
1211     {
1212       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1213       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1214       float *pt(tmp);
1215       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1216       for(const double *src=begin();src!=end();src++,pt++)
1217         *pt=float(*src);
1218       const char *data(reinterpret_cast<const char *>((float *)tmp));
1219       std::size_t sz(getNbOfElems()*sizeof(float));
1220       byteArr->insertAtTheEnd(data,data+sz);
1221       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1222     }
1223   else
1224     {
1225       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1226       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1227     }
1228   ofs << std::endl << idt << "</DataArray>\n";
1229 }
1230
1231 void DataArrayDouble::reprStream(std::ostream& stream) const
1232 {
1233   stream << "Name of double array : \"" << _name << "\"\n";
1234   reprWithoutNameStream(stream);
1235 }
1236
1237 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1238 {
1239   stream << "Name of double array : \"" << _name << "\"\n";
1240   reprZipWithoutNameStream(stream);
1241 }
1242
1243 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1244 {
1245   stream << "Name of double array : \"" << _name << "\"\n";
1246   reprNotTooLongWithoutNameStream(stream);
1247 }
1248
1249 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1250 {
1251   DataArray::reprWithoutNameStream(stream);
1252   stream.precision(17);
1253   _mem.repr(getNumberOfComponents(),stream);
1254 }
1255
1256 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1257 {
1258   DataArray::reprWithoutNameStream(stream);
1259   stream.precision(17);
1260   _mem.reprZip(getNumberOfComponents(),stream);
1261 }
1262
1263 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1264 {
1265   DataArray::reprWithoutNameStream(stream);
1266   stream.precision(17);
1267   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1268 }
1269
1270 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1271 {
1272   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1273   const double *data=getConstPointer();
1274   stream.precision(17);
1275   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1276   if(nbTuples*nbComp>=1)
1277     {
1278       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1279       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1280       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1281       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1282     }
1283   else
1284     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1285   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1286 }
1287
1288 /*!
1289  * Method that gives a quick overvien of \a this for python.
1290  */
1291 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1292 {
1293   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1294   stream << "DataArrayDouble C++ instance at " << this << ". ";
1295   if(isAllocated())
1296     {
1297       int nbOfCompo=(int)_info_on_compo.size();
1298       if(nbOfCompo>=1)
1299         {
1300           int nbOfTuples=getNumberOfTuples();
1301           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1302           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1303         }
1304       else
1305         stream << "Number of components : 0.";
1306     }
1307   else
1308     stream << "*** No data allocated ****";
1309 }
1310
1311 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1312 {
1313   const double *data=begin();
1314   int nbOfTuples=getNumberOfTuples();
1315   int nbOfCompo=(int)_info_on_compo.size();
1316   std::ostringstream oss2; oss2 << "[";
1317   oss2.precision(17);
1318   std::string oss2Str(oss2.str());
1319   bool isFinished=true;
1320   for(int i=0;i<nbOfTuples && isFinished;i++)
1321     {
1322       if(nbOfCompo>1)
1323         {
1324           oss2 << "(";
1325           for(int j=0;j<nbOfCompo;j++,data++)
1326             {
1327               oss2 << *data;
1328               if(j!=nbOfCompo-1) oss2 << ", ";
1329             }
1330           oss2 << ")";
1331         }
1332       else
1333         oss2 << *data++;
1334       if(i!=nbOfTuples-1) oss2 << ", ";
1335       std::string oss3Str(oss2.str());
1336       if(oss3Str.length()<maxNbOfByteInRepr)
1337         oss2Str=oss3Str;
1338       else
1339         isFinished=false;
1340     }
1341   stream << oss2Str;
1342   if(!isFinished)
1343     stream << "... ";
1344   stream << "]";
1345 }
1346
1347 /*!
1348  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1349  * mismatch is given.
1350  * 
1351  * \param [in] other the instance to be compared with \a this
1352  * \param [in] prec the precision to compare numeric data of the arrays.
1353  * \param [out] reason In case of inequality returns the reason.
1354  * \sa DataArrayDouble::isEqual
1355  */
1356 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1357 {
1358   if(!areInfoEqualsIfNotWhy(other,reason))
1359     return false;
1360   return _mem.isEqual(other._mem,prec,reason);
1361 }
1362
1363 /*!
1364  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1365  * \ref MEDCouplingArrayBasicsCompare.
1366  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1367  *  \param [in] prec - precision value to compare numeric data of the arrays.
1368  *  \return bool - \a true if the two arrays are equal, \a false else.
1369  */
1370 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1371 {
1372   std::string tmp;
1373   return isEqualIfNotWhy(other,prec,tmp);
1374 }
1375
1376 /*!
1377  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1378  * \ref MEDCouplingArrayBasicsCompare.
1379  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1380  *  \param [in] prec - precision value to compare numeric data of the arrays.
1381  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1382  */
1383 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1384 {
1385   std::string tmp;
1386   return _mem.isEqual(other._mem,prec,tmp);
1387 }
1388
1389 /*!
1390  * Changes number of tuples in the array. If the new number of tuples is smaller
1391  * than the current number the array is truncated, otherwise the array is extended.
1392  *  \param [in] nbOfTuples - new number of tuples. 
1393  *  \throw If \a this is not allocated.
1394  *  \throw If \a nbOfTuples is negative.
1395  */
1396 void DataArrayDouble::reAlloc(int nbOfTuples)
1397 {
1398   if(nbOfTuples<0)
1399     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1400   checkAllocated();
1401   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1402   declareAsNew();
1403 }
1404
1405 /*!
1406  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1407  * array to the new one.
1408  *  \return DataArrayInt * - the new instance of DataArrayInt.
1409  */
1410 DataArrayInt *DataArrayDouble::convertToIntArr() const
1411 {
1412   DataArrayInt *ret=DataArrayInt::New();
1413   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1414   int *dest=ret->getPointer();
1415   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1416   for(const double *src=begin();src!=end();src++,dest++)
1417     *dest=(int)*src;
1418   ret->copyStringInfoFrom(*this);
1419   return ret;
1420 }
1421
1422 /*!
1423  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1424  * arranged in memory. If \a this array holds 2 components of 3 values:
1425  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1426  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1427  *  \warning Do not confuse this method with transpose()!
1428  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1429  *          is to delete using decrRef() as it is no more needed.
1430  *  \throw If \a this is not allocated.
1431  */
1432 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1433 {
1434   if(_mem.isNull())
1435     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1436   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1437   DataArrayDouble *ret=DataArrayDouble::New();
1438   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1439   return ret;
1440 }
1441
1442 /*!
1443  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1444  * arranged in memory. If \a this array holds 2 components of 3 values:
1445  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1446  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1447  *  \warning Do not confuse this method with transpose()!
1448  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1449  *          is to delete using decrRef() as it is no more needed.
1450  *  \throw If \a this is not allocated.
1451  */
1452 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1453 {
1454   if(_mem.isNull())
1455     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1456   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1457   DataArrayDouble *ret=DataArrayDouble::New();
1458   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1459   return ret;
1460 }
1461
1462 /*!
1463  * Permutes values of \a this array as required by \a old2New array. The values are
1464  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1465  * the same as in \c this one.
1466  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1467  * For more info on renumbering see \ref numbering.
1468  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1469  *     giving a new position for i-th old value.
1470  */
1471 void DataArrayDouble::renumberInPlace(const int *old2New)
1472 {
1473   checkAllocated();
1474   int nbTuples=getNumberOfTuples();
1475   int nbOfCompo=getNumberOfComponents();
1476   double *tmp=new double[nbTuples*nbOfCompo];
1477   const double *iptr=getConstPointer();
1478   for(int i=0;i<nbTuples;i++)
1479     {
1480       int v=old2New[i];
1481       if(v>=0 && v<nbTuples)
1482         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1483       else
1484         {
1485           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1486           throw INTERP_KERNEL::Exception(oss.str().c_str());
1487         }
1488     }
1489   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1490   delete [] tmp;
1491   declareAsNew();
1492 }
1493
1494 /*!
1495  * Permutes values of \a this array as required by \a new2Old array. The values are
1496  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1497  * the same as in \c this one.
1498  * For more info on renumbering see \ref numbering.
1499  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1500  *     giving a previous position of i-th new value.
1501  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1502  *          is to delete using decrRef() as it is no more needed.
1503  */
1504 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1505 {
1506   checkAllocated();
1507   int nbTuples=getNumberOfTuples();
1508   int nbOfCompo=getNumberOfComponents();
1509   double *tmp=new double[nbTuples*nbOfCompo];
1510   const double *iptr=getConstPointer();
1511   for(int i=0;i<nbTuples;i++)
1512     {
1513       int v=new2Old[i];
1514       if(v>=0 && v<nbTuples)
1515         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1516       else
1517         {
1518           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1519           throw INTERP_KERNEL::Exception(oss.str().c_str());
1520         }
1521     }
1522   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1523   delete [] tmp;
1524   declareAsNew();
1525 }
1526
1527 /*!
1528  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1529  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1530  * Number of tuples in the result array remains the same as in \c this one.
1531  * If a permutation reduction is needed, renumberAndReduce() should be used.
1532  * For more info on renumbering see \ref numbering.
1533  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1534  *          giving a new position for i-th old value.
1535  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1536  *          is to delete using decrRef() as it is no more needed.
1537  *  \throw If \a this is not allocated.
1538  */
1539 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1540 {
1541   checkAllocated();
1542   int nbTuples=getNumberOfTuples();
1543   int nbOfCompo=getNumberOfComponents();
1544   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1545   ret->alloc(nbTuples,nbOfCompo);
1546   ret->copyStringInfoFrom(*this);
1547   const double *iptr=getConstPointer();
1548   double *optr=ret->getPointer();
1549   for(int i=0;i<nbTuples;i++)
1550     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1551   ret->copyStringInfoFrom(*this);
1552   return ret.retn();
1553 }
1554
1555 /*!
1556  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1557  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1558  * tuples in the result array remains the same as in \c this one.
1559  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1560  * For more info on renumbering see \ref numbering.
1561  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1562  *     giving a previous position of i-th new value.
1563  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1564  *          is to delete using decrRef() as it is no more needed.
1565  */
1566 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1567 {
1568   checkAllocated();
1569   int nbTuples=getNumberOfTuples();
1570   int nbOfCompo=getNumberOfComponents();
1571   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1572   ret->alloc(nbTuples,nbOfCompo);
1573   ret->copyStringInfoFrom(*this);
1574   const double *iptr=getConstPointer();
1575   double *optr=ret->getPointer();
1576   for(int i=0;i<nbTuples;i++)
1577     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1578   ret->copyStringInfoFrom(*this);
1579   return ret.retn();
1580 }
1581
1582 /*!
1583  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1584  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1585  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1586  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1587  * \a old2New[ i ] is negative, is missing from the result array.
1588  * For more info on renumbering see \ref numbering.
1589  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1590  *     giving a new position for i-th old tuple and giving negative position for
1591  *     for i-th old tuple that should be omitted.
1592  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1593  *          is to delete using decrRef() as it is no more needed.
1594  */
1595 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1596 {
1597   checkAllocated();
1598   int nbTuples=getNumberOfTuples();
1599   int nbOfCompo=getNumberOfComponents();
1600   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1601   ret->alloc(newNbOfTuple,nbOfCompo);
1602   const double *iptr=getConstPointer();
1603   double *optr=ret->getPointer();
1604   for(int i=0;i<nbTuples;i++)
1605     {
1606       int w=old2New[i];
1607       if(w>=0)
1608         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1609     }
1610   ret->copyStringInfoFrom(*this);
1611   return ret.retn();
1612 }
1613
1614 /*!
1615  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1616  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1617  * \a new2OldBg array.
1618  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1619  * This method is equivalent to renumberAndReduce() except that convention in input is
1620  * \c new2old and \b not \c old2new.
1621  * For more info on renumbering see \ref numbering.
1622  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1623  *              tuple index in \a this array to fill the i-th tuple in the new array.
1624  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1625  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1626  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1627  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1628  *          is to delete using decrRef() as it is no more needed.
1629  */
1630 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1631 {
1632   checkAllocated();
1633   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1634   int nbComp=getNumberOfComponents();
1635   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1636   ret->copyStringInfoFrom(*this);
1637   double *pt=ret->getPointer();
1638   const double *srcPt=getConstPointer();
1639   int i=0;
1640   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1641     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1642   ret->copyStringInfoFrom(*this);
1643   return ret.retn();
1644 }
1645
1646 DataArrayDouble *DataArrayDouble::selectByTupleId(const DataArrayInt & di) const
1647 {
1648   return selectByTupleId(di.getConstPointer(), di.getConstPointer()+di.getNumberOfTuples());
1649 }
1650
1651 /*!
1652  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1653  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1654  * \a new2OldBg array.
1655  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1656  * This method is equivalent to renumberAndReduce() except that convention in input is
1657  * \c new2old and \b not \c old2new.
1658  * This method is equivalent to selectByTupleId() except that it prevents coping data
1659  * from behind the end of \a this array.
1660  * For more info on renumbering see \ref numbering.
1661  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1662  *              tuple index in \a this array to fill the i-th tuple in the new array.
1663  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1664  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1665  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1666  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1667  *          is to delete using decrRef() as it is no more needed.
1668  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1669  */
1670 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1671 {
1672   checkAllocated();
1673   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1674   int nbComp=getNumberOfComponents();
1675   int oldNbOfTuples=getNumberOfTuples();
1676   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1677   ret->copyStringInfoFrom(*this);
1678   double *pt=ret->getPointer();
1679   const double *srcPt=getConstPointer();
1680   int i=0;
1681   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1682     if(*w>=0 && *w<oldNbOfTuples)
1683       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1684     else
1685       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1686   ret->copyStringInfoFrom(*this);
1687   return ret.retn();
1688 }
1689
1690 /*!
1691  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1692  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1693  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1694  * command \c range( \a bg, \a end2, \a step ).
1695  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1696  * not constructed explicitly.
1697  * For more info on renumbering see \ref numbering.
1698  *  \param [in] bg - index of the first tuple to copy from \a this array.
1699  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1700  *  \param [in] step - index increment to get index of the next tuple to copy.
1701  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1702  *          is to delete using decrRef() as it is no more needed.
1703  *  \sa DataArrayDouble::subArray.
1704  */
1705 DataArrayDouble *DataArrayDouble::selectByTupleIdSafeSlice(int bg, int end2, int step) const
1706 {
1707   checkAllocated();
1708   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1709   int nbComp=getNumberOfComponents();
1710   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleIdSafeSlice : ");
1711   ret->alloc(newNbOfTuples,nbComp);
1712   double *pt=ret->getPointer();
1713   const double *srcPt=getConstPointer()+bg*nbComp;
1714   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1715     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1716   ret->copyStringInfoFrom(*this);
1717   return ret.retn();
1718 }
1719
1720 /*!
1721  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1722  * of tuples specified by \a ranges parameter.
1723  * For more info on renumbering see \ref numbering.
1724  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1725  *              of tuples in [\c begin,\c end) format.
1726  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1727  *          is to delete using decrRef() as it is no more needed.
1728  *  \throw If \a end < \a begin.
1729  *  \throw If \a end > \a this->getNumberOfTuples().
1730  *  \throw If \a this is not allocated.
1731  */
1732 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1733 {
1734   checkAllocated();
1735   int nbOfComp=getNumberOfComponents();
1736   int nbOfTuplesThis=getNumberOfTuples();
1737   if(ranges.empty())
1738     {
1739       DataArrayDouble *ret=DataArrayDouble::New();
1740       ret->alloc(0,nbOfComp);
1741       ret->copyStringInfoFrom(*this);
1742       return ret;
1743     }
1744   int ref=ranges.front().first;
1745   int nbOfTuples=0;
1746   bool isIncreasing=true;
1747   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1748     {
1749       if((*it).first<=(*it).second)
1750         {
1751           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1752             {
1753               nbOfTuples+=(*it).second-(*it).first;
1754               if(isIncreasing)
1755                 isIncreasing=ref<=(*it).first;
1756               ref=(*it).second;
1757             }
1758           else
1759             {
1760               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1761               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1762               throw INTERP_KERNEL::Exception(oss.str().c_str());
1763             }
1764         }
1765       else
1766         {
1767           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1768           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1769           throw INTERP_KERNEL::Exception(oss.str().c_str());
1770         }
1771     }
1772   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1773     return deepCopy();
1774   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1775   ret->alloc(nbOfTuples,nbOfComp);
1776   ret->copyStringInfoFrom(*this);
1777   const double *src=getConstPointer();
1778   double *work=ret->getPointer();
1779   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1780     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1781   return ret.retn();
1782 }
1783
1784 /*!
1785  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1786  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1787  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1788  * This method is a specialization of selectByTupleIdSafeSlice().
1789  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1790  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1791  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1792  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1793  *          is to delete using decrRef() as it is no more needed.
1794  *  \throw If \a tupleIdBg < 0.
1795  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1796     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1797  *  \sa DataArrayDouble::selectByTupleIdSafeSlice
1798  */
1799 DataArrayDouble *DataArrayDouble::subArray(int tupleIdBg, int tupleIdEnd) const
1800 {
1801   checkAllocated();
1802   int nbt=getNumberOfTuples();
1803   if(tupleIdBg<0)
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter must be greater than 0 !");
1805   if(tupleIdBg>nbt)
1806     throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter is greater than number of tuples !");
1807   int trueEnd=tupleIdEnd;
1808   if(tupleIdEnd!=-1)
1809     {
1810       if(tupleIdEnd>nbt)
1811         throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
1812     }
1813   else
1814     trueEnd=nbt;
1815   int nbComp=getNumberOfComponents();
1816   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1817   ret->alloc(trueEnd-tupleIdBg,nbComp);
1818   ret->copyStringInfoFrom(*this);
1819   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1820   return ret.retn();
1821 }
1822
1823 /*!
1824  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1825  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1826  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1827  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1828  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1829  * components.  
1830  *  \param [in] newNbOfComp - number of components for the new array to have.
1831  *  \param [in] dftValue - value assigned to new values added to the new array.
1832  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1833  *          is to delete using decrRef() as it is no more needed.
1834  *  \throw If \a this is not allocated.
1835  */
1836 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1837 {
1838   checkAllocated();
1839   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1840   ret->alloc(getNumberOfTuples(),newNbOfComp);
1841   const double *oldc=getConstPointer();
1842   double *nc=ret->getPointer();
1843   int nbOfTuples=getNumberOfTuples();
1844   int oldNbOfComp=getNumberOfComponents();
1845   int dim=std::min(oldNbOfComp,newNbOfComp);
1846   for(int i=0;i<nbOfTuples;i++)
1847     {
1848       int j=0;
1849       for(;j<dim;j++)
1850         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1851       for(;j<newNbOfComp;j++)
1852         nc[newNbOfComp*i+j]=dftValue;
1853     }
1854   ret->setName(getName());
1855   for(int i=0;i<dim;i++)
1856     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1857   ret->setName(getName());
1858   return ret.retn();
1859 }
1860
1861 /*!
1862  * Changes the number of components within \a this array so that its raw data **does
1863  * not** change, instead splitting this data into tuples changes.
1864  *  \warning This method erases all (name and unit) component info set before!
1865  *  \param [in] newNbOfComp - number of components for \a this array to have.
1866  *  \throw If \a this is not allocated
1867  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1868  *  \throw If \a newNbOfCompo is lower than 1.
1869  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1870  *  \warning This method erases all (name and unit) component info set before!
1871  */
1872 void DataArrayDouble::rearrange(int newNbOfCompo)
1873 {
1874   checkAllocated();
1875   if(newNbOfCompo<1)
1876     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1877   std::size_t nbOfElems=getNbOfElems();
1878   if(nbOfElems%newNbOfCompo!=0)
1879     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1880   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1881     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1882   _info_on_compo.clear();
1883   _info_on_compo.resize(newNbOfCompo);
1884   declareAsNew();
1885 }
1886
1887 /*!
1888  * Changes the number of components within \a this array to be equal to its number
1889  * of tuples, and inversely its number of tuples to become equal to its number of 
1890  * components. So that its raw data **does not** change, instead splitting this
1891  * data into tuples changes.
1892  *  \warning This method erases all (name and unit) component info set before!
1893  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1894  *  \throw If \a this is not allocated.
1895  *  \sa rearrange()
1896  */
1897 void DataArrayDouble::transpose()
1898 {
1899   checkAllocated();
1900   int nbOfTuples=getNumberOfTuples();
1901   rearrange(nbOfTuples);
1902 }
1903
1904 /*!
1905  * Returns a copy of \a this array composed of selected components.
1906  * The new DataArrayDouble has the same number of tuples but includes components
1907  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1908  * can be either less, same or more than \a this->getNbOfElems().
1909  *  \param [in] compoIds - sequence of zero based indices of components to include
1910  *              into the new array.
1911  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1912  *          is to delete using decrRef() as it is no more needed.
1913  *  \throw If \a this is not allocated.
1914  *  \throw If a component index (\a i) is not valid: 
1915  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1916  *
1917  *  \if ENABLE_EXAMPLES
1918  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1919  *  \endif
1920  */
1921 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1922 {
1923   checkAllocated();
1924   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1925   std::size_t newNbOfCompo=compoIds.size();
1926   int oldNbOfCompo=getNumberOfComponents();
1927   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1928     if((*it)<0 || (*it)>=oldNbOfCompo)
1929       {
1930         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1931         throw INTERP_KERNEL::Exception(oss.str().c_str());
1932       }
1933   int nbOfTuples=getNumberOfTuples();
1934   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1935   ret->copyPartOfStringInfoFrom(*this,compoIds);
1936   const double *oldc=getConstPointer();
1937   double *nc=ret->getPointer();
1938   for(int i=0;i<nbOfTuples;i++)
1939     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1940       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1941   return ret.retn();
1942 }
1943
1944 /*!
1945  * Appends components of another array to components of \a this one, tuple by tuple.
1946  * So that the number of tuples of \a this array remains the same and the number of 
1947  * components increases.
1948  *  \param [in] other - the DataArrayDouble to append to \a this one.
1949  *  \throw If \a this is not allocated.
1950  *  \throw If \a this and \a other arrays have different number of tuples.
1951  *
1952  *  \if ENABLE_EXAMPLES
1953  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1954  *
1955  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1956  *  \endif
1957  */
1958 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1959 {
1960   checkAllocated();
1961   other->checkAllocated();
1962   int nbOfTuples=getNumberOfTuples();
1963   if(nbOfTuples!=other->getNumberOfTuples())
1964     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1965   int nbOfComp1=getNumberOfComponents();
1966   int nbOfComp2=other->getNumberOfComponents();
1967   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1968   double *w=newArr;
1969   const double *inp1=getConstPointer();
1970   const double *inp2=other->getConstPointer();
1971   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1972     {
1973       w=std::copy(inp1,inp1+nbOfComp1,w);
1974       w=std::copy(inp2,inp2+nbOfComp2,w);
1975     }
1976   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1977   std::vector<int> compIds(nbOfComp2);
1978   for(int i=0;i<nbOfComp2;i++)
1979     compIds[i]=nbOfComp1+i;
1980   copyPartOfStringInfoFrom2(compIds,*other);
1981 }
1982
1983 /*!
1984  * This method checks that all tuples in \a other are in \a this.
1985  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1986  * 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.
1987  *
1988  * \param [in] other - the array having the same number of components than \a this.
1989  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1990  * \sa DataArrayDouble::findCommonTuples
1991  */
1992 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1993 {
1994   if(!other)
1995     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1996   checkAllocated(); other->checkAllocated();
1997   if(getNumberOfComponents()!=other->getNumberOfComponents())
1998     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1999   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
2000   DataArrayInt *c=0,*ci=0;
2001   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
2002   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2003   int newNbOfTuples=-1;
2004   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
2005   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
2006   tupleIds=ret1.retn();
2007   return newNbOfTuples==getNumberOfTuples();
2008 }
2009
2010 /*!
2011  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
2012  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
2013  * distance separating two points is computed with the infinite norm.
2014  *
2015  * Indices of coincident tuples are stored in output arrays.
2016  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
2017  *
2018  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
2019  * MEDCouplingUMesh::mergeNodes().
2020  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
2021  *              considered not coincident.
2022  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2023  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
2024  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
2025  *               \a comm->getNumberOfComponents() == 1. 
2026  *               \a comm->getNumberOfTuples() == \a commIndex->back().
2027  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
2028  *               groups of (indices of) coincident tuples. Its every value is a tuple
2029  *               index where a next group of tuples begins. For example the second
2030  *               group of tuples in \a comm is described by following range of indices:
2031  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
2032  *               gives the number of groups of coincident tuples.
2033  *  \throw If \a this is not allocated.
2034  *  \throw If the number of components is not in [1,2,3,4].
2035  *
2036  *  \if ENABLE_EXAMPLES
2037  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
2038  *
2039  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
2040  *  \endif
2041  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
2042  */
2043 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
2044 {
2045   checkAllocated();
2046   int nbOfCompo=getNumberOfComponents();
2047   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
2048     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
2049
2050   int nbOfTuples=getNumberOfTuples();
2051   //
2052   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
2053   switch(nbOfCompo)
2054   {
2055     case 4:
2056       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2057       break;
2058     case 3:
2059       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2060       break;
2061     case 2:
2062       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2063       break;
2064     case 1:
2065       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2066       break;
2067     default:
2068       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2069   }
2070   comm=c.retn();
2071   commIndex=cI.retn();
2072 }
2073
2074 /*!
2075  * 
2076  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2077  *             \a nbTimes  should be at least equal to 1.
2078  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2079  * \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.
2080  */
2081 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2082 {
2083   checkAllocated();
2084   if(getNumberOfComponents()!=1)
2085     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2086   if(nbTimes<1)
2087     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2088   int nbTuples=getNumberOfTuples();
2089   const double *inPtr=getConstPointer();
2090   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2091   double *retPtr=ret->getPointer();
2092   for(int i=0;i<nbTuples;i++,inPtr++)
2093     {
2094       double val=*inPtr;
2095       for(int j=0;j<nbTimes;j++,retPtr++)
2096         *retPtr=val;
2097     }
2098   ret->copyStringInfoFrom(*this);
2099   return ret.retn();
2100 }
2101
2102 /*!
2103  * This methods returns the minimal distance between the two set of points \a this and \a other.
2104  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2105  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2106  *
2107  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2108  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2109  * \return the minimal distance between the two set of points \a this and \a other.
2110  * \sa DataArrayDouble::findClosestTupleId
2111  */
2112 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2113 {
2114   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
2115   int nbOfCompo(getNumberOfComponents());
2116   int otherNbTuples(other->getNumberOfTuples());
2117   const double *thisPt(begin()),*otherPt(other->begin());
2118   const int *part1Pt(part1->begin());
2119   double ret=std::numeric_limits<double>::max();
2120   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2121     {
2122       double tmp(0.);
2123       for(int j=0;j<nbOfCompo;j++)
2124         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2125       if(tmp<ret)
2126         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2127     }
2128   return sqrt(ret);
2129 }
2130
2131 /*!
2132  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2133  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2134  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2135  *
2136  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2137  * \sa DataArrayDouble::minimalDistanceTo
2138  */
2139 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2140 {
2141   if(!other)
2142     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2143   checkAllocated(); other->checkAllocated();
2144   int nbOfCompo=getNumberOfComponents();
2145   if(nbOfCompo!=other->getNumberOfComponents())
2146     {
2147       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2148       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2149       throw INTERP_KERNEL::Exception(oss.str().c_str());
2150     }
2151   int nbOfTuples=other->getNumberOfTuples();
2152   int thisNbOfTuples=getNumberOfTuples();
2153   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2154   double bounds[6];
2155   getMinMaxPerComponent(bounds);
2156   switch(nbOfCompo)
2157   {
2158     case 3:
2159       {
2160         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2161         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2162         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2163         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2164         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2165         break;
2166       }
2167     case 2:
2168       {
2169         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2170         double delta=std::max(xDelta,yDelta);
2171         double characSize=sqrt(delta/(double)thisNbOfTuples);
2172         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2173         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2174         break;
2175       }
2176     case 1:
2177       {
2178         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2179         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2180         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2181         break;
2182       }
2183     default:
2184       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2185   }
2186   return ret.retn();
2187 }
2188
2189 /*!
2190  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2191  * 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
2192  * how many bounding boxes in \a otherBBoxFrmt.
2193  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2194  *
2195  * \param [in] otherBBoxFrmt - It is an array .
2196  * \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.
2197  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2198  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2199  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2200  */
2201 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2202 {
2203   if(!otherBBoxFrmt)
2204     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2205   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2206     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2207   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2208   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2209     {
2210       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2211       throw INTERP_KERNEL::Exception(oss.str().c_str());
2212     }
2213   if(nbOfComp%2!=0)
2214     {
2215       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2216       throw INTERP_KERNEL::Exception(oss.str().c_str());
2217     }
2218   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2219   const double *thisBBPtr(begin());
2220   int *retPtr(ret->getPointer());
2221   switch(nbOfComp/2)
2222   {
2223     case 3:
2224       {
2225         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2226         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2227           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2228         break;
2229       }
2230     case 2:
2231       {
2232         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2233         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2234           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2235         break;
2236       }
2237     case 1:
2238       {
2239         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2240         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2241           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2242         break;
2243       }
2244     default:
2245       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2246   }
2247
2248   return ret.retn();
2249 }
2250
2251 /*!
2252  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2253  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2254  * space. The distance between tuples is computed using norm2. If several tuples are
2255  * not far each from other than \a prec, only one of them remains in the result
2256  * array. The order of tuples in the result array is same as in \a this one except
2257  * that coincident tuples are excluded.
2258  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2259  *              considered not coincident.
2260  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2261  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2262  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2263  *          is to delete using decrRef() as it is no more needed.
2264  *  \throw If \a this is not allocated.
2265  *  \throw If the number of components is not in [1,2,3,4].
2266  *
2267  *  \if ENABLE_EXAMPLES
2268  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2269  *  \endif
2270  */
2271 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2272 {
2273   checkAllocated();
2274   DataArrayInt *c0=0,*cI0=0;
2275   findCommonTuples(prec,limitTupleId,c0,cI0);
2276   MCAuto<DataArrayInt> c(c0),cI(cI0);
2277   int newNbOfTuples=-1;
2278   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2279   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2280 }
2281
2282 /*!
2283  * Copy all components in a specified order from another DataArrayDouble.
2284  * Both numerical and textual data is copied. The number of tuples in \a this and
2285  * the other array can be different.
2286  *  \param [in] a - the array to copy data from.
2287  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2288  *              to be copied.
2289  *  \throw If \a a is NULL.
2290  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2291  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2292  *
2293  *  \if ENABLE_EXAMPLES
2294  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2295  *  \endif
2296  */
2297 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2298 {
2299   if(!a)
2300     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2301   checkAllocated();
2302   copyPartOfStringInfoFrom2(compoIds,*a);
2303   std::size_t partOfCompoSz=compoIds.size();
2304   int nbOfCompo=getNumberOfComponents();
2305   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2306   const double *ac=a->getConstPointer();
2307   double *nc=getPointer();
2308   for(int i=0;i<nbOfTuples;i++)
2309     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2310       nc[nbOfCompo*i+compoIds[j]]=*ac;
2311 }
2312
2313 /*!
2314  * Copy all values from another DataArrayDouble into specified tuples and components
2315  * of \a this array. Textual data is not copied.
2316  * The tree parameters defining set of indices of tuples and components are similar to
2317  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2318  *  \param [in] a - the array to copy values from.
2319  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2320  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2321  *              are located.
2322  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2323  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2324  *  \param [in] endComp - index of the component before which the components to assign
2325  *              to are located.
2326  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2327  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2328  *              must be equal to the number of columns to assign to, else an
2329  *              exception is thrown; if \a false, then it is only required that \a
2330  *              a->getNbOfElems() equals to number of values to assign to (this condition
2331  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2332  *              values to assign to is given by following Python expression:
2333  *              \a nbTargetValues = 
2334  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2335  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2336  *  \throw If \a a is NULL.
2337  *  \throw If \a a is not allocated.
2338  *  \throw If \a this is not allocated.
2339  *  \throw If parameters specifying tuples and components to assign to do not give a
2340  *            non-empty range of increasing indices.
2341  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2342  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2343  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2344  *
2345  *  \if ENABLE_EXAMPLES
2346  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2347  *  \endif
2348  */
2349 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2350 {
2351   if(!a)
2352     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2353   const char msg[]="DataArrayDouble::setPartOfValues1";
2354   checkAllocated();
2355   a->checkAllocated();
2356   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2357   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2358   int nbComp=getNumberOfComponents();
2359   int nbOfTuples=getNumberOfTuples();
2360   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2361   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2362   bool assignTech=true;
2363   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2364     {
2365       if(strictCompoCompare)
2366         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2367     }
2368   else
2369     {
2370       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2371       assignTech=false;
2372     }
2373   const double *srcPt=a->getConstPointer();
2374   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2375   if(assignTech)
2376     {
2377       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2378         for(int j=0;j<newNbOfComp;j++,srcPt++)
2379           pt[j*stepComp]=*srcPt;
2380     }
2381   else
2382     {
2383       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2384         {
2385           const double *srcPt2=srcPt;
2386           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2387             pt[j*stepComp]=*srcPt2;
2388         }
2389     }
2390 }
2391
2392 /*!
2393  * Assign a given value to values at specified tuples and components of \a this array.
2394  * The tree parameters defining set of indices of tuples and components are similar to
2395  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2396  *  \param [in] a - the value to assign.
2397  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2398  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2399  *              are located.
2400  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2401  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2402  *  \param [in] endComp - index of the component before which the components to assign
2403  *              to are located.
2404  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2405  *  \throw If \a this is not allocated.
2406  *  \throw If parameters specifying tuples and components to assign to, do not give a
2407  *            non-empty range of increasing indices or indices are out of a valid range
2408  *            for \c this array.
2409  *
2410  *  \if ENABLE_EXAMPLES
2411  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2412  *  \endif
2413  */
2414 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2415 {
2416   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2417   checkAllocated();
2418   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2419   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2420   int nbComp=getNumberOfComponents();
2421   int nbOfTuples=getNumberOfTuples();
2422   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2423   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2424   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2425   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2426     for(int j=0;j<newNbOfComp;j++)
2427       pt[j*stepComp]=a;
2428 }
2429
2430 /*!
2431  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2432  * components of \a this array. Textual data is not copied.
2433  * The tuples and components to assign to are defined by C arrays of indices.
2434  * There are two *modes of usage*:
2435  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2436  *   of \a a is assigned to its own location within \a this array. 
2437  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2438  *   components of every specified tuple of \a this array. In this mode it is required
2439  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2440  *
2441  *  \param [in] a - the array to copy values from.
2442  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2443  *              assign values of \a a to.
2444  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2445  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2446  *              \a bgTuples <= \a pi < \a endTuples.
2447  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2448  *              assign values of \a a to.
2449  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2450  *              pointer to a component index <em>(pi)</em> varies as this: 
2451  *              \a bgComp <= \a pi < \a endComp.
2452  *  \param [in] strictCompoCompare - this parameter is checked only if the
2453  *               *mode of usage* is the first; if it is \a true (default), 
2454  *               then \a a->getNumberOfComponents() must be equal 
2455  *               to the number of specified columns, else this is not required.
2456  *  \throw If \a a is NULL.
2457  *  \throw If \a a is not allocated.
2458  *  \throw If \a this is not allocated.
2459  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2460  *         out of a valid range for \a this array.
2461  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2462  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2463  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2464  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2465  *
2466  *  \if ENABLE_EXAMPLES
2467  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2468  *  \endif
2469  */
2470 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2471 {
2472   if(!a)
2473     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2474   const char msg[]="DataArrayDouble::setPartOfValues2";
2475   checkAllocated();
2476   a->checkAllocated();
2477   int nbComp=getNumberOfComponents();
2478   int nbOfTuples=getNumberOfTuples();
2479   for(const int *z=bgComp;z!=endComp;z++)
2480     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2481   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2482   int newNbOfComp=(int)std::distance(bgComp,endComp);
2483   bool assignTech=true;
2484   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2485     {
2486       if(strictCompoCompare)
2487         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2488     }
2489   else
2490     {
2491       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2492       assignTech=false;
2493     }
2494   double *pt=getPointer();
2495   const double *srcPt=a->getConstPointer();
2496   if(assignTech)
2497     {    
2498       for(const int *w=bgTuples;w!=endTuples;w++)
2499         {
2500           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2501           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2502             {    
2503               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2504             }
2505         }
2506     }
2507   else
2508     {
2509       for(const int *w=bgTuples;w!=endTuples;w++)
2510         {
2511           const double *srcPt2=srcPt;
2512           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2513           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2514             {    
2515               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2516             }
2517         }
2518     }
2519 }
2520
2521 /*!
2522  * Assign a given value to values at specified tuples and components of \a this array.
2523  * The tuples and components to assign to are defined by C arrays of indices.
2524  *  \param [in] a - the value to assign.
2525  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2526  *              assign \a a to.
2527  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2528  *              pointer to a tuple index (\a pi) varies as this: 
2529  *              \a bgTuples <= \a pi < \a endTuples.
2530  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2531  *              assign \a a to.
2532  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2533  *              pointer to a component index (\a pi) varies as this: 
2534  *              \a bgComp <= \a pi < \a endComp.
2535  *  \throw If \a this is not allocated.
2536  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2537  *         out of a valid range for \a this array.
2538  *
2539  *  \if ENABLE_EXAMPLES
2540  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2541  *  \endif
2542  */
2543 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2544 {
2545   checkAllocated();
2546   int nbComp=getNumberOfComponents();
2547   int nbOfTuples=getNumberOfTuples();
2548   for(const int *z=bgComp;z!=endComp;z++)
2549     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2550   double *pt=getPointer();
2551   for(const int *w=bgTuples;w!=endTuples;w++)
2552     for(const int *z=bgComp;z!=endComp;z++)
2553       {
2554         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2555         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2556       }
2557 }
2558
2559 /*!
2560  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2561  * components of \a this array. Textual data is not copied.
2562  * The tuples to assign to are defined by a C array of indices.
2563  * The components to assign to are defined by three values similar to parameters of
2564  * the Python function \c range(\c start,\c stop,\c step).
2565  * There are two *modes of usage*:
2566  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2567  *   of \a a is assigned to its own location within \a this array. 
2568  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2569  *   components of every specified tuple of \a this array. In this mode it is required
2570  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2571  *
2572  *  \param [in] a - the array to copy values from.
2573  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2574  *              assign values of \a a to.
2575  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2576  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2577  *              \a bgTuples <= \a pi < \a endTuples.
2578  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2579  *  \param [in] endComp - index of the component before which the components to assign
2580  *              to are located.
2581  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2582  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2583  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2584  *               then \a a->getNumberOfComponents() must be equal 
2585  *               to the number of specified columns, else this is not required.
2586  *  \throw If \a a is NULL.
2587  *  \throw If \a a is not allocated.
2588  *  \throw If \a this is not allocated.
2589  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2590  *         \a this array.
2591  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2592  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2593  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2594  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2595  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2596  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2597  *  \throw If parameters specifying components to assign to, do not give a
2598  *            non-empty range of increasing indices or indices are out of a valid range
2599  *            for \c this array.
2600  *
2601  *  \if ENABLE_EXAMPLES
2602  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2603  *  \endif
2604  */
2605 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2606 {
2607   if(!a)
2608     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2609   const char msg[]="DataArrayDouble::setPartOfValues3";
2610   checkAllocated();
2611   a->checkAllocated();
2612   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2613   int nbComp=getNumberOfComponents();
2614   int nbOfTuples=getNumberOfTuples();
2615   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2616   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2617   bool assignTech=true;
2618   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2619     {
2620       if(strictCompoCompare)
2621         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2622     }
2623   else
2624     {
2625       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2626       assignTech=false;
2627     }
2628   double *pt=getPointer()+bgComp;
2629   const double *srcPt=a->getConstPointer();
2630   if(assignTech)
2631     {
2632       for(const int *w=bgTuples;w!=endTuples;w++)
2633         for(int j=0;j<newNbOfComp;j++,srcPt++)
2634           {
2635             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2636             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2637           }
2638     }
2639   else
2640     {
2641       for(const int *w=bgTuples;w!=endTuples;w++)
2642         {
2643           const double *srcPt2=srcPt;
2644           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2645             {
2646               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2647               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2648             }
2649         }
2650     }
2651 }
2652
2653 /*!
2654  * Assign a given value to values at specified tuples and components of \a this array.
2655  * The tuples to assign to are defined by a C array of indices.
2656  * The components to assign to are defined by three values similar to parameters of
2657  * the Python function \c range(\c start,\c stop,\c step).
2658  *  \param [in] a - the value to assign.
2659  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2660  *              assign \a a to.
2661  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2662  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2663  *              \a bgTuples <= \a pi < \a endTuples.
2664  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2665  *  \param [in] endComp - index of the component before which the components to assign
2666  *              to are located.
2667  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2668  *  \throw If \a this is not allocated.
2669  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2670  *         \a this array.
2671  *  \throw If parameters specifying components to assign to, do not give a
2672  *            non-empty range of increasing indices or indices are out of a valid range
2673  *            for \c this array.
2674  *
2675  *  \if ENABLE_EXAMPLES
2676  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2677  *  \endif
2678  */
2679 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2680 {
2681   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2682   checkAllocated();
2683   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2684   int nbComp=getNumberOfComponents();
2685   int nbOfTuples=getNumberOfTuples();
2686   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2687   double *pt=getPointer()+bgComp;
2688   for(const int *w=bgTuples;w!=endTuples;w++)
2689     for(int j=0;j<newNbOfComp;j++)
2690       {
2691         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2692         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2693       }
2694 }
2695
2696 /*!
2697  * Copy all values from another DataArrayDouble into specified tuples and components
2698  * of \a this array. Textual data is not copied.
2699  * The tree parameters defining set of indices of tuples and components are similar to
2700  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2701  *  \param [in] a - the array to copy values from.
2702  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2703  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2704  *              are located.
2705  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2706  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2707  *              assign \a a to.
2708  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2709  *              pointer to a component index (\a pi) varies as this: 
2710  *              \a bgComp <= \a pi < \a endComp.
2711  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2712  *              must be equal to the number of columns to assign to, else an
2713  *              exception is thrown; if \a false, then it is only required that \a
2714  *              a->getNbOfElems() equals to number of values to assign to (this condition
2715  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2716  *              values to assign to is given by following Python expression:
2717  *              \a nbTargetValues = 
2718  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2719  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2720  *  \throw If \a a is NULL.
2721  *  \throw If \a a is not allocated.
2722  *  \throw If \a this is not allocated.
2723  *  \throw If parameters specifying tuples and components to assign to do not give a
2724  *            non-empty range of increasing indices.
2725  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2726  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2727  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2728  *
2729  */
2730 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2731 {
2732   if(!a)
2733     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2734   const char msg[]="DataArrayDouble::setPartOfValues4";
2735   checkAllocated();
2736   a->checkAllocated();
2737   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2738   int newNbOfComp=(int)std::distance(bgComp,endComp);
2739   int nbComp=getNumberOfComponents();
2740   for(const int *z=bgComp;z!=endComp;z++)
2741     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2742   int nbOfTuples=getNumberOfTuples();
2743   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2744   bool assignTech=true;
2745   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2746     {
2747       if(strictCompoCompare)
2748         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2749     }
2750   else
2751     {
2752       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2753       assignTech=false;
2754     }
2755   const double *srcPt=a->getConstPointer();
2756   double *pt=getPointer()+bgTuples*nbComp;
2757   if(assignTech)
2758     {
2759       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2760         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2761           pt[*z]=*srcPt;
2762     }
2763   else
2764     {
2765       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2766         {
2767           const double *srcPt2=srcPt;
2768           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2769             pt[*z]=*srcPt2;
2770         }
2771     }
2772 }
2773
2774 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2775 {
2776   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2777   checkAllocated();
2778   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2779   int nbComp=getNumberOfComponents();
2780   for(const int *z=bgComp;z!=endComp;z++)
2781     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2782   int nbOfTuples=getNumberOfTuples();
2783   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2784   double *pt=getPointer()+bgTuples*nbComp;
2785   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2786     for(const int *z=bgComp;z!=endComp;z++)
2787       pt[*z]=a;
2788 }
2789
2790 /*!
2791  * Copy some tuples from another DataArrayDouble into specified tuples
2792  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2793  * components.
2794  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2795  * All components of selected tuples are copied.
2796  *  \param [in] a - the array to copy values from.
2797  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2798  *              target tuples of \a this. \a tuplesSelec has two components, and the
2799  *              first component specifies index of the source tuple and the second
2800  *              one specifies index of the target tuple.
2801  *  \throw If \a this is not allocated.
2802  *  \throw If \a a is NULL.
2803  *  \throw If \a a is not allocated.
2804  *  \throw If \a tuplesSelec is NULL.
2805  *  \throw If \a tuplesSelec is not allocated.
2806  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2807  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2808  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2809  *         the corresponding (\a this or \a a) array.
2810  */
2811 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2812 {
2813   if(!a || !tuplesSelec)
2814     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2815   checkAllocated();
2816   a->checkAllocated();
2817   tuplesSelec->checkAllocated();
2818   int nbOfComp=getNumberOfComponents();
2819   if(nbOfComp!=a->getNumberOfComponents())
2820     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2821   if(tuplesSelec->getNumberOfComponents()!=2)
2822     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2823   int thisNt=getNumberOfTuples();
2824   int aNt=a->getNumberOfTuples();
2825   double *valsToSet=getPointer();
2826   const double *valsSrc=a->getConstPointer();
2827   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2828     {
2829       if(tuple[1]>=0 && tuple[1]<aNt)
2830         {
2831           if(tuple[0]>=0 && tuple[0]<thisNt)
2832             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2833           else
2834             {
2835               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2836               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2837               throw INTERP_KERNEL::Exception(oss.str().c_str());
2838             }
2839         }
2840       else
2841         {
2842           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2843           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2844           throw INTERP_KERNEL::Exception(oss.str().c_str());
2845         }
2846     }
2847 }
2848
2849 /*!
2850  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2851  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2852  * components.
2853  * The tuples to assign to are defined by index of the first tuple, and
2854  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2855  * The tuples to copy are defined by values of a DataArrayInt.
2856  * All components of selected tuples are copied.
2857  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2858  *              values to.
2859  *  \param [in] aBase - the array to copy values from.
2860  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2861  *  \throw If \a this is not allocated.
2862  *  \throw If \a aBase is NULL.
2863  *  \throw If \a aBase is not allocated.
2864  *  \throw If \a tuplesSelec is NULL.
2865  *  \throw If \a tuplesSelec is not allocated.
2866  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2867  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2868  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2869  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2870  *         \a aBase array.
2871  */
2872 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2873 {
2874   if(!aBase || !tuplesSelec)
2875     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2876   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2877   if(!a)
2878     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2879   checkAllocated();
2880   a->checkAllocated();
2881   tuplesSelec->checkAllocated();
2882   int nbOfComp=getNumberOfComponents();
2883   if(nbOfComp!=a->getNumberOfComponents())
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2885   if(tuplesSelec->getNumberOfComponents()!=1)
2886     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2887   int thisNt=getNumberOfTuples();
2888   int aNt=a->getNumberOfTuples();
2889   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2890   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2891   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2892     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2893   const double *valsSrc=a->getConstPointer();
2894   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2895     {
2896       if(*tuple>=0 && *tuple<aNt)
2897         {
2898           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2899         }
2900       else
2901         {
2902           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2903           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2904           throw INTERP_KERNEL::Exception(oss.str().c_str());
2905         }
2906     }
2907 }
2908
2909 /*!
2910  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2911  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2912  * components.
2913  * The tuples to copy are defined by three values similar to parameters of
2914  * the Python function \c range(\c start,\c stop,\c step).
2915  * The tuples to assign to are defined by index of the first tuple, and
2916  * their number is defined by number of tuples to copy.
2917  * All components of selected tuples are copied.
2918  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2919  *              values to.
2920  *  \param [in] aBase - the array to copy values from.
2921  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2922  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2923  *              are located.
2924  *  \param [in] step - index increment to get index of the next tuple to copy.
2925  *  \throw If \a this is not allocated.
2926  *  \throw If \a aBase is NULL.
2927  *  \throw If \a aBase is not allocated.
2928  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2929  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2930  *  \throw If parameters specifying tuples to copy, do not give a
2931  *            non-empty range of increasing indices or indices are out of a valid range
2932  *            for the array \a aBase.
2933  */
2934 void DataArrayDouble::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2935 {
2936   if(!aBase)
2937     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
2938   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2939   if(!a)
2940     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !");
2941   checkAllocated();
2942   a->checkAllocated();
2943   int nbOfComp=getNumberOfComponents();
2944   const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice";
2945   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2946   if(nbOfComp!=a->getNumberOfComponents())
2947     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
2948   int thisNt=getNumberOfTuples();
2949   int aNt=a->getNumberOfTuples();
2950   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2951   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2952     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
2953   if(end2>aNt)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
2955   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2956   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2957     {
2958       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2959     }
2960 }
2961
2962 /*!
2963  * Returns a value located at specified tuple and component.
2964  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2965  * parameters is checked. So this method is safe but expensive if used to go through
2966  * all values of \a this.
2967  *  \param [in] tupleId - index of tuple of interest.
2968  *  \param [in] compoId - index of component of interest.
2969  *  \return double - value located by \a tupleId and \a compoId.
2970  *  \throw If \a this is not allocated.
2971  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2972  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2973  */
2974 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2975 {
2976   checkAllocated();
2977   if(tupleId<0 || tupleId>=getNumberOfTuples())
2978     {
2979       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2980       throw INTERP_KERNEL::Exception(oss.str().c_str());
2981     }
2982   if(compoId<0 || compoId>=getNumberOfComponents())
2983     {
2984       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2985       throw INTERP_KERNEL::Exception(oss.str().c_str());
2986     }
2987   return _mem[tupleId*_info_on_compo.size()+compoId];
2988 }
2989
2990 /*!
2991  * Returns the first value of \a this. 
2992  *  \return double - the last value of \a this array.
2993  *  \throw If \a this is not allocated.
2994  *  \throw If \a this->getNumberOfComponents() != 1.
2995  *  \throw If \a this->getNumberOfTuples() < 1.
2996  */
2997 double DataArrayDouble::front() const
2998 {
2999   checkAllocated();
3000   if(getNumberOfComponents()!=1)
3001     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
3002   int nbOfTuples=getNumberOfTuples();
3003   if(nbOfTuples<1)
3004     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
3005   return *(getConstPointer());
3006 }
3007
3008 /*!
3009  * Returns the last value of \a this. 
3010  *  \return double - the last value of \a this array.
3011  *  \throw If \a this is not allocated.
3012  *  \throw If \a this->getNumberOfComponents() != 1.
3013  *  \throw If \a this->getNumberOfTuples() < 1.
3014  */
3015 double DataArrayDouble::back() const
3016 {
3017   checkAllocated();
3018   if(getNumberOfComponents()!=1)
3019     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
3020   int nbOfTuples=getNumberOfTuples();
3021   if(nbOfTuples<1)
3022     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
3023   return *(getConstPointer()+nbOfTuples-1);
3024 }
3025
3026 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
3027 {
3028   if(newArray!=arrayToSet)
3029     {
3030       if(arrayToSet)
3031         arrayToSet->decrRef();
3032       arrayToSet=newArray;
3033       if(arrayToSet)
3034         arrayToSet->incrRef();
3035     }
3036 }
3037
3038 /*!
3039  * Sets a C array to be used as raw data of \a this. The previously set info
3040  *  of components is retained and re-sized. 
3041  * For more info see \ref MEDCouplingArraySteps1.
3042  *  \param [in] array - the C array to be used as raw data of \a this.
3043  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
3044  *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
3045  *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
3046  *                     \c free(\c array ) will be called.
3047  *  \param [in] nbOfTuple - new number of tuples in \a this.
3048  *  \param [in] nbOfCompo - new number of components in \a this.
3049  */
3050 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
3051 {
3052   _info_on_compo.resize(nbOfCompo);
3053   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
3054   declareAsNew();
3055 }
3056
3057 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3058 {
3059   _info_on_compo.resize(nbOfCompo);
3060   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3061   declareAsNew();
3062 }
3063
3064 /*!
3065  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3066  * is thrown.
3067  * \throw If zero is found in \a this array.
3068  */
3069 void DataArrayDouble::checkNoNullValues() const
3070 {
3071   const double *tmp=getConstPointer();
3072   std::size_t nbOfElems=getNbOfElems();
3073   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3074   if(where!=tmp+nbOfElems)
3075     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3076 }
3077
3078 /*!
3079  * Computes minimal and maximal value in each component. An output array is filled
3080  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3081  * enough memory before calling this method.
3082  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3083  *               It is filled as follows:<br>
3084  *               \a bounds[0] = \c min_of_component_0 <br>
3085  *               \a bounds[1] = \c max_of_component_0 <br>
3086  *               \a bounds[2] = \c min_of_component_1 <br>
3087  *               \a bounds[3] = \c max_of_component_1 <br>
3088  *               ...
3089  */
3090 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3091 {
3092   checkAllocated();
3093   int dim=getNumberOfComponents();
3094   for (int idim=0; idim<dim; idim++)
3095     {
3096       bounds[idim*2]=std::numeric_limits<double>::max();
3097       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3098     } 
3099   const double *ptr=getConstPointer();
3100   int nbOfTuples=getNumberOfTuples();
3101   for(int i=0;i<nbOfTuples;i++)
3102     {
3103       for(int idim=0;idim<dim;idim++)
3104         {
3105           if(bounds[idim*2]>ptr[i*dim+idim])
3106             {
3107               bounds[idim*2]=ptr[i*dim+idim];
3108             }
3109           if(bounds[idim*2+1]<ptr[i*dim+idim])
3110             {
3111               bounds[idim*2+1]=ptr[i*dim+idim];
3112             }
3113         }
3114     }
3115 }
3116
3117 /*!
3118  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3119  * to store both the min and max per component of each tuples. 
3120  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3121  *
3122  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3123  *
3124  * \throw If \a this is not allocated yet.
3125  */
3126 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3127 {
3128   checkAllocated();
3129   const double *dataPtr=getConstPointer();
3130   int nbOfCompo=getNumberOfComponents();
3131   int nbTuples=getNumberOfTuples();
3132   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
3133   bbox->alloc(nbTuples,2*nbOfCompo);
3134   double *bboxPtr=bbox->getPointer();
3135   for(int i=0;i<nbTuples;i++)
3136     {
3137       for(int j=0;j<nbOfCompo;j++)
3138         {
3139           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3140           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3141         }
3142     }
3143   return bbox.retn();
3144 }
3145
3146 /*!
3147  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3148  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3149  * 
3150  * \param [in] other a DataArrayDouble having same number of components than \a this.
3151  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3152  * \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.
3153  *             \a cI allows to extract information in \a c.
3154  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3155  *
3156  * \throw In case of:
3157  *  - \a this is not allocated
3158  *  - \a other is not allocated or null
3159  *  - \a this and \a other do not have the same number of components
3160  *  - if number of components of \a this is not in [1,2,3]
3161  *
3162  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3163  */
3164 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3165 {
3166   if(!other)
3167     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3168   checkAllocated();
3169   other->checkAllocated();
3170   int nbOfCompo=getNumberOfComponents();
3171   int otherNbOfCompo=other->getNumberOfComponents();
3172   if(nbOfCompo!=otherNbOfCompo)
3173     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3174   int nbOfTuplesOther=other->getNumberOfTuples();
3175   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3176   switch(nbOfCompo)
3177   {
3178     case 3:
3179       {
3180         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3181         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3182         break;
3183       }
3184     case 2:
3185       {
3186         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3187         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3188         break;
3189       }
3190     case 1:
3191       {
3192         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3193         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3194         break;
3195       }
3196     default:
3197       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3198   }
3199   c=cArr.retn(); cI=cIArr.retn();
3200 }
3201
3202 /*!
3203  * 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
3204  * around origin of 'radius' 1.
3205  * 
3206  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3207  */
3208 void DataArrayDouble::recenterForMaxPrecision(double eps)
3209 {
3210   checkAllocated();
3211   int dim=getNumberOfComponents();
3212   std::vector<double> bounds(2*dim);
3213   getMinMaxPerComponent(&bounds[0]);
3214   for(int i=0;i<dim;i++)
3215     {
3216       double delta=bounds[2*i+1]-bounds[2*i];
3217       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3218       if(delta>eps)
3219         applyLin(1./delta,-offset/delta,i);
3220       else
3221         applyLin(1.,-offset,i);
3222     }
3223 }
3224
3225 /*!
3226  * Returns the maximal value and its location within \a this one-dimensional array.
3227  *  \param [out] tupleId - index of the tuple holding the maximal value.
3228  *  \return double - the maximal value among all values of \a this array.
3229  *  \throw If \a this->getNumberOfComponents() != 1
3230  *  \throw If \a this->getNumberOfTuples() < 1
3231  */
3232 double DataArrayDouble::getMaxValue(int& tupleId) const
3233 {
3234   checkAllocated();
3235   if(getNumberOfComponents()!=1)
3236     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 !");
3237   int nbOfTuples=getNumberOfTuples();
3238   if(nbOfTuples<=0)
3239     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3240   const double *vals=getConstPointer();
3241   const double *loc=std::max_element(vals,vals+nbOfTuples);
3242   tupleId=(int)std::distance(vals,loc);
3243   return *loc;
3244 }
3245
3246 /*!
3247  * Returns the maximal value within \a this array that is allowed to have more than
3248  *  one component.
3249  *  \return double - the maximal value among all values of \a this array.
3250  *  \throw If \a this is not allocated.
3251  */
3252 double DataArrayDouble::getMaxValueInArray() const
3253 {
3254   checkAllocated();
3255   const double *loc=std::max_element(begin(),end());
3256   return *loc;
3257 }
3258
3259 /*!
3260  * Returns the maximal value and all its locations within \a this one-dimensional array.
3261  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3262  *               tuples holding the maximal value. The caller is to delete it using
3263  *               decrRef() as it is no more needed.
3264  *  \return double - the maximal value among all values of \a this array.
3265  *  \throw If \a this->getNumberOfComponents() != 1
3266  *  \throw If \a this->getNumberOfTuples() < 1
3267  */
3268 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3269 {
3270   int tmp;
3271   tupleIds=0;
3272   double ret=getMaxValue(tmp);
3273   tupleIds=findIdsInRange(ret,ret);
3274   return ret;
3275 }
3276
3277 /*!
3278  * Returns the minimal value and its location within \a this one-dimensional array.
3279  *  \param [out] tupleId - index of the tuple holding the minimal value.
3280  *  \return double - the minimal value among all values of \a this array.
3281  *  \throw If \a this->getNumberOfComponents() != 1
3282  *  \throw If \a this->getNumberOfTuples() < 1
3283  */
3284 double DataArrayDouble::getMinValue(int& tupleId) const
3285 {
3286   checkAllocated();
3287   if(getNumberOfComponents()!=1)
3288     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3289   int nbOfTuples=getNumberOfTuples();
3290   if(nbOfTuples<=0)
3291     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3292   const double *vals=getConstPointer();
3293   const double *loc=std::min_element(vals,vals+nbOfTuples);
3294   tupleId=(int)std::distance(vals,loc);
3295   return *loc;
3296 }
3297
3298 /*!
3299  * Returns the minimal value within \a this array that is allowed to have more than
3300  *  one component.
3301  *  \return double - the minimal value among all values of \a this array.
3302  *  \throw If \a this is not allocated.
3303  */
3304 double DataArrayDouble::getMinValueInArray() const
3305 {
3306   checkAllocated();
3307   const double *loc=std::min_element(begin(),end());
3308   return *loc;
3309 }
3310
3311 /*!
3312  * Returns the minimal value and all its locations within \a this one-dimensional array.
3313  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3314  *               tuples holding the minimal value. The caller is to delete it using
3315  *               decrRef() as it is no more needed.
3316  *  \return double - the minimal value among all values of \a this array.
3317  *  \throw If \a this->getNumberOfComponents() != 1
3318  *  \throw If \a this->getNumberOfTuples() < 1
3319  */
3320 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3321 {
3322   int tmp;
3323   tupleIds=0;
3324   double ret=getMinValue(tmp);
3325   tupleIds=findIdsInRange(ret,ret);
3326   return ret;
3327 }
3328
3329 /*!
3330  * 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.
3331  * This method only works for single component array.
3332  *
3333  * \return a value in [ 0, \c this->getNumberOfTuples() )
3334  *
3335  * \throw If \a this is not allocated
3336  *
3337  */
3338 int DataArrayDouble::count(double value, double eps) const
3339 {
3340   int ret=0;
3341   checkAllocated();
3342   if(getNumberOfComponents()!=1)
3343     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3344   const double *vals=begin();
3345   int nbOfTuples=getNumberOfTuples();
3346   for(int i=0;i<nbOfTuples;i++,vals++)
3347     if(fabs(*vals-value)<=eps)
3348       ret++;
3349   return ret;
3350 }
3351
3352 /*!
3353  * Returns the average value of \a this one-dimensional array.
3354  *  \return double - the average value over all values of \a this array.
3355  *  \throw If \a this->getNumberOfComponents() != 1
3356  *  \throw If \a this->getNumberOfTuples() < 1
3357  */
3358 double DataArrayDouble::getAverageValue() const
3359 {
3360   if(getNumberOfComponents()!=1)
3361     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3362   int nbOfTuples=getNumberOfTuples();
3363   if(nbOfTuples<=0)
3364     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3365   const double *vals=getConstPointer();
3366   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3367   return ret/nbOfTuples;
3368 }
3369
3370 /*!
3371  * Returns the Euclidean norm of the vector defined by \a this array.
3372  *  \return double - the value of the Euclidean norm, i.e.
3373  *          the square root of the inner product of vector.
3374  *  \throw If \a this is not allocated.
3375  */
3376 double DataArrayDouble::norm2() const
3377 {
3378   checkAllocated();
3379   double ret=0.;
3380   std::size_t nbOfElems=getNbOfElems();
3381   const double *pt=getConstPointer();
3382   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3383     ret+=(*pt)*(*pt);
3384   return sqrt(ret);
3385 }
3386
3387 /*!
3388  * Returns the maximum norm of the vector defined by \a this array.
3389  * This method works even if the number of components is diferent from one.
3390  * If the number of elements in \a this is 0, -1. is returned.
3391  *  \return double - the value of the maximum norm, i.e.
3392  *          the maximal absolute value among values of \a this array (whatever its number of components).
3393  *  \throw If \a this is not allocated.
3394  */
3395 double DataArrayDouble::normMax() const
3396 {
3397   checkAllocated();
3398   double ret(-1.);
3399   std::size_t nbOfElems(getNbOfElems());
3400   const double *pt(getConstPointer());
3401   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3402     {
3403       double val(std::abs(*pt));
3404       if(val>ret)
3405         ret=val;
3406     }
3407   return ret;
3408 }
3409
3410 /*!
3411  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3412  * This method works even if the number of components is diferent from one.
3413  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3414  *  \return double - the value of the minimum norm, i.e.
3415  *          the minimal absolute value among values of \a this array (whatever its number of components).
3416  *  \throw If \a this is not allocated.
3417  */
3418 double DataArrayDouble::normMin() const
3419 {
3420   checkAllocated();
3421   double ret(std::numeric_limits<double>::max());
3422   std::size_t nbOfElems(getNbOfElems());
3423   const double *pt(getConstPointer());
3424   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3425     {
3426       double val(std::abs(*pt));
3427       if(val<ret)
3428         ret=val;
3429     }
3430   return ret;
3431 }
3432
3433 /*!
3434  * Accumulates values of each component of \a this array.
3435  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3436  *         by the caller, that is filled by this method with sum value for each
3437  *         component.
3438  *  \throw If \a this is not allocated.
3439  */
3440 void DataArrayDouble::accumulate(double *res) const
3441 {
3442   checkAllocated();
3443   const double *ptr=getConstPointer();
3444   int nbTuple=getNumberOfTuples();
3445   int nbComps=getNumberOfComponents();
3446   std::fill(res,res+nbComps,0.);
3447   for(int i=0;i<nbTuple;i++)
3448     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3449 }
3450
3451 /*!
3452  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3453  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3454  *
3455  *
3456  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3457  * \a tupleEnd. If not an exception will be thrown.
3458  *
3459  * \param [in] tupleBg start pointer (included) of input external tuple
3460  * \param [in] tupleEnd end pointer (not included) of input external tuple
3461  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3462  * \return the min distance.
3463  * \sa MEDCouplingUMesh::distanceToPoint
3464  */
3465 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3466 {
3467   checkAllocated();
3468   int nbTuple=getNumberOfTuples();
3469   int nbComps=getNumberOfComponents();
3470   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3471     { 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()); }
3472   if(nbTuple==0)
3473     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3474   double ret0=std::numeric_limits<double>::max();
3475   tupleId=-1;
3476   const double *work=getConstPointer();
3477   for(int i=0;i<nbTuple;i++)
3478     {
3479       double val=0.;
3480       for(int j=0;j<nbComps;j++,work++) 
3481         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3482       if(val>=ret0)
3483         continue;
3484       else
3485         { ret0=val; tupleId=i; }
3486     }
3487   return sqrt(ret0);
3488 }
3489
3490 /*!
3491  * Accumulate values of the given component of \a this array.
3492  *  \param [in] compId - the index of the component of interest.
3493  *  \return double - a sum value of \a compId-th component.
3494  *  \throw If \a this is not allocated.
3495  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3496  *         not respected.
3497  */
3498 double DataArrayDouble::accumulate(int compId) const
3499 {
3500   checkAllocated();
3501   const double *ptr=getConstPointer();
3502   int nbTuple=getNumberOfTuples();
3503   int nbComps=getNumberOfComponents();
3504   if(compId<0 || compId>=nbComps)
3505     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3506   double ret=0.;
3507   for(int i=0;i<nbTuple;i++)
3508     ret+=ptr[i*nbComps+compId];
3509   return ret;
3510 }
3511
3512 /*!
3513  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3514  * The returned array will have same number of components than \a this and number of tuples equal to
3515  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3516  *
3517  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3518  * 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.
3519  *
3520  * \param [in] bgOfIndex - begin (included) of the input index array.
3521  * \param [in] endOfIndex - end (excluded) of the input index array.
3522  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3523  * 
3524  * \throw If bgOfIndex or end is NULL.
3525  * \throw If input index array is not ascendingly sorted.
3526  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3527  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3528  */
3529 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3530 {
3531   if(!bgOfIndex || !endOfIndex)
3532     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3533   checkAllocated();
3534   int nbCompo=getNumberOfComponents();
3535   int nbOfTuples=getNumberOfTuples();
3536   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3537   if(sz<1)
3538     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3539   sz--;
3540   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3541   const int *w=bgOfIndex;
3542   if(*w<0 || *w>=nbOfTuples)
3543     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3544   const double *srcPt=begin()+(*w)*nbCompo;
3545   double *tmp=ret->getPointer();
3546   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3547     {
3548       std::fill(tmp,tmp+nbCompo,0.);
3549       if(w[1]>=w[0])
3550         {
3551           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3552             {
3553               if(j>=0 && j<nbOfTuples)
3554                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3555               else
3556                 {
3557                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3558                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3559                 }
3560             }
3561         }
3562       else
3563         {
3564           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3565           throw INTERP_KERNEL::Exception(oss.str().c_str());
3566         }
3567     }
3568   ret->copyStringInfoFrom(*this);
3569   return ret.retn();
3570 }
3571
3572 /*!
3573  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3574  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3575  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3576  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3577  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3578  *          is to delete this array using decrRef() as it is no more needed. The array
3579  *          does not contain any textual info on components.
3580  *  \throw If \a this->getNumberOfComponents() != 2.
3581  */
3582 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3583 {
3584   checkAllocated();
3585   int nbOfComp(getNumberOfComponents());
3586   if(nbOfComp!=2)
3587     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3588   int nbOfTuple(getNumberOfTuples());
3589   DataArrayDouble *ret(DataArrayDouble::New());
3590   ret->alloc(nbOfTuple,2);
3591   double *w(ret->getPointer());
3592   const double *wIn(getConstPointer());
3593   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3594     {
3595       w[0]=wIn[0]*cos(wIn[1]);
3596       w[1]=wIn[0]*sin(wIn[1]);
3597     }
3598   return ret;
3599 }
3600
3601 /*!
3602  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3603  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3604  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3605  * the Cylindrical CS.
3606  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3607  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3608  *          on the third component is copied from \a this array. The caller
3609  *          is to delete this array using decrRef() as it is no more needed. 
3610  *  \throw If \a this->getNumberOfComponents() != 3.
3611  */
3612 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3613 {
3614   checkAllocated();
3615   int nbOfComp(getNumberOfComponents());
3616   if(nbOfComp!=3)
3617     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3618   int nbOfTuple(getNumberOfTuples());
3619   DataArrayDouble *ret(DataArrayDouble::New());
3620   ret->alloc(getNumberOfTuples(),3);
3621   double *w(ret->getPointer());
3622   const double *wIn(getConstPointer());
3623   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3624     {
3625       w[0]=wIn[0]*cos(wIn[1]);
3626       w[1]=wIn[0]*sin(wIn[1]);
3627       w[2]=wIn[2];
3628     }
3629   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3630   return ret;
3631 }
3632
3633 /*!
3634  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3635  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3636  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3637  * point in the Cylindrical CS.
3638  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3639  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3640  *          on the third component is copied from \a this array. The caller
3641  *          is to delete this array using decrRef() as it is no more needed.
3642  *  \throw If \a this->getNumberOfComponents() != 3.
3643  */
3644 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3645 {
3646   checkAllocated();
3647   int nbOfComp(getNumberOfComponents());
3648   if(nbOfComp!=3)
3649     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3650   int nbOfTuple(getNumberOfTuples());
3651   DataArrayDouble *ret(DataArrayDouble::New());
3652   ret->alloc(getNumberOfTuples(),3);
3653   double *w(ret->getPointer());
3654   const double *wIn(getConstPointer());
3655   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3656     {
3657       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3658       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3659       w[2]=wIn[0]*cos(wIn[1]);
3660     }
3661   return ret;
3662 }
3663
3664 /*!
3665  * This method returns a new array containing the same number of tuples than \a this. To do this, this method needs \a at parameter to specify the convention of \a this.
3666  * All the tuples of the returned array will be in cartesian sense. So if \a at equals to AX_CART the returned array is basically a deep copy of \a this.
3667  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
3668  *
3669  * \param [in] atOfThis - The axis type of \a this.
3670  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
3671  */
3672 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
3673 {
3674   checkAllocated();
3675   int nbOfComp(getNumberOfComponents());
3676   MCAuto<DataArrayDouble> ret;
3677   switch(atOfThis)
3678     {
3679     case AX_CART:
3680       ret=deepCopy();
3681     case AX_CYL:
3682       if(nbOfComp==3)
3683         {
3684           ret=fromCylToCart();
3685           break;
3686         }
3687       if(nbOfComp==2)
3688         {
3689           ret=fromPolarToCart();
3690           break;
3691         }
3692       else
3693         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3694     case AX_SPHER:
3695       if(nbOfComp==3)
3696         {
3697           ret=fromSpherToCart();
3698           break;
3699         }
3700       if(nbOfComp==2)
3701         {
3702           ret=fromPolarToCart();
3703           break;
3704         }
3705       else
3706         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3707     default:
3708       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
3709     }
3710   ret->copyStringInfoFrom(*this);
3711   return ret.retn();
3712 }
3713
3714 /*!
3715  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3716  * array contating 6 components.
3717  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3718  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3719  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3720  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3721  *  \throw If \a this->getNumberOfComponents() != 6.
3722  */
3723 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3724 {
3725   checkAllocated();
3726   int nbOfComp(getNumberOfComponents());
3727   if(nbOfComp!=6)
3728     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3729   DataArrayDouble *ret=DataArrayDouble::New();
3730   int nbOfTuple=getNumberOfTuples();
3731   ret->alloc(nbOfTuple,1);
3732   const double *src=getConstPointer();
3733   double *dest=ret->getPointer();
3734   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3735     *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];
3736   return ret;
3737 }
3738
3739 /*!
3740  * Computes the determinant of every square matrix defined by the tuple of \a this
3741  * array, which contains either 4, 6 or 9 components. The case of 6 components
3742  * corresponds to that of the upper triangular matrix.
3743  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3744  *          is the determinant of matrix of the corresponding tuple of \a this array.
3745  *          The caller is to delete this result array using decrRef() as it is no more
3746  *          needed. 
3747  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3748  */
3749 DataArrayDouble *DataArrayDouble::determinant() const
3750 {
3751   checkAllocated();
3752   DataArrayDouble *ret=DataArrayDouble::New();
3753   int nbOfTuple=getNumberOfTuples();
3754   ret->alloc(nbOfTuple,1);
3755   const double *src=getConstPointer();
3756   double *dest=ret->getPointer();
3757   switch(getNumberOfComponents())
3758   {
3759     case 6:
3760       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3761         *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];
3762       return ret;
3763     case 4:
3764       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3765         *dest=src[0]*src[3]-src[1]*src[2];
3766       return ret;
3767     case 9:
3768       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3769         *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];
3770       return ret;
3771     default:
3772       ret->decrRef();
3773       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3774   }
3775 }
3776
3777 /*!
3778  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3779  * \a this array, which contains 6 components.
3780  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3781  *          components, whose each tuple contains the eigenvalues of the matrix of
3782  *          corresponding tuple of \a this array. 
3783  *          The caller is to delete this result array using decrRef() as it is no more
3784  *          needed. 
3785  *  \throw If \a this->getNumberOfComponents() != 6.
3786  */
3787 DataArrayDouble *DataArrayDouble::eigenValues() const
3788 {
3789   checkAllocated();
3790   int nbOfComp=getNumberOfComponents();
3791   if(nbOfComp!=6)
3792     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3793   DataArrayDouble *ret=DataArrayDouble::New();
3794   int nbOfTuple=getNumberOfTuples();
3795   ret->alloc(nbOfTuple,3);
3796   const double *src=getConstPointer();
3797   double *dest=ret->getPointer();
3798   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3799     INTERP_KERNEL::computeEigenValues6(src,dest);
3800   return ret;
3801 }
3802
3803 /*!
3804  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3805  * \a this array, which contains 6 components.
3806  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3807  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3808  *          corresponding tuple of \a this array.
3809  *          The caller is to delete this result array using decrRef() as it is no more
3810  *          needed.
3811  *  \throw If \a this->getNumberOfComponents() != 6.
3812  */
3813 DataArrayDouble *DataArrayDouble::eigenVectors() const
3814 {
3815   checkAllocated();
3816   int nbOfComp=getNumberOfComponents();
3817   if(nbOfComp!=6)
3818     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3819   DataArrayDouble *ret=DataArrayDouble::New();
3820   int nbOfTuple=getNumberOfTuples();
3821   ret->alloc(nbOfTuple,9);
3822   const double *src=getConstPointer();
3823   double *dest=ret->getPointer();
3824   for(int i=0;i<nbOfTuple;i++,src+=6)
3825     {
3826       double tmp[3];
3827       INTERP_KERNEL::computeEigenValues6(src,tmp);
3828       for(int j=0;j<3;j++,dest+=3)
3829         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3830     }
3831   return ret;
3832 }
3833
3834 /*!
3835  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3836  * array, which contains either 4, 6 or 9 components. The case of 6 components
3837  * corresponds to that of the upper triangular matrix.
3838  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3839  *          same number of components as \a this one, whose each tuple is the inverse
3840  *          matrix of the matrix of corresponding tuple of \a this array. 
3841  *          The caller is to delete this result array using decrRef() as it is no more
3842  *          needed. 
3843  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3844  */
3845 DataArrayDouble *DataArrayDouble::inverse() const
3846 {
3847   checkAllocated();
3848   int nbOfComp=getNumberOfComponents();
3849   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3850     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3851   DataArrayDouble *ret=DataArrayDouble::New();
3852   int nbOfTuple=getNumberOfTuples();
3853   ret->alloc(nbOfTuple,nbOfComp);
3854   const double *src=getConstPointer();
3855   double *dest=ret->getPointer();
3856   if(nbOfComp==6)
3857     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3858       {
3859         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];
3860         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3861         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3862         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3863         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3864         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3865         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3866       }
3867   else if(nbOfComp==4)
3868     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3869       {
3870         double det=src[0]*src[3]-src[1]*src[2];
3871         dest[0]=src[3]/det;
3872         dest[1]=-src[1]/det;
3873         dest[2]=-src[2]/det;
3874         dest[3]=src[0]/det;
3875       }
3876   else
3877     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3878       {
3879         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];
3880         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3881         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3882         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3883         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3884         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3885         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3886         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3887         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3888         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3889       }
3890   return ret;
3891 }
3892
3893 /*!
3894  * Computes the trace of every matrix defined by the tuple of \a this
3895  * array, which contains either 4, 6 or 9 components. The case of 6 components
3896  * corresponds to that of the upper triangular matrix.
3897  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3898  *          1 component, whose each tuple is the trace of
3899  *          the matrix of corresponding tuple of \a this array. 
3900  *          The caller is to delete this result array using decrRef() as it is no more
3901  *          needed. 
3902  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3903  */
3904 DataArrayDouble *DataArrayDouble::trace() const
3905 {
3906   checkAllocated();
3907   int nbOfComp=getNumberOfComponents();
3908   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3909     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3910   DataArrayDouble *ret=DataArrayDouble::New();
3911   int nbOfTuple=getNumberOfTuples();
3912   ret->alloc(nbOfTuple,1);
3913   const double *src=getConstPointer();
3914   double *dest=ret->getPointer();
3915   if(nbOfComp==6)
3916     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3917       *dest=src[0]+src[1]+src[2];
3918   else if(nbOfComp==4)
3919     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3920       *dest=src[0]+src[3];
3921   else
3922     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3923       *dest=src[0]+src[4]+src[8];
3924   return ret;
3925 }
3926
3927 /*!
3928  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3929  * \a this array, which contains 6 components.
3930  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3931  *          same number of components and tuples as \a this array.
3932  *          The caller is to delete this result array using decrRef() as it is no more
3933  *          needed.
3934  *  \throw If \a this->getNumberOfComponents() != 6.
3935  */
3936 DataArrayDouble *DataArrayDouble::deviator() const
3937 {
3938   checkAllocated();
3939   int nbOfComp=getNumberOfComponents();
3940   if(nbOfComp!=6)
3941     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3942   DataArrayDouble *ret=DataArrayDouble::New();
3943   int nbOfTuple=getNumberOfTuples();
3944   ret->alloc(nbOfTuple,6);
3945   const double *src=getConstPointer();
3946   double *dest=ret->getPointer();
3947   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3948     {
3949       double tr=(src[0]+src[1]+src[2])/3.;
3950       dest[0]=src[0]-tr;
3951       dest[1]=src[1]-tr;
3952       dest[2]=src[2]-tr;
3953       dest[3]=src[3];
3954       dest[4]=src[4];
3955       dest[5]=src[5];
3956     }
3957   return ret;
3958 }
3959
3960 /*!
3961  * Computes the magnitude of every vector defined by the tuple of
3962  * \a this array.
3963  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3964  *          same number of tuples as \a this array and one component.
3965  *          The caller is to delete this result array using decrRef() as it is no more
3966  *          needed.
3967  *  \throw If \a this is not allocated.
3968  */
3969 DataArrayDouble *DataArrayDouble::magnitude() const
3970 {
3971   checkAllocated();
3972   int nbOfComp=getNumberOfComponents();
3973   DataArrayDouble *ret=DataArrayDouble::New();
3974   int nbOfTuple=getNumberOfTuples();
3975   ret->alloc(nbOfTuple,1);
3976   const double *src=getConstPointer();
3977   double *dest=ret->getPointer();
3978   for(int i=0;i<nbOfTuple;i++,dest++)
3979     {
3980       double sum=0.;
3981       for(int j=0;j<nbOfComp;j++,src++)
3982         sum+=(*src)*(*src);
3983       *dest=sqrt(sum);
3984     }
3985   return ret;
3986 }
3987
3988 /*!
3989  * Computes for each tuple the sum of number of components values in the tuple and return it.
3990  * 
3991  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3992  *          same number of tuples as \a this array and one component.
3993  *          The caller is to delete this result array using decrRef() as it is no more
3994  *          needed.
3995  *  \throw If \a this is not allocated.
3996  */
3997 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3998 {
3999   checkAllocated();
4000   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4001   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
4002   ret->alloc(nbOfTuple,1);
4003   const double *src(getConstPointer());
4004   double *dest(ret->getPointer());
4005   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4006     *dest=std::accumulate(src,src+nbOfComp,0.);
4007   return ret.retn();
4008 }
4009
4010 /*!
4011  * Computes the maximal value within every tuple of \a this array.
4012  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4013  *          same number of tuples as \a this array and one component.
4014  *          The caller is to delete this result array using decrRef() as it is no more
4015  *          needed.
4016  *  \throw If \a this is not allocated.
4017  *  \sa DataArrayDouble::maxPerTupleWithCompoId
4018  */
4019 DataArrayDouble *DataArrayDouble::maxPerTuple() const
4020 {
4021   checkAllocated();
4022   int nbOfComp=getNumberOfComponents();
4023   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4024   int nbOfTuple=getNumberOfTuples();
4025   ret->alloc(nbOfTuple,1);
4026   const double *src=getConstPointer();
4027   double *dest=ret->getPointer();
4028   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4029     *dest=*std::max_element(src,src+nbOfComp);
4030   return ret.retn();
4031 }
4032
4033 /*!
4034  * Computes the maximal value within every tuple of \a this array and it returns the first component
4035  * id for each tuple that corresponds to the maximal value within the tuple.
4036  * 
4037  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
4038  *          same number of tuples and only one component.
4039  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4040  *          same number of tuples as \a this array and one component.
4041  *          The caller is to delete this result array using decrRef() as it is no more
4042  *          needed.
4043  *  \throw If \a this is not allocated.
4044  *  \sa DataArrayDouble::maxPerTuple
4045  */
4046 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
4047 {
4048   checkAllocated();
4049   int nbOfComp=getNumberOfComponents();
4050   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
4051   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4052   int nbOfTuple=getNumberOfTuples();
4053   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
4054   const double *src=getConstPointer();
4055   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
4056   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
4057     {
4058       const double *loc=std::max_element(src,src+nbOfComp);
4059       *dest=*loc;
4060       *dest1=(int)std::distance(src,loc);
4061     }
4062   compoIdOfMaxPerTuple=ret1.retn();
4063   return ret0.retn();
4064 }
4065
4066 /*!
4067  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
4068  * \n This returned array contains the euclidian distance for each tuple in \a this. 
4069  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
4070  * \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)
4071  *
4072  * \warning use this method with care because it can leads to big amount of consumed memory !
4073  * 
4074  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
4075  *
4076  * \throw If \a this is not allocated.
4077  *
4078  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
4079  */
4080 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
4081 {
4082   checkAllocated();
4083   int nbOfComp=getNumberOfComponents();
4084   int nbOfTuples=getNumberOfTuples();
4085   const double *inData=getConstPointer();
4086   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4087   ret->alloc(nbOfTuples*nbOfTuples,1);
4088   double *outData=ret->getPointer();
4089   for(int i=0;i<nbOfTuples;i++)
4090     {
4091       outData[i*nbOfTuples+i]=0.;
4092       for(int j=i+1;j<nbOfTuples;j++)
4093         {
4094           double dist=0.;
4095           for(int k=0;k<nbOfComp;k++)
4096             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4097           dist=sqrt(dist);
4098           outData[i*nbOfTuples+j]=dist;
4099           outData[j*nbOfTuples+i]=dist;
4100         }
4101     }
4102   return ret.retn();
4103 }
4104
4105 /*!
4106  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4107  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4108  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4109  * \n Output rectangular matrix is sorted along rows.
4110  * \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)
4111  *
4112  * \warning use this method with care because it can leads to big amount of consumed memory !
4113  * 
4114  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4115  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
4116  *
4117  * \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.
4118  *
4119  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4120  */
4121 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4122 {
4123   if(!other)
4124     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4125   checkAllocated();
4126   other->checkAllocated();
4127   int nbOfComp=getNumberOfComponents();
4128   int otherNbOfComp=other->getNumberOfComponents();
4129   if(nbOfComp!=otherNbOfComp)
4130     {
4131       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4132       throw INTERP_KERNEL::Exception(oss.str().c_str());
4133     }
4134   int nbOfTuples=getNumberOfTuples();
4135   int otherNbOfTuples=other->getNumberOfTuples();
4136   const double *inData=getConstPointer();
4137   const double *inDataOther=other->getConstPointer();
4138   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4139   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4140   double *outData=ret->getPointer();
4141   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4142     {
4143       for(int j=0;j<nbOfTuples;j++)
4144         {
4145           double dist=0.;
4146           for(int k=0;k<nbOfComp;k++)
4147             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4148           dist=sqrt(dist);
4149           outData[i*nbOfTuples+j]=dist;
4150         }
4151     }
4152   return ret.retn();
4153 }
4154
4155 /*!
4156  * Sorts value within every tuple of \a this array.
4157  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4158  *              in descending order.
4159  *  \throw If \a this is not allocated.
4160  */
4161 void DataArrayDouble::sortPerTuple(bool asc)
4162 {
4163   checkAllocated();
4164   double *pt=getPointer();
4165   int nbOfTuple=getNumberOfTuples();
4166   int nbOfComp=getNumberOfComponents();
4167   if(asc)
4168     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4169       std::sort(pt,pt+nbOfComp);
4170   else
4171     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4172       std::sort(pt,pt+nbOfComp,std::greater<double>());
4173   declareAsNew();
4174 }
4175
4176 /*!
4177  * Converts every value of \a this array to its absolute value.
4178  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4179  * should be called instead.
4180  *
4181  * \throw If \a this is not allocated.
4182  * \sa DataArrayDouble::computeAbs
4183  */
4184 void DataArrayDouble::abs()
4185 {
4186   checkAllocated();
4187   double *ptr(getPointer());
4188   std::size_t nbOfElems(getNbOfElems());
4189   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4190   declareAsNew();
4191 }
4192
4193 /*!
4194  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4195  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4196  *
4197  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4198  *         same number of tuples and component as \a this array.
4199  *         The caller is to delete this result array using decrRef() as it is no more
4200  *         needed.
4201  * \throw If \a this is not allocated.
4202  * \sa DataArrayDouble::abs
4203  */
4204 DataArrayDouble *DataArrayDouble::computeAbs() const
4205 {
4206   checkAllocated();
4207   DataArrayDouble *newArr(DataArrayDouble::New());
4208   int nbOfTuples(getNumberOfTuples());
4209   int nbOfComp(getNumberOfComponents());
4210   newArr->alloc(nbOfTuples,nbOfComp);
4211   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4212   newArr->copyStringInfoFrom(*this);
4213   return newArr;
4214 }
4215
4216 /*!
4217  * Apply a linear function to a given component of \a this array, so that
4218  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4219  *  \param [in] a - the first coefficient of the function.
4220  *  \param [in] b - the second coefficient of the function.
4221  *  \param [in] compoId - the index of component to modify.
4222  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4223  */
4224 void DataArrayDouble::applyLin(double a, double b, int compoId)
4225 {
4226   checkAllocated();
4227   double *ptr(getPointer()+compoId);
4228   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4229   if(compoId<0 || compoId>=nbOfComp)
4230     {
4231       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4232       throw INTERP_KERNEL::Exception(oss.str().c_str());
4233     }
4234   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4235     *ptr=a*(*ptr)+b;
4236   declareAsNew();
4237 }
4238
4239 /*!
4240  * Apply a linear function to all elements of \a this array, so that
4241  * an element _x_ becomes \f$ a * x + b \f$.
4242  *  \param [in] a - the first coefficient of the function.
4243  *  \param [in] b - the second coefficient of the function.
4244  *  \throw If \a this is not allocated.
4245  */
4246 void DataArrayDouble::applyLin(double a, double b)
4247 {
4248   checkAllocated();
4249   double *ptr=getPointer();
4250   std::size_t nbOfElems=getNbOfElems();
4251   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4252     *ptr=a*(*ptr)+b;
4253   declareAsNew();
4254 }
4255
4256 /*!
4257  * Modify all elements of \a this array, so that
4258  * an element _x_ becomes \f$ numerator / x \f$.
4259  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4260  *           array, all elements processed before detection of the zero element remain
4261  *           modified.
4262  *  \param [in] numerator - the numerator used to modify array elements.
4263  *  \throw If \a this is not allocated.
4264  *  \throw If there is an element equal to 0.0 in \a this array.
4265  */
4266 void DataArrayDouble::applyInv(double numerator)
4267 {
4268   checkAllocated();
4269   double *ptr=getPointer();
4270   std::size_t nbOfElems=getNbOfElems();
4271   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4272     {
4273       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4274         {
4275           *ptr=numerator/(*ptr);
4276         }
4277       else
4278         {
4279           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4280           oss << " !";
4281           throw INTERP_KERNEL::Exception(oss.str().c_str());
4282         }
4283     }
4284   declareAsNew();
4285 }
4286
4287 /*!
4288  * Returns a full copy of \a this array except that sign of all elements is reversed.
4289  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4290  *          same number of tuples and component as \a this array.
4291  *          The caller is to delete this result array using decrRef() as it is no more
4292  *          needed.
4293  *  \throw If \a this is not allocated.
4294  */
4295 DataArrayDouble *DataArrayDouble::negate() const
4296 {
4297   checkAllocated();
4298   DataArrayDouble *newArr=DataArrayDouble::New();
4299   int nbOfTuples=getNumberOfTuples();
4300   int nbOfComp=getNumberOfComponents();
4301   newArr->alloc(nbOfTuples,nbOfComp);
4302   const double *cptr=getConstPointer();
4303   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4304   newArr->copyStringInfoFrom(*this);
4305   return newArr;
4306 }
4307
4308 /*!
4309  * Modify all elements of \a this array, so that
4310  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4311  * all values in \a this have to be >= 0 if val is \b not integer.
4312  *  \param [in] val - the value used to apply pow on all array elements.
4313  *  \throw If \a this is not allocated.
4314  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4315  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4316  *           modified.
4317  */
4318 void DataArrayDouble::applyPow(double val)
4319 {
4320   checkAllocated();
4321   double *ptr=getPointer();
4322   std::size_t nbOfElems=getNbOfElems();
4323   int val2=(int)val;
4324   bool isInt=((double)val2)==val;
4325   if(!isInt)
4326     {
4327       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4328         {
4329           if(*ptr>=0)
4330             *ptr=pow(*ptr,val);
4331           else
4332             {
4333               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4334               throw INTERP_KERNEL::Exception(oss.str().c_str());
4335             }
4336         }
4337     }
4338   else
4339     {
4340       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4341         *ptr=pow(*ptr,val2);
4342     }
4343   declareAsNew();
4344 }
4345
4346 /*!
4347  * Modify all elements of \a this array, so that
4348  * an element _x_ becomes \f$ val ^ x \f$.
4349  *  \param [in] val - the value used to apply pow on all array elements.
4350  *  \throw If \a this is not allocated.
4351  *  \throw If \a val < 0.
4352  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4353  *           array, all elements processed before detection of the zero element remain
4354  *           modified.
4355  */
4356 void DataArrayDouble::applyRPow(double val)
4357 {
4358   checkAllocated();
4359   if(val<0.)
4360     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4361   double *ptr=getPointer();
4362   std::size_t nbOfElems=getNbOfElems();
4363   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4364     *ptr=pow(val,*ptr);
4365   declareAsNew();
4366 }
4367
4368 /*!
4369  * Returns a new DataArrayDouble created from \a this one by applying \a
4370  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4371  * For more info see \ref MEDCouplingArrayApplyFunc
4372  *  \param [in] nbOfComp - number of components in the result array.
4373  *  \param [in] func - the \a FunctionToEvaluate declared as 
4374  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4375  *              where \a pos points to the first component of a tuple of \a this array
4376  *              and \a res points to the first component of a tuple of the result array.
4377  *              Note that length (number of components) of \a pos can differ from
4378  *              that of \a res.
4379  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4380  *          same number of tuples as \a this array.
4381  *          The caller is to delete this result array using decrRef() as it is no more
4382  *          needed.
4383  *  \throw If \a this is not allocated.
4384  *  \throw If \a func returns \a false.
4385  */
4386 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4387 {
4388   checkAllocated();
4389   DataArrayDouble *newArr=DataArrayDouble::New();
4390   int nbOfTuples=getNumberOfTuples();
4391   int oldNbOfComp=getNumberOfComponents();
4392   newArr->alloc(nbOfTuples,nbOfComp);
4393   const double *ptr=getConstPointer();
4394   double *ptrToFill=newArr->getPointer();
4395   for(int i=0;i<nbOfTuples;i++)
4396     {
4397       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4398         {
4399           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4400           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4401           oss << ") : Evaluation of function failed !";
4402           newArr->decrRef();
4403           throw INTERP_KERNEL::Exception(oss.str().c_str());
4404         }
4405     }
4406   return newArr;
4407 }
4408
4409 /*!
4410  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4411  * tuple of \a this array. Textual data is not copied.
4412  * For more info see \ref MEDCouplingArrayApplyFunc1.
4413  *  \param [in] nbOfComp - number of components in the result array.
4414  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4415  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4416  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4417  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4418  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4419  *          same number of tuples as \a this array and \a nbOfComp components.
4420  *          The caller is to delete this result array using decrRef() as it is no more
4421  *          needed.
4422  *  \throw If \a this is not allocated.
4423  *  \throw If computing \a func fails.
4424  */
4425 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4426 {
4427   INTERP_KERNEL::ExprParser expr(func);
4428   expr.parse();
4429   std::set<std::string> vars;
4430   expr.getTrueSetOfVars(vars);
4431   std::vector<std::string> varsV(vars.begin(),vars.end());
4432   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
4433 }
4434
4435 /*!
4436  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4437  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4438  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4439  *
4440  * For more info see \ref MEDCouplingArrayApplyFunc0.
4441  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4442  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4443  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4444  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4445  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4446  *          same number of tuples and components as \a this array.
4447  *          The caller is to delete this result array using decrRef() as it is no more
4448  *          needed.
4449  *  \sa applyFuncOnThis
4450  *  \throw If \a this is not allocated.
4451  *  \throw If computing \a func fails.
4452  */
4453 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4454 {
4455   int nbOfComp(getNumberOfComponents());
4456   if(nbOfComp<=0)
4457     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4458   checkAllocated();
4459   int nbOfTuples(getNumberOfTuples());
4460   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4461   newArr->alloc(nbOfTuples,nbOfComp);
4462   INTERP_KERNEL::ExprParser expr(func);
4463   expr.parse();
4464   std::set<std::string> vars;
4465   expr.getTrueSetOfVars(vars);
4466   if((int)vars.size()>1)
4467     {
4468       std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : ";
4469       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4470       throw INTERP_KERNEL::Exception(oss.str().c_str());
4471     }
4472   if(vars.empty())
4473     {
4474       expr.prepareFastEvaluator();
4475       newArr->rearrange(1);
4476       newArr->fillWithValue(expr.evaluateDouble());
4477       newArr->rearrange(nbOfComp);
4478       return newArr.retn();
4479     }
4480   std::vector<std::string> vars2(vars.begin(),vars.end());
4481   double buff,*ptrToFill(newArr->getPointer());
4482   const double *ptr(begin());
4483   std::vector<double> stck;
4484   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4485   expr.prepareFastEvaluator();
4486   if(!isSafe)
4487     {
4488       for(int i=0;i<nbOfTuples;i++)
4489         {
4490           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4491             {
4492               buff=*ptr;
4493               expr.evaluateDoubleInternal(stck);
4494               *ptrToFill=stck.back();
4495               stck.pop_back();
4496             }
4497         }
4498     }
4499   else
4500     {
4501       for(int i=0;i<nbOfTuples;i++)
4502         {
4503           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4504             {
4505               buff=*ptr;
4506               try
4507               {
4508                   expr.evaluateDoubleInternalSafe(stck);
4509               }
4510               catch(INTERP_KERNEL::Exception& e)
4511               {
4512                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4513                   oss << buff;
4514                   oss << ") : Evaluation of function failed !" << e.what();
4515                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4516               }
4517               *ptrToFill=stck.back();
4518               stck.pop_back();
4519             }
4520         }
4521     }
4522   return newArr.retn();
4523 }
4524
4525 /*!
4526  * This method is a non const method that modify the array in \a this.
4527  * This method only works on one component array. It means that function \a func must
4528  * contain at most one variable.
4529  * This method is a specialization of applyFunc method with one parameter on one component array.
4530  *
4531  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4532  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4533  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4534  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4535  *
4536  * \sa applyFunc
4537  */
4538 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4539 {
4540   int nbOfComp(getNumberOfComponents());
4541   if(nbOfComp<=0)
4542     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4543   checkAllocated();
4544   int nbOfTuples(getNumberOfTuples());
4545   INTERP_KERNEL::ExprParser expr(func);
4546   expr.parse();
4547   std::set<std::string> vars;
4548   expr.getTrueSetOfVars(vars);
4549   if((int)vars.size()>1)
4550     {
4551       std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : ";
4552       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4553       throw INTERP_KERNEL::Exception(oss.str().c_str());
4554     }
4555   if(vars.empty())
4556     {
4557       expr.prepareFastEvaluator();
4558       std::vector<std::string> compInfo(getInfoOnComponents());
4559       rearrange(1);
4560       fillWithValue(expr.evaluateDouble());
4561       rearrange(nbOfComp);
4562       setInfoOnComponents(compInfo);
4563       return ;
4564     }
4565   std::vector<std::string> vars2(vars.begin(),vars.end());
4566   double buff,*ptrToFill(getPointer());
4567   const double *ptr(begin());
4568   std::vector<double> stck;
4569   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4570   expr.prepareFastEvaluator();
4571   if(!isSafe)
4572     {
4573       for(int i=0;i<nbOfTuples;i++)
4574         {
4575           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4576             {
4577               buff=*ptr;
4578               expr.evaluateDoubleInternal(stck);
4579               *ptrToFill=stck.back();
4580               stck.pop_back();
4581             }
4582         }
4583     }
4584   else
4585     {
4586       for(int i=0;i<nbOfTuples;i++)
4587         {
4588           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4589             {
4590               buff=*ptr;
4591               try
4592               {
4593                   expr.evaluateDoubleInternalSafe(stck);
4594               }
4595               catch(INTERP_KERNEL::Exception& e)
4596               {
4597                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4598                   oss << buff;
4599                   oss << ") : Evaluation of function failed !" << e.what();
4600                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4601               }
4602               *ptrToFill=stck.back();
4603               stck.pop_back();
4604             }
4605         }
4606     }
4607 }
4608
4609 /*!
4610  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4611  * tuple of \a this array. Textual data is not copied.
4612  * For more info see \ref MEDCouplingArrayApplyFunc2.
4613  *  \param [in] nbOfComp - number of components in the result array.
4614  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4615  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4616  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4617  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4618  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4619  *          same number of tuples as \a this array.
4620  *          The caller is to delete this result array using decrRef() as it is no more
4621  *          needed.
4622  *  \throw If \a this is not allocated.
4623  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4624  *  \throw If computing \a func fails.
4625  */
4626 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
4627 {
4628   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
4629 }
4630
4631 /*!
4632  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4633  * tuple of \a this array. Textual data is not copied.
4634  * For more info see \ref MEDCouplingArrayApplyFunc3.
4635  *  \param [in] nbOfComp - number of components in the result array.
4636  *  \param [in] varsOrder - sequence of vars defining their order.
4637  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4638  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4639  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4640  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4641  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4642  *          same number of tuples as \a this array.
4643  *          The caller is to delete this result array using decrRef() as it is no more
4644  *          needed.
4645  *  \throw If \a this is not allocated.
4646  *  \throw If \a func contains vars not in \a varsOrder.
4647  *  \throw If computing \a func fails.
4648  */
4649 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4650 {
4651   if(nbOfComp<=0)
4652     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
4653   std::vector<std::string> varsOrder2(varsOrder);
4654   int oldNbOfComp(getNumberOfComponents());
4655   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4656     varsOrder2.push_back(std::string());
4657   checkAllocated();
4658   int nbOfTuples(getNumberOfTuples());
4659   INTERP_KERNEL::ExprParser expr(func);
4660   expr.parse();
4661   std::set<std::string> vars;
4662   expr.getTrueSetOfVars(vars);
4663   if((int)vars.size()>oldNbOfComp)
4664     {
4665       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4666       oss << vars.size() << " variables : ";
4667       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4668       throw INTERP_KERNEL::Exception(oss.str().c_str());
4669     }
4670   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4671   newArr->alloc(nbOfTuples,nbOfComp);
4672   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4673   double *buffPtr(buff),*ptrToFill;
4674   std::vector<double> stck;
4675   for(int iComp=0;iComp<nbOfComp;iComp++)
4676     {
4677       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4678       expr.prepareFastEvaluator();
4679       const double *ptr(getConstPointer());
4680       ptrToFill=newArr->getPointer()+iComp;
4681       if(!isSafe)
4682         {
4683           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4684             {
4685               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4686               expr.evaluateDoubleInternal(stck);
4687               *ptrToFill=stck.back();
4688               stck.pop_back();
4689             }
4690         }
4691       else
4692         {
4693           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4694             {
4695               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4696               try
4697               {
4698                   expr.evaluateDoubleInternalSafe(stck);
4699                   *ptrToFill=stck.back();
4700                   stck.pop_back();
4701               }
4702               catch(INTERP_KERNEL::Exception& e)
4703               {
4704                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4705                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4706                   oss << ") : Evaluation of function failed !" << e.what();
4707                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4708               }
4709             }
4710         }
4711     }
4712   return newArr.retn();
4713 }
4714
4715 void DataArrayDouble::applyFuncFast32(const std::string& func)
4716 {
4717   checkAllocated();
4718   INTERP_KERNEL::ExprParser expr(func);
4719   expr.parse();
4720   char *funcStr=expr.compileX86();
4721   MYFUNCPTR funcPtr;
4722   *((void **)&funcPtr)=funcStr;//he he...
4723   //
4724   double *ptr=getPointer();
4725   int nbOfComp=getNumberOfComponents();
4726   int nbOfTuples=getNumberOfTuples();
4727   int nbOfElems=nbOfTuples*nbOfComp;
4728   for(int i=0;i<nbOfElems;i++,ptr++)
4729     *ptr=funcPtr(*ptr);
4730   declareAsNew();
4731 }
4732
4733 void DataArrayDouble::applyFuncFast64(const std::string& func)
4734 {
4735   checkAllocated();
4736   INTERP_KERNEL::ExprParser expr(func);
4737   expr.parse();
4738   char *funcStr=expr.compileX86_64();
4739   MYFUNCPTR funcPtr;
4740   *((void **)&funcPtr)=funcStr;//he he...
4741   //
4742   double *ptr=getPointer();
4743   int nbOfComp=getNumberOfComponents();
4744   int nbOfTuples=getNumberOfTuples();
4745   int nbOfElems=nbOfTuples*nbOfComp;
4746   for(int i=0;i<nbOfElems;i++,ptr++)
4747     *ptr=funcPtr(*ptr);
4748   declareAsNew();
4749 }
4750
4751 DataArrayDoubleIterator *DataArrayDouble::iterator()
4752 {
4753   return new DataArrayDoubleIterator(this);
4754 }
4755
4756 /*!
4757  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4758  * array whose values are within a given range. Textual data is not copied.
4759  *  \param [in] vmin - a lowest acceptable value (included).
4760  *  \param [in] vmax - a greatest acceptable value (included).
4761  *  \return DataArrayInt * - the new instance of DataArrayInt.
4762  *          The caller is to delete this result array using decrRef() as it is no more
4763  *          needed.
4764  *  \throw If \a this->getNumberOfComponents() != 1.
4765  *
4766  *  \sa DataArrayDouble::findIdsNotInRange
4767  *
4768  *  \if ENABLE_EXAMPLES
4769  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4770  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4771  *  \endif
4772  */
4773 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
4774 {
4775   checkAllocated();
4776   if(getNumberOfComponents()!=1)
4777     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
4778   const double *cptr(begin());
4779   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4780   int nbOfTuples(getNumberOfTuples());
4781   for(int i=0;i<nbOfTuples;i++,cptr++)
4782     if(*cptr>=vmin && *cptr<=vmax)
4783       ret->pushBackSilent(i);
4784   return ret.retn();
4785 }
4786
4787 /*!
4788  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4789  * array whose values are not within a given range. Textual data is not copied.
4790  *  \param [in] vmin - a lowest not acceptable value (excluded).
4791  *  \param [in] vmax - a greatest not acceptable value (excluded).
4792  *  \return DataArrayInt * - the new instance of DataArrayInt.
4793  *          The caller is to delete this result array using decrRef() as it is no more
4794  *          needed.
4795  *  \throw If \a this->getNumberOfComponents() != 1.
4796  *
4797  *  \sa DataArrayDouble::findIdsInRange
4798  */
4799 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
4800 {
4801   checkAllocated();
4802   if(getNumberOfComponents()!=1)
4803     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
4804   const double *cptr(begin());
4805   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4806   int nbOfTuples(getNumberOfTuples());
4807   for(int i=0;i<nbOfTuples;i++,cptr++)
4808     if(*cptr<vmin || *cptr>vmax)
4809       ret->pushBackSilent(i);
4810   return ret.retn();
4811 }
4812
4813 /*!
4814  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4815  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4816  * the number of component in the result array is same as that of each of given arrays.
4817  * Info on components is copied from the first of the given arrays. Number of components
4818  * in the given arrays must be  the same.
4819  *  \param [in] a1 - an array to include in the result array.
4820  *  \param [in] a2 - another array to include in the result array.
4821  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4822  *          The caller is to delete this result array using decrRef() as it is no more
4823  *          needed.
4824  *  \throw If both \a a1 and \a a2 are NULL.
4825  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4826  */
4827 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4828 {
4829   std::vector<const DataArrayDouble *> tmp(2);
4830   tmp[0]=a1; tmp[1]=a2;
4831   return Aggregate(tmp);
4832 }
4833
4834 /*!
4835  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4836  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4837  * the number of component in the result array is same as that of each of given arrays.
4838  * Info on components is copied from the first of the given arrays. Number of components
4839  * in the given arrays must be  the same.
4840  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4841  * not the object itself.
4842  *  \param [in] arr - a sequence of arrays to include in the result array.
4843  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4844  *          The caller is to delete this result array using decrRef() as it is no more
4845  *          needed.
4846  *  \throw If all arrays within \a arr are NULL.
4847  *  \throw If getNumberOfComponents() of arrays within \a arr.
4848  */
4849 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4850 {
4851   std::vector<const DataArrayDouble *> a;
4852   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4853     if(*it4)
4854       a.push_back(*it4);
4855   if(a.empty())
4856     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4857   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4858   int nbOfComp=(*it)->getNumberOfComponents();
4859   int nbt=(*it++)->getNumberOfTuples();
4860   for(int i=1;it!=a.end();it++,i++)
4861     {
4862       if((*it)->getNumberOfComponents()!=nbOfComp)
4863         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4864       nbt+=(*it)->getNumberOfTuples();
4865     }
4866   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4867   ret->alloc(nbt,nbOfComp);
4868   double *pt=ret->getPointer();
4869   for(it=a.begin();it!=a.end();it++)
4870     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4871   ret->copyStringInfoFrom(*(a[0]));
4872   return ret.retn();
4873 }
4874
4875 /*!
4876  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4877  * of components in the result array is a sum of the number of components of given arrays
4878  * and (2) the number of tuples in the result array is same as that of each of given
4879  * arrays. In other words the i-th tuple of result array includes all components of
4880  * i-th tuples of all given arrays.
4881  * Number of tuples in the given arrays must be  the same.
4882  *  \param [in] a1 - an array to include in the result array.
4883  *  \param [in] a2 - another array to include in the result array.
4884  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4885  *          The caller is to delete this result array using decrRef() as it is no more
4886  *          needed.
4887  *  \throw If both \a a1 and \a a2 are NULL.
4888  *  \throw If any given array is not allocated.
4889  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4890  */
4891 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4892 {
4893   std::vector<const DataArrayDouble *> arr(2);
4894   arr[0]=a1; arr[1]=a2;
4895   return Meld(arr);
4896 }
4897
4898 /*!
4899  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4900  * of components in the result array is a sum of the number of components of given arrays
4901  * and (2) the number of tuples in the result array is same as that of each of given
4902  * arrays. In other words the i-th tuple of result array includes all components of
4903  * i-th tuples of all given arrays.
4904  * Number of tuples in the given arrays must be  the same.
4905  *  \param [in] arr - a sequence of arrays to include in the result array.
4906  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4907  *          The caller is to delete this result array using decrRef() as it is no more
4908  *          needed.
4909  *  \throw If all arrays within \a arr are NULL.
4910  *  \throw If any given array is not allocated.
4911  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4912  */
4913 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4914 {
4915   std::vector<const DataArrayDouble *> a;
4916   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4917     if(*it4)
4918       a.push_back(*it4);
4919   if(a.empty())
4920     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4921   std::vector<const DataArrayDouble *>::const_iterator it;
4922   for(it=a.begin();it!=a.end();it++)
4923     (*it)->checkAllocated();
4924   it=a.begin();
4925   int nbOfTuples=(*it)->getNumberOfTuples();
4926   std::vector<int> nbc(a.size());
4927   std::vector<const double *> pts(a.size());
4928   nbc[0]=(*it)->getNumberOfComponents();
4929   pts[0]=(*it++)->getConstPointer();
4930   for(int i=1;it!=a.end();it++,i++)
4931     {
4932       if(nbOfTuples!=(*it)->getNumberOfTuples())
4933         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4934       nbc[i]=(*it)->getNumberOfComponents();
4935       pts[i]=(*it)->getConstPointer();
4936     }
4937   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4938   DataArrayDouble *ret=DataArrayDouble::New();
4939   ret->alloc(nbOfTuples,totalNbOfComp);
4940   double *retPtr=ret->getPointer();
4941   for(int i=0;i<nbOfTuples;i++)
4942     for(int j=0;j<(int)a.size();j++)
4943       {
4944         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4945         pts[j]+=nbc[j];
4946       }
4947   int k=0;
4948   for(int i=0;i<(int)a.size();i++)
4949     for(int j=0;j<nbc[i];j++,k++)
4950       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4951   return ret;
4952 }
4953
4954 /*!
4955  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4956  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4957  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4958  * Info on components and name is copied from the first of the given arrays.
4959  * Number of tuples and components in the given arrays must be the same.
4960  *  \param [in] a1 - a given array.
4961  *  \param [in] a2 - another given array.
4962  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4963  *          The caller is to delete this result array using decrRef() as it is no more
4964  *          needed.
4965  *  \throw If either \a a1 or \a a2 is NULL.
4966  *  \throw If any given array is not allocated.
4967  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4968  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4969  */
4970 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4971 {
4972   if(!a1 || !a2)
4973     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4974   a1->checkAllocated();
4975   a2->checkAllocated();
4976   int nbOfComp=a1->getNumberOfComponents();
4977   if(nbOfComp!=a2->getNumberOfComponents())
4978     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4979   int nbOfTuple=a1->getNumberOfTuples();
4980   if(nbOfTuple!=a2->getNumberOfTuples())
4981     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4982   DataArrayDouble *ret=DataArrayDouble::New();
4983   ret->alloc(nbOfTuple,1);
4984   double *retPtr=ret->getPointer();
4985   const double *a1Ptr=a1->getConstPointer();
4986   const double *a2Ptr=a2->getConstPointer();
4987   for(int i=0;i<nbOfTuple;i++)
4988     {
4989       double sum=0.;
4990       for(int j=0;j<nbOfComp;j++)
4991         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4992       retPtr[i]=sum;
4993     }
4994   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4995   ret->setName(a1->getName());
4996   return ret;
4997 }
4998
4999 /*!
5000  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
5001  * the i-th tuple of the result array contains 3 components of a vector which is a cross
5002  * product of two vectors defined by the i-th tuples of given arrays.
5003  * Info on components is copied from the first of the given arrays.
5004  * Number of tuples in the given arrays must be the same.
5005  * Number of components in the given arrays must be 3.
5006  *  \param [in] a1 - a given array.
5007  *  \param [in] a2 - another given array.
5008  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5009  *          The caller is to delete this result array using decrRef() as it is no more
5010  *          needed.
5011  *  \throw If either \a a1 or \a a2 is NULL.
5012  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5013  *  \throw If \a a1->getNumberOfComponents() != 3
5014  *  \throw If \a a2->getNumberOfComponents() != 3
5015  */
5016 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
5017 {
5018   if(!a1 || !a2)
5019     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
5020   int nbOfComp=a1->getNumberOfComponents();
5021   if(nbOfComp!=a2->getNumberOfComponents())
5022     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
5023   if(nbOfComp!=3)
5024     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
5025   int nbOfTuple=a1->getNumberOfTuples();
5026   if(nbOfTuple!=a2->getNumberOfTuples())
5027     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
5028   DataArrayDouble *ret=DataArrayDouble::New();
5029   ret->alloc(nbOfTuple,3);
5030   double *retPtr=ret->getPointer();
5031   const double *a1Ptr=a1->getConstPointer();
5032   const double *a2Ptr=a2->getConstPointer();
5033   for(int i=0;i<nbOfTuple;i++)
5034     {
5035       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
5036       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
5037       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
5038     }
5039   ret->copyStringInfoFrom(*a1);
5040   return ret;
5041 }
5042
5043 /*!
5044  * Returns a new DataArrayDouble containing maximal values of two given arrays.
5045  * Info on components is copied from the first of the given arrays.
5046  * Number of tuples and components in the given arrays must be the same.
5047  *  \param [in] a1 - an array to compare values with another one.
5048  *  \param [in] a2 - another array to compare values with the first one.
5049  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5050  *          The caller is to delete this result array using decrRef() as it is no more
5051  *          needed.
5052  *  \throw If either \a a1 or \a a2 is NULL.
5053  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5054  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5055  */
5056 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
5057 {
5058   if(!a1 || !a2)
5059     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
5060   int nbOfComp=a1->getNumberOfComponents();
5061   if(nbOfComp!=a2->getNumberOfComponents())
5062     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
5063   int nbOfTuple=a1->getNumberOfTuples();
5064   if(nbOfTuple!=a2->getNumberOfTuples())
5065     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
5066   DataArrayDouble *ret=DataArrayDouble::New();
5067   ret->alloc(nbOfTuple,nbOfComp);
5068   double *retPtr=ret->getPointer();
5069   const double *a1Ptr=a1->getConstPointer();
5070   const double *a2Ptr=a2->getConstPointer();
5071   int nbElem=nbOfTuple*nbOfComp;
5072   for(int i=0;i<nbElem;i++)
5073     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
5074   ret->copyStringInfoFrom(*a1);
5075   return ret;
5076 }
5077
5078 /*!
5079  * Returns a new DataArrayDouble containing minimal values of two given arrays.
5080  * Info on components is copied from the first of the given arrays.
5081  * Number of tuples and components in the given arrays must be the same.
5082  *  \param [in] a1 - an array to compare values with another one.
5083  *  \param [in] a2 - another array to compare values with the first one.
5084  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5085  *          The caller is to delete this result array using decrRef() as it is no more
5086  *          needed.
5087  *  \throw If either \a a1 or \a a2 is NULL.
5088  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5089  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5090  */
5091 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
5092 {
5093   if(!a1 || !a2)
5094     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
5095   int nbOfComp=a1->getNumberOfComponents();
5096   if(nbOfComp!=a2->getNumberOfComponents())
5097     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5098   int nbOfTuple=a1->getNumberOfTuples();
5099   if(nbOfTuple!=a2->getNumberOfTuples())
5100     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5101   DataArrayDouble *ret=DataArrayDouble::New();
5102   ret->alloc(nbOfTuple,nbOfComp);
5103   double *retPtr=ret->getPointer();
5104   const double *a1Ptr=a1->getConstPointer();
5105   const double *a2Ptr=a2->getConstPointer();
5106   int nbElem=nbOfTuple*nbOfComp;
5107   for(int i=0;i<nbElem;i++)
5108     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5109   ret->copyStringInfoFrom(*a1);
5110   return ret;
5111 }
5112
5113 /*!
5114  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5115  * valid cases.
5116  * 1.  The arrays have same number of tuples and components. Then each value of
5117  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5118  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5119  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5120  *   component. Then
5121  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5122  * 3.  The arrays have same number of components and one array, say _a2_, has one
5123  *   tuple. Then
5124  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5125  *
5126  * Info on components is copied either from the first array (in the first case) or from
5127  * the array with maximal number of elements (getNbOfElems()).
5128  *  \param [in] a1 - an array to sum up.
5129  *  \param [in] a2 - another array to sum up.
5130  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5131  *          The caller is to delete this result array using decrRef() as it is no more
5132  *          needed.
5133  *  \throw If either \a a1 or \a a2 is NULL.
5134  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5135  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5136  *         none of them has number of tuples or components equal to 1.
5137  */
5138 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5139 {
5140   if(!a1 || !a2)
5141     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5142   int nbOfTuple=a1->getNumberOfTuples();
5143   int nbOfTuple2=a2->getNumberOfTuples();
5144   int nbOfComp=a1->getNumberOfComponents();
5145   int nbOfComp2=a2->getNumberOfComponents();
5146   MCAuto<DataArrayDouble> ret=0;
5147   if(nbOfTuple==nbOfTuple2)
5148     {
5149       if(nbOfComp==nbOfComp2)
5150         {
5151           ret=DataArrayDouble::New();
5152           ret->alloc(nbOfTuple,nbOfComp);
5153           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5154           ret->copyStringInfoFrom(*a1);
5155         }
5156       else
5157         {
5158           int nbOfCompMin,nbOfCompMax;
5159           const DataArrayDouble *aMin, *aMax;
5160           if(nbOfComp>nbOfComp2)
5161             {
5162               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5163               aMin=a2; aMax=a1;
5164             }
5165           else
5166             {
5167               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5168               aMin=a1; aMax=a2;
5169             }
5170           if(nbOfCompMin==1)
5171             {
5172               ret=DataArrayDouble::New();
5173               ret->alloc(nbOfTuple,nbOfCompMax);
5174               const double *aMinPtr=aMin->getConstPointer();
5175               const double *aMaxPtr=aMax->getConstPointer();
5176               double *res=ret->getPointer();
5177               for(int i=0;i<nbOfTuple;i++)
5178                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5179               ret->copyStringInfoFrom(*aMax);
5180             }
5181           else
5182             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5183         }
5184     }
5185   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5186     {
5187       if(nbOfComp==nbOfComp2)
5188         {
5189           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5190           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5191           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5192           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5193           ret=DataArrayDouble::New();
5194           ret->alloc(nbOfTupleMax,nbOfComp);
5195           double *res=ret->getPointer();
5196           for(int i=0;i<nbOfTupleMax;i++)
5197             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5198           ret->copyStringInfoFrom(*aMax);
5199         }
5200       else
5201         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5202     }
5203   else
5204     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5205   return ret.retn();
5206 }
5207
5208 /*!
5209  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5210  * valid cases.
5211  * 1.  The arrays have same number of tuples and components. Then each value of
5212  *   \a other array is added to the corresponding value of \a this array, i.e.:
5213  *   _a_ [ i, j ] += _other_ [ i, j ].
5214  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5215  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5216  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5217  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5218  *
5219  *  \param [in] other - an array to add to \a this one.
5220  *  \throw If \a other is NULL.
5221  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5222  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5223  *         \a other has number of both tuples and components not equal to 1.
5224  */
5225 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5226 {
5227   if(!other)
5228     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5229   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5230   checkAllocated();
5231   other->checkAllocated();
5232   int nbOfTuple=getNumberOfTuples();
5233   int nbOfTuple2=other->getNumberOfTuples();
5234   int nbOfComp=getNumberOfComponents();
5235   int nbOfComp2=other->getNumberOfComponents();
5236   if(nbOfTuple==nbOfTuple2)
5237     {
5238       if(nbOfComp==nbOfComp2)
5239         {
5240           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5241         }
5242       else if(nbOfComp2==1)
5243         {
5244           double *ptr=getPointer();
5245           const double *ptrc=other->getConstPointer();
5246           for(int i=0;i<nbOfTuple;i++)
5247             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5248         }
5249       else
5250         throw INTERP_KERNEL::Exception(msg);
5251     }
5252   else if(nbOfTuple2==1)
5253     {
5254       if(nbOfComp2==nbOfComp)
5255         {
5256           double *ptr=getPointer();
5257           const double *ptrc=other->getConstPointer();
5258           for(int i=0;i<nbOfTuple;i++)
5259             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5260         }
5261       else
5262         throw INTERP_KERNEL::Exception(msg);
5263     }
5264   else
5265     throw INTERP_KERNEL::Exception(msg);
5266   declareAsNew();
5267 }
5268
5269 /*!
5270  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5271  * valid cases.
5272  * 1.  The arrays have same number of tuples and components. Then each value of
5273  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5274  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5275  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5276  *   component. Then
5277  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5278  * 3.  The arrays have same number of components and one array, say _a2_, has one
5279  *   tuple. Then
5280  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5281  *
5282  * Info on components is copied either from the first array (in the first case) or from
5283  * the array with maximal number of elements (getNbOfElems()).
5284  *  \param [in] a1 - an array to subtract from.
5285  *  \param [in] a2 - an array to subtract.
5286  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5287  *          The caller is to delete this result array using decrRef() as it is no more
5288  *          needed.
5289  *  \throw If either \a a1 or \a a2 is NULL.
5290  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5291  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5292  *         none of them has number of tuples or components equal to 1.
5293  */
5294 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5295 {
5296   if(!a1 || !a2)
5297     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5298   int nbOfTuple1=a1->getNumberOfTuples();
5299   int nbOfTuple2=a2->getNumberOfTuples();
5300   int nbOfComp1=a1->getNumberOfComponents();
5301   int nbOfComp2=a2->getNumberOfComponents();
5302   if(nbOfTuple2==nbOfTuple1)
5303     {
5304       if(nbOfComp1==nbOfComp2)
5305         {
5306           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5307           ret->alloc(nbOfTuple2,nbOfComp1);
5308           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5309           ret->copyStringInfoFrom(*a1);
5310           return ret.retn();
5311         }
5312       else if(nbOfComp2==1)
5313         {
5314           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5315           ret->alloc(nbOfTuple1,nbOfComp1);
5316           const double *a2Ptr=a2->getConstPointer();
5317           const double *a1Ptr=a1->getConstPointer();
5318           double *res=ret->getPointer();
5319           for(int i=0;i<nbOfTuple1;i++)
5320             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5321           ret->copyStringInfoFrom(*a1);
5322           return ret.retn();
5323         }
5324       else
5325         {
5326           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5327           return 0;
5328         }
5329     }
5330   else if(nbOfTuple2==1)
5331     {
5332       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5333       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5334       ret->alloc(nbOfTuple1,nbOfComp1);
5335       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5336       double *pt=ret->getPointer();
5337       for(int i=0;i<nbOfTuple1;i++)
5338         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5339       ret->copyStringInfoFrom(*a1);
5340       return ret.retn();
5341     }
5342   else
5343     {
5344       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5345       return 0;
5346     }
5347 }
5348
5349 /*!
5350  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5351  * valid cases.
5352  * 1.  The arrays have same number of tuples and components. Then each value of
5353  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5354  *   _a_ [ i, j ] -= _other_ [ i, j ].
5355  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5356  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5357  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5358  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5359  *
5360  *  \param [in] other - an array to subtract from \a this one.
5361  *  \throw If \a other is NULL.
5362  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5363  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5364  *         \a other has number of both tuples and components not equal to 1.
5365  */
5366 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5367 {
5368   if(!other)
5369     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5370   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5371   checkAllocated();
5372   other->checkAllocated();
5373   int nbOfTuple=getNumberOfTuples();
5374   int nbOfTuple2=other->getNumberOfTuples();
5375   int nbOfComp=getNumberOfComponents();
5376   int nbOfComp2=other->getNumberOfComponents();
5377   if(nbOfTuple==nbOfTuple2)
5378     {
5379       if(nbOfComp==nbOfComp2)
5380         {
5381           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5382         }
5383       else if(nbOfComp2==1)
5384         {
5385           double *ptr=getPointer();
5386           const double *ptrc=other->getConstPointer();
5387           for(int i=0;i<nbOfTuple;i++)
5388             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5389         }
5390       else
5391         throw INTERP_KERNEL::Exception(msg);
5392     }
5393   else if(nbOfTuple2==1)
5394     {
5395       if(nbOfComp2==nbOfComp)
5396         {
5397           double *ptr=getPointer();
5398           const double *ptrc=other->getConstPointer();
5399           for(int i=0;i<nbOfTuple;i++)
5400             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5401         }
5402       else
5403         throw INTERP_KERNEL::Exception(msg);
5404     }
5405   else
5406     throw INTERP_KERNEL::Exception(msg);
5407   declareAsNew();
5408 }
5409
5410 /*!
5411  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5412  * valid cases.
5413  * 1.  The arrays have same number of tuples and components. Then each value of
5414  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5415  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5416  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5417  *   component. Then
5418  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5419  * 3.  The arrays have same number of components and one array, say _a2_, has one
5420  *   tuple. Then
5421  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5422  *
5423  * Info on components is copied either from the first array (in the first case) or from
5424  * the array with maximal number of elements (getNbOfElems()).
5425  *  \param [in] a1 - a factor array.
5426  *  \param [in] a2 - another factor array.
5427  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5428  *          The caller is to delete this result array using decrRef() as it is no more
5429  *          needed.
5430  *  \throw If either \a a1 or \a a2 is NULL.
5431  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5432  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5433  *         none of them has number of tuples or components equal to 1.
5434  */
5435 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5436 {
5437   if(!a1 || !a2)
5438     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5439   int nbOfTuple=a1->getNumberOfTuples();
5440   int nbOfTuple2=a2->getNumberOfTuples();
5441   int nbOfComp=a1->getNumberOfComponents();
5442   int nbOfComp2=a2->getNumberOfComponents();
5443   MCAuto<DataArrayDouble> ret=0;
5444   if(nbOfTuple==nbOfTuple2)
5445     {
5446       if(nbOfComp==nbOfComp2)
5447         {
5448           ret=DataArrayDouble::New();
5449           ret->alloc(nbOfTuple,nbOfComp);
5450           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5451           ret->copyStringInfoFrom(*a1);
5452         }
5453       else
5454         {
5455           int nbOfCompMin,nbOfCompMax;
5456           const DataArrayDouble *aMin, *aMax;
5457           if(nbOfComp>nbOfComp2)
5458             {
5459               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5460               aMin=a2; aMax=a1;
5461             }
5462           else
5463             {
5464               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5465               aMin=a1; aMax=a2;
5466             }
5467           if(nbOfCompMin==1)
5468             {
5469               ret=DataArrayDouble::New();
5470               ret->alloc(nbOfTuple,nbOfCompMax);
5471               const double *aMinPtr=aMin->getConstPointer();
5472               const double *aMaxPtr=aMax->getConstPointer();
5473               double *res=ret->getPointer();
5474               for(int i=0;i<nbOfTuple;i++)
5475                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5476               ret->copyStringInfoFrom(*aMax);
5477             }
5478           else
5479             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5480         }
5481     }
5482   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5483     {
5484       if(nbOfComp==nbOfComp2)
5485         {
5486           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5487           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5488           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5489           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5490           ret=DataArrayDouble::New();
5491           ret->alloc(nbOfTupleMax,nbOfComp);
5492           double *res=ret->getPointer();
5493           for(int i=0;i<nbOfTupleMax;i++)
5494             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5495           ret->copyStringInfoFrom(*aMax);
5496         }
5497       else
5498         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5499     }
5500   else
5501     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5502   return ret.retn();
5503 }
5504
5505 /*!
5506  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5507  * valid cases.
5508  * 1.  The arrays have same number of tuples and components. Then each value of
5509  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5510  *   _this_ [ i, j ] *= _other_ [ i, j ].
5511  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5512  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5513  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5514  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5515  *
5516  *  \param [in] other - an array to multiply to \a this one.
5517  *  \throw If \a other is NULL.
5518  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5519  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5520  *         \a other has number of both tuples and components not equal to 1.
5521  */
5522 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5523 {
5524   if(!other)
5525     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5526   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5527   checkAllocated();
5528   other->checkAllocated();
5529   int nbOfTuple=getNumberOfTuples();
5530   int nbOfTuple2=other->getNumberOfTuples();
5531   int nbOfComp=getNumberOfComponents();
5532   int nbOfComp2=other->getNumberOfComponents();
5533   if(nbOfTuple==nbOfTuple2)
5534     {
5535       if(nbOfComp==nbOfComp2)
5536         {
5537           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5538         }
5539       else if(nbOfComp2==1)
5540         {
5541           double *ptr=getPointer();
5542           const double *ptrc=other->getConstPointer();
5543           for(int i=0;i<nbOfTuple;i++)
5544             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5545         }
5546       else
5547         throw INTERP_KERNEL::Exception(msg);
5548     }
5549   else if(nbOfTuple2==1)
5550     {
5551       if(nbOfComp2==nbOfComp)
5552         {
5553           double *ptr=getPointer();
5554           const double *ptrc=other->getConstPointer();
5555           for(int i=0;i<nbOfTuple;i++)
5556             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5557         }
5558       else
5559         throw INTERP_KERNEL::Exception(msg);
5560     }
5561   else
5562     throw INTERP_KERNEL::Exception(msg);
5563   declareAsNew();
5564 }
5565
5566 /*!
5567  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5568  * valid cases.
5569  * 1.  The arrays have same number of tuples and components. Then each value of
5570  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5571  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5572  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5573  *   component. Then
5574  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5575  * 3.  The arrays have same number of components and one array, say _a2_, has one
5576  *   tuple. Then
5577  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5578  *
5579  * Info on components is copied either from the first array (in the first case) or from
5580  * the array with maximal number of elements (getNbOfElems()).
5581  *  \warning No check of division by zero is performed!
5582  *  \param [in] a1 - a numerator array.
5583  *  \param [in] a2 - a denominator array.
5584  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5585  *          The caller is to delete this result array using decrRef() as it is no more
5586  *          needed.
5587  *  \throw If either \a a1 or \a a2 is NULL.
5588  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5589  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5590  *         none of them has number of tuples or components equal to 1.
5591  */
5592 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5593 {
5594   if(!a1 || !a2)
5595     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5596   int nbOfTuple1=a1->getNumberOfTuples();
5597   int nbOfTuple2=a2->getNumberOfTuples();
5598   int nbOfComp1=a1->getNumberOfComponents();
5599   int nbOfComp2=a2->getNumberOfComponents();
5600   if(nbOfTuple2==nbOfTuple1)
5601     {
5602       if(nbOfComp1==nbOfComp2)
5603         {
5604           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5605           ret->alloc(nbOfTuple2,nbOfComp1);
5606           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5607           ret->copyStringInfoFrom(*a1);
5608           return ret.retn();
5609         }
5610       else if(nbOfComp2==1)
5611         {
5612           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5613           ret->alloc(nbOfTuple1,nbOfComp1);
5614           const double *a2Ptr=a2->getConstPointer();
5615           const double *a1Ptr=a1->getConstPointer();
5616           double *res=ret->getPointer();
5617           for(int i=0;i<nbOfTuple1;i++)
5618             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5619           ret->copyStringInfoFrom(*a1);
5620           return ret.retn();
5621         }
5622       else
5623         {
5624           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5625           return 0;
5626         }
5627     }
5628   else if(nbOfTuple2==1)
5629     {
5630       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5631       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5632       ret->alloc(nbOfTuple1,nbOfComp1);
5633       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5634       double *pt=ret->getPointer();
5635       for(int i=0;i<nbOfTuple1;i++)
5636         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5637       ret->copyStringInfoFrom(*a1);
5638       return ret.retn();
5639     }
5640   else
5641     {
5642       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5643       return 0;
5644     }
5645 }
5646
5647 /*!
5648  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5649  * valid cases.
5650  * 1.  The arrays have same number of tuples and components. Then each value of
5651  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5652  *   _a_ [ i, j ] /= _other_ [ i, j ].
5653  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5654  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5655  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5656  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5657  *
5658  *  \warning No check of division by zero is performed!
5659  *  \param [in] other - an array to divide \a this one by.
5660  *  \throw If \a other is NULL.
5661  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5662  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5663  *         \a other has number of both tuples and components not equal to 1.
5664  */
5665 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5666 {
5667   if(!other)
5668     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5669   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5670   checkAllocated();
5671   other->checkAllocated();
5672   int nbOfTuple=getNumberOfTuples();
5673   int nbOfTuple2=other->getNumberOfTuples();
5674   int nbOfComp=getNumberOfComponents();
5675   int nbOfComp2=other->getNumberOfComponents();
5676   if(nbOfTuple==nbOfTuple2)
5677     {
5678       if(nbOfComp==nbOfComp2)
5679         {
5680           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5681         }
5682       else if(nbOfComp2==1)
5683         {
5684           double *ptr=getPointer();
5685           const double *ptrc=other->getConstPointer();
5686           for(int i=0;i<nbOfTuple;i++)
5687             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5688         }
5689       else
5690         throw INTERP_KERNEL::Exception(msg);
5691     }
5692   else if(nbOfTuple2==1)
5693     {
5694       if(nbOfComp2==nbOfComp)
5695         {
5696           double *ptr=getPointer();
5697           const double *ptrc=other->getConstPointer();
5698           for(int i=0;i<nbOfTuple;i++)
5699             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5700         }
5701       else
5702         throw INTERP_KERNEL::Exception(msg);
5703     }
5704   else
5705     throw INTERP_KERNEL::Exception(msg);
5706   declareAsNew();
5707 }
5708
5709 /*!
5710  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5711  * valid cases.
5712  *
5713  *  \param [in] a1 - an array to pow up.
5714  *  \param [in] a2 - another array to sum up.
5715  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5716  *          The caller is to delete this result array using decrRef() as it is no more
5717  *          needed.
5718  *  \throw If either \a a1 or \a a2 is NULL.
5719  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5720  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5721  *  \throw If there is a negative value in \a a1.
5722  */
5723 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5724 {
5725   if(!a1 || !a2)
5726     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5727   int nbOfTuple=a1->getNumberOfTuples();
5728   int nbOfTuple2=a2->getNumberOfTuples();
5729   int nbOfComp=a1->getNumberOfComponents();
5730   int nbOfComp2=a2->getNumberOfComponents();
5731   if(nbOfTuple!=nbOfTuple2)
5732     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5733   if(nbOfComp!=1 || nbOfComp2!=1)
5734     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5735   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5736   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5737   double *ptr=ret->getPointer();
5738   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5739     {
5740       if(*ptr1>=0)
5741         {
5742           *ptr=pow(*ptr1,*ptr2);
5743         }
5744       else
5745         {
5746           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5747           throw INTERP_KERNEL::Exception(oss.str().c_str());
5748         }
5749     }
5750   return ret.retn();
5751 }
5752
5753 /*!
5754  * Apply pow on values of another DataArrayDouble to values of \a this one.
5755  *
5756  *  \param [in] other - an array to pow to \a this one.
5757  *  \throw If \a other is NULL.
5758  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5759  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5760  *  \throw If there is a negative value in \a this.
5761  */
5762 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5763 {
5764   if(!other)
5765     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5766   int nbOfTuple=getNumberOfTuples();
5767   int nbOfTuple2=other->getNumberOfTuples();
5768   int nbOfComp=getNumberOfComponents();
5769   int nbOfComp2=other->getNumberOfComponents();
5770   if(nbOfTuple!=nbOfTuple2)
5771     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5772   if(nbOfComp!=1 || nbOfComp2!=1)
5773     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5774   double *ptr=getPointer();
5775   const double *ptrc=other->begin();
5776   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5777     {
5778       if(*ptr>=0)
5779         *ptr=pow(*ptr,*ptrc);
5780       else
5781         {
5782           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5783           throw INTERP_KERNEL::Exception(oss.str().c_str());
5784         }
5785     }
5786   declareAsNew();
5787 }
5788
5789 /*!
5790  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5791  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5792  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5793  *
5794  * \throw if \a this is not allocated.
5795  * \throw if \a this has not exactly one component.
5796  */
5797 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5798 {
5799   checkAllocated();
5800   if(getNumberOfComponents()!=1)
5801     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5802   int nbt(getNumberOfTuples());
5803   std::vector<bool> ret(nbt);
5804   const double *pt(begin());
5805   for(int i=0;i<nbt;i++)
5806     {
5807       if(fabs(pt[i])<eps)
5808         ret[i]=false;
5809       else if(fabs(pt[i]-1.)<eps)
5810         ret[i]=true;
5811       else
5812         {
5813           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5814           throw INTERP_KERNEL::Exception(oss.str().c_str());
5815         }
5816     }
5817   return ret;
5818 }
5819
5820 /*!
5821  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5822  * Server side.
5823  */
5824 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5825 {
5826   tinyInfo.resize(2);
5827   if(isAllocated())
5828     {
5829       tinyInfo[0]=getNumberOfTuples();
5830       tinyInfo[1]=getNumberOfComponents();
5831     }
5832   else
5833     {
5834       tinyInfo[0]=-1;
5835       tinyInfo[1]=-1;
5836     }
5837 }
5838
5839 /*!
5840  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5841  * Server side.
5842  */
5843 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5844 {
5845   if(isAllocated())
5846     {
5847       int nbOfCompo=getNumberOfComponents();
5848       tinyInfo.resize(nbOfCompo+1);
5849       tinyInfo[0]=getName();
5850       for(int i=0;i<nbOfCompo;i++)
5851         tinyInfo[i+1]=getInfoOnComponent(i);
5852     }
5853   else
5854     {
5855       tinyInfo.resize(1);
5856       tinyInfo[0]=getName();
5857     }
5858 }
5859
5860 /*!
5861  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5862  * This method returns if a feeding is needed.
5863  */
5864 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5865 {
5866   int nbOfTuple=tinyInfoI[0];
5867   int nbOfComp=tinyInfoI[1];
5868   if(nbOfTuple!=-1 || nbOfComp!=-1)
5869     {
5870       alloc(nbOfTuple,nbOfComp);
5871       return true;
5872     }
5873   return false;
5874 }
5875
5876 /*!
5877  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5878  */
5879 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5880 {
5881   setName(tinyInfoS[0]);
5882   if(isAllocated())
5883     {
5884       int nbOfCompo=getNumberOfComponents();
5885       for(int i=0;i<nbOfCompo;i++)
5886         setInfoOnComponent(i,tinyInfoS[i+1]);
5887     }
5888 }
5889
5890 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5891 {
5892   if(_da)
5893     {
5894       _da->incrRef();
5895       if(_da->isAllocated())
5896         {
5897           _nb_comp=da->getNumberOfComponents();
5898           _nb_tuple=da->getNumberOfTuples();
5899           _pt=da->getPointer();
5900         }
5901     }
5902 }
5903
5904 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5905 {
5906   if(_da)
5907     _da->decrRef();
5908 }
5909
5910 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5911 {
5912   if(_tuple_id<_nb_tuple)
5913     {
5914       _tuple_id++;
5915       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5916       _pt+=_nb_comp;
5917       return ret;
5918     }
5919   else
5920     return 0;
5921 }
5922
5923 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5924 {
5925 }
5926
5927
5928 std::string DataArrayDoubleTuple::repr() const
5929 {
5930   std::ostringstream oss; oss.precision(17); oss << "(";
5931   for(int i=0;i<_nb_of_compo-1;i++)
5932     oss << _pt[i] << ", ";
5933   oss << _pt[_nb_of_compo-1] << ")";
5934   return oss.str();
5935 }
5936
5937 double DataArrayDoubleTuple::doubleValue() const
5938 {
5939   if(_nb_of_compo==1)
5940     return *_pt;
5941   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5942 }
5943
5944 /*!
5945  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
5946  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
5947  * 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
5948  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5949  */
5950 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5951 {
5952   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5953     {
5954       DataArrayDouble *ret=DataArrayDouble::New();
5955       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5956       return ret;
5957     }
5958   else
5959     {
5960       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5961       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5962       throw INTERP_KERNEL::Exception(oss.str().c_str());
5963     }
5964 }
5965
5966 /*!
5967  * Returns a new instance of DataArrayInt. The caller is to delete this array
5968  * using decrRef() as it is no more needed. 
5969  */
5970 DataArrayInt *DataArrayInt::New()
5971 {
5972   return new DataArrayInt;
5973 }
5974
5975 /*!
5976  * Checks if raw data is allocated. Read more on the raw data
5977  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5978  *  \return bool - \a true if the raw data is allocated, \a false else.
5979  */
5980 bool DataArrayInt::isAllocated() const
5981 {
5982   return getConstPointer()!=0;
5983 }
5984
5985 /*!
5986  * Checks if raw data is allocated and throws an exception if it is not the case.
5987  *  \throw If the raw data is not allocated.
5988  */
5989 void DataArrayInt::checkAllocated() const
5990 {
5991   if(!isAllocated())
5992     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5993 }
5994
5995 /*!
5996  * This method desallocated \a this without modification of informations relative to the components.
5997  * After call of this method, DataArrayInt::isAllocated will return false.
5998  * If \a this is already not allocated, \a this is let unchanged.
5999  */
6000 void DataArrayInt::desallocate()
6001 {
6002   _mem.destroy();
6003 }
6004
6005 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
6006 {
6007   std::size_t sz(_mem.getNbOfElemAllocated());
6008   sz*=sizeof(int);
6009   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
6010 }
6011
6012 /*!
6013  * Returns the only one value in \a this, if and only if number of elements
6014  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
6015  *  \return double - the sole value stored in \a this array.
6016  *  \throw If at least one of conditions stated above is not fulfilled.
6017  */
6018 int DataArrayInt::intValue() const
6019 {
6020   if(isAllocated())
6021     {
6022       if(getNbOfElems()==1)
6023         {
6024           return *getConstPointer();
6025         }
6026       else
6027         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
6028     }
6029   else
6030     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
6031 }
6032
6033 /*!
6034  * Returns an integer value characterizing \a this array, which is useful for a quick
6035  * comparison of many instances of DataArrayInt.
6036  *  \return int - the hash value.
6037  *  \throw If \a this is not allocated.
6038  */
6039 int DataArrayInt::getHashCode() const
6040 {
6041   checkAllocated();
6042   std::size_t nbOfElems=getNbOfElems();
6043   int ret=nbOfElems*65536;
6044   int delta=3;
6045   if(nbOfElems>48)
6046     delta=nbOfElems/8;
6047   int ret0=0;
6048   const int *pt=begin();
6049   for(std::size_t i=0;i<nbOfElems;i+=delta)
6050     ret0+=pt[i] & 0x1FFF;
6051   return ret+ret0;
6052 }
6053
6054 /*!
6055  * Checks the number of tuples.
6056  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
6057  *  \throw If \a this is not allocated.
6058  */
6059 bool DataArrayInt::empty() const
6060 {
6061   checkAllocated();
6062   return getNumberOfTuples()==0;
6063 }
6064
6065 /*!
6066  * Returns a full copy of \a this. For more info on copying data arrays see
6067  * \ref MEDCouplingArrayBasicsCopyDeep.
6068  *  \return DataArrayInt * - a new instance of DataArrayInt.
6069  */
6070 DataArrayInt *DataArrayInt::deepCopy() const
6071 {
6072   return new DataArrayInt(*this);
6073 }
6074
6075 /*!
6076  * Returns either a \a deep or \a shallow copy of this array. For more info see
6077  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
6078  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
6079  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
6080  *          == \a true) or \a this instance (if \a dCpy == \a false).
6081  */
6082 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
6083 {
6084   if(dCpy)
6085     return deepCopy();
6086   else
6087     {
6088       incrRef();
6089       return const_cast<DataArrayInt *>(this);
6090     }
6091 }
6092
6093 /*!
6094  * Copies all the data from another DataArrayInt. For more info see
6095  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
6096  *  \param [in] other - another instance of DataArrayInt to copy data from.
6097  *  \throw If the \a other is not allocated.
6098  */
6099 void DataArrayInt::deepCopyFrom(const DataArrayInt& other)
6100 {
6101   other.checkAllocated();
6102   int nbOfTuples=other.getNumberOfTuples();
6103   int nbOfComp=other.getNumberOfComponents();
6104   allocIfNecessary(nbOfTuples,nbOfComp);
6105   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6106   int *pt=getPointer();
6107   const int *ptI=other.getConstPointer();
6108   for(std::size_t i=0;i<nbOfElems;i++)
6109     pt[i]=ptI[i];
6110   copyStringInfoFrom(other);
6111 }
6112
6113 /*!
6114  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6115  * 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.
6116  * If \a this has not already been allocated, number of components is set to one.
6117  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6118  * 
6119  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6120  */
6121 void DataArrayInt::reserve(std::size_t nbOfElems)
6122 {
6123   int nbCompo=getNumberOfComponents();
6124   if(nbCompo==1)
6125     {
6126       _mem.reserve(nbOfElems);
6127     }
6128   else if(nbCompo==0)
6129     {
6130       _mem.reserve(nbOfElems);
6131       _info_on_compo.resize(1);
6132     }
6133   else
6134     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6135 }
6136
6137 /*!
6138  * 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
6139  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6140  *
6141  * \param [in] val the value to be added in \a this
6142  * \throw If \a this has already been allocated with number of components different from one.
6143  * \sa DataArrayInt::pushBackValsSilent
6144  */
6145 void DataArrayInt::pushBackSilent(int val)
6146 {
6147   int nbCompo=getNumberOfComponents();
6148   if(nbCompo==1)
6149     _mem.pushBack(val);
6150   else if(nbCompo==0)
6151     {
6152       _info_on_compo.resize(1);
6153       _mem.pushBack(val);
6154     }
6155   else
6156     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6157 }
6158
6159 /*!
6160  * 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
6161  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6162  *
6163  *  \param [in] valsBg - an array of values to push at the end of \c this.
6164  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6165  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6166  * \throw If \a this has already been allocated with number of components different from one.
6167  * \sa DataArrayInt::pushBackSilent
6168  */
6169 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6170 {
6171   int nbCompo=getNumberOfComponents();
6172   if(nbCompo==1)
6173     _mem.insertAtTheEnd(valsBg,valsEnd);
6174   else if(nbCompo==0)
6175     {
6176       _info_on_compo.resize(1);
6177       _mem.insertAtTheEnd(valsBg,valsEnd);
6178     }
6179   else
6180     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6181 }
6182
6183 /*!
6184  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6185  * \throw If \a this is already empty.
6186  * \throw If \a this has number of components different from one.
6187  */
6188 int DataArrayInt::popBackSilent()
6189 {
6190   if(getNumberOfComponents()==1)
6191     return _mem.popBack();
6192   else
6193     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6194 }
6195
6196 /*!
6197  * 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.
6198  *
6199  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6200  */
6201 void DataArrayInt::pack() const
6202 {
6203   _mem.pack();
6204 }
6205
6206 /*!
6207  * Allocates the raw data in memory. If exactly as same memory as needed already
6208  * allocated, it is not re-allocated.
6209  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6210  *  \param [in] nbOfCompo - number of components of data to allocate.
6211  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6212  */
6213 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6214 {
6215   if(isAllocated())
6216     {
6217       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6218         alloc(nbOfTuple,nbOfCompo);
6219     }
6220   else
6221     alloc(nbOfTuple,nbOfCompo);
6222 }
6223
6224 /*!
6225  * Allocates the raw data in memory. If the memory was already allocated, then it is
6226  * freed and re-allocated. See an example of this method use
6227  * \ref MEDCouplingArraySteps1WC "here".
6228  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6229  *  \param [in] nbOfCompo - number of components of data to allocate.
6230  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6231  */
6232 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6233 {
6234   if(nbOfTuple<0 || nbOfCompo<0)
6235     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6236   _info_on_compo.resize(nbOfCompo);
6237   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6238   declareAsNew();
6239 }
6240
6241 /*!
6242  * Assign zero to all values in \a this array. To know more on filling arrays see
6243  * \ref MEDCouplingArrayFill.
6244  * \throw If \a this is not allocated.
6245  */
6246 void DataArrayInt::fillWithZero()
6247 {
6248   checkAllocated();
6249   _mem.fillWithValue(0);
6250   declareAsNew();
6251 }
6252
6253 /*!
6254  * Assign \a val to all values in \a this array. To know more on filling arrays see
6255  * \ref MEDCouplingArrayFill.
6256  *  \param [in] val - the value to fill with.
6257  *  \throw If \a this is not allocated.
6258  */
6259 void DataArrayInt::fillWithValue(int val)
6260 {
6261   checkAllocated();
6262   _mem.fillWithValue(val);
6263   declareAsNew();
6264 }
6265
6266 /*!
6267  * Set all values in \a this array so that the i-th element equals to \a init + i
6268  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6269  *  \param [in] init - value to assign to the first element of array.
6270  *  \throw If \a this->getNumberOfComponents() != 1
6271  *  \throw If \a this is not allocated.
6272  */
6273 void DataArrayInt::iota(int init)
6274 {
6275   checkAllocated();
6276   if(getNumberOfComponents()!=1)
6277     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6278   int *ptr=getPointer();
6279   int ntuples=getNumberOfTuples();
6280   for(int i=0;i<ntuples;i++)
6281     ptr[i]=init+i;
6282   declareAsNew();
6283 }
6284
6285 /*!
6286  * Returns a textual and human readable representation of \a this instance of
6287  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6288  * \return std::string - text describing \a this DataArrayInt.
6289  * 
6290  * \sa reprNotTooLong, reprZip
6291  */
6292 std::string DataArrayInt::repr() const
6293 {
6294   std::ostringstream ret;
6295   reprStream(ret);
6296   return ret.str();
6297 }
6298
6299 std::string DataArrayInt::reprZip() const
6300 {
6301   std::ostringstream ret;
6302   reprZipStream(ret);
6303   return ret.str();
6304 }
6305
6306 /*!
6307  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
6308  * printed out to avoid to consume too much space in interpretor.
6309  * \sa repr
6310  */
6311 std::string DataArrayInt::reprNotTooLong() const
6312 {
6313   std::ostringstream ret;
6314   reprNotTooLongStream(ret);
6315   return ret.str();
6316 }
6317
6318 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6319 {
6320   static const char SPACE[4]={' ',' ',' ',' '};
6321   checkAllocated();
6322   std::string idt(indent,' ');
6323   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6324   if(byteArr)
6325     {
6326       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6327       if(std::string(type)=="Int32")
6328         {
6329           const char *data(reinterpret_cast<const char *>(begin()));
6330           std::size_t sz(getNbOfElems()*sizeof(int));
6331           byteArr->insertAtTheEnd(data,data+sz);
6332           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6333         }
6334       else if(std::string(type)=="Int8")
6335         {
6336           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6337           std::copy(begin(),end(),(char *)tmp);
6338           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6339           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6340         }
6341       else if(std::string(type)=="UInt8")
6342         {
6343           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6344           std::copy(begin(),end(),(unsigned char *)tmp);
6345           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6346           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6347         }
6348       else
6349         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6350     }
6351   else
6352     {
6353       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6354       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6355     }
6356   ofs << std::endl << idt << "</DataArray>\n";
6357 }
6358
6359 void DataArrayInt::reprStream(std::ostream& stream) const
6360 {
6361   stream << "Name of int array : \"" << _name << "\"\n";
6362   reprWithoutNameStream(stream);
6363 }
6364
6365 void DataArrayInt::reprZipStream(std::ostream& stream) const
6366 {
6367   stream << "Name of int array : \"" << _name << "\"\n";
6368   reprZipWithoutNameStream(stream);
6369 }
6370
6371 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
6372 {
6373   stream << "Name of int array : \"" << _name << "\"\n";
6374   reprNotTooLongWithoutNameStream(stream);
6375 }
6376
6377 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6378 {
6379   DataArray::reprWithoutNameStream(stream);
6380   _mem.repr(getNumberOfComponents(),stream);
6381 }
6382
6383 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6384 {
6385   DataArray::reprWithoutNameStream(stream);
6386   _mem.reprZip(getNumberOfComponents(),stream);
6387 }
6388
6389 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
6390 {
6391   DataArray::reprWithoutNameStream(stream);
6392   stream.precision(17);
6393   _mem.reprNotTooLong(getNumberOfComponents(),stream);
6394 }
6395
6396 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6397 {
6398   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6399   const int *data=getConstPointer();
6400   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6401   if(nbTuples*nbComp>=1)
6402     {
6403       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6404       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6405       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6406       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6407     }
6408   else
6409     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6410   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6411 }
6412
6413 /*!
6414  * Method that gives a quick overvien of \a this for python.
6415  */
6416 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6417 {
6418   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6419   stream << "DataArrayInt C++ instance at " << this << ". ";
6420   if(isAllocated())
6421     {
6422       int nbOfCompo=(int)_info_on_compo.size();
6423       if(nbOfCompo>=1)
6424         {
6425           int nbOfTuples=getNumberOfTuples();
6426           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6427           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6428         }
6429       else
6430         stream << "Number of components : 0.";
6431     }
6432   else
6433     stream << "*** No data allocated ****";
6434 }
6435
6436 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6437 {
6438   const int *data=begin();
6439   int nbOfTuples=getNumberOfTuples();
6440   int nbOfCompo=(int)_info_on_compo.size();
6441   std::ostringstream oss2; oss2 << "[";
6442   std::string oss2Str(oss2.str());
6443   bool isFinished=true;
6444   for(int i=0;i<nbOfTuples && isFinished;i++)
6445     {
6446       if(nbOfCompo>1)
6447         {
6448           oss2 << "(";
6449           for(int j=0;j<nbOfCompo;j++,data++)
6450             {
6451               oss2 << *data;
6452               if(j!=nbOfCompo-1) oss2 << ", ";
6453             }
6454           oss2 << ")";
6455         }
6456       else
6457         oss2 << *data++;
6458       if(i!=nbOfTuples-1) oss2 << ", ";
6459       std::string oss3Str(oss2.str());
6460       if(oss3Str.length()<maxNbOfByteInRepr)
6461         oss2Str=oss3Str;
6462       else
6463         isFinished=false;
6464     }
6465   stream << oss2Str;
6466   if(!isFinished)
6467     stream << "... ";
6468   stream << "]";
6469 }
6470
6471 /*!
6472  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6473  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6474  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6475  *         to \a this array.
6476  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6477  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6478  *  \throw If \a this->getNumberOfComponents() != 1
6479  *  \throw If any value of \a this can't be used as a valid index for 
6480  *         [\a indArrBg, \a indArrEnd).
6481  *
6482  *  \sa changeValue
6483  */
6484 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6485 {
6486   checkAllocated();
6487   if(getNumberOfComponents()!=1)
6488     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6489   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6490   for(int i=0;i<nbOfTuples;i++,pt++)
6491     {
6492       if(*pt>=0 && *pt<nbElemsIn)
6493         *pt=indArrBg[*pt];
6494       else
6495         {
6496           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6497           throw INTERP_KERNEL::Exception(oss.str().c_str());
6498         }
6499     }
6500   declareAsNew();
6501 }
6502
6503 /*!
6504  * Computes distribution of values of \a this one-dimensional array between given value
6505  * ranges (casts). This method is typically useful for entity number spliting by types,
6506  * for example. 
6507  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6508  *           check of this is be done. If not, the result is not warranted. 
6509  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6510  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6511  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6512  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6513  *         should be more than every value in \a this array.
6514  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6515  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6516  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6517  *         (same number of tuples and components), the caller is to delete 
6518  *         using decrRef() as it is no more needed.
6519  *         This array contains indices of ranges for every value of \a this array. I.e.
6520  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6521  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6522  *         this in which cast it holds.
6523  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6524  *         array, the caller is to delete using decrRef() as it is no more needed.
6525  *         This array contains ranks of values of \a this array within ranges
6526  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6527  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6528  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6529  *         for each tuple its rank inside its cast. The rank is computed as difference
6530  *         between the value and the lowest value of range.
6531  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6532  *         ranges (casts) to which at least one value of \a this array belongs.
6533  *         Or, in other words, this param contains the casts that \a this contains.
6534  *         The caller is to delete this array using decrRef() as it is no more needed.
6535  *
6536  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6537  *            the output of this method will be : 
6538  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6539  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6540  * - \a castsPresent  : [0,1]
6541  *
6542  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6543  * range #1 and its rank within this range is 2; etc.
6544  *
6545  *  \throw If \a this->getNumberOfComponents() != 1.
6546  *  \throw If \a arrEnd - arrBg < 2.
6547  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6548  */
6549 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6550                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6551 {
6552   checkAllocated();
6553   if(getNumberOfComponents()!=1)
6554     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6555   int nbOfTuples=getNumberOfTuples();
6556   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6557   if(nbOfCast<2)
6558     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6559   nbOfCast--;
6560   const int *work=getConstPointer();
6561   typedef std::reverse_iterator<const int *> rintstart;
6562   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6563   rintstart end2(arrBg);
6564   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
6565   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
6566   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
6567   ret1->alloc(nbOfTuples,1);
6568   ret2->alloc(nbOfTuples,1);
6569   int *ret1Ptr=ret1->getPointer();
6570   int *ret2Ptr=ret2->getPointer();
6571   std::set<std::size_t> castsDetected;
6572   for(int i=0;i<nbOfTuples;i++)
6573     {
6574       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6575       std::size_t pos=std::distance(bg,res);
6576       std::size_t pos2=nbOfCast-pos;
6577       if(pos2<nbOfCast)
6578         {
6579           ret1Ptr[i]=(int)pos2;
6580           ret2Ptr[i]=work[i]-arrBg[pos2];
6581           castsDetected.insert(pos2);
6582         }
6583       else
6584         {
6585           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6586           throw INTERP_KERNEL::Exception(oss.str().c_str());
6587         }
6588     }
6589   ret3->alloc((int)castsDetected.size(),1);
6590   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6591   castArr=ret1.retn();
6592   rankInsideCast=ret2.retn();
6593   castsPresent=ret3.retn();
6594 }
6595
6596 /*!
6597  * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ).
6598  * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ).
6599  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6600  *
6601  * \param [out] strt - the start of the range (included) if true is returned.
6602  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6603  * \param [out] stteepp - the step of the range if true is returned.
6604  * \return the verdict of the check.
6605  *
6606  * \sa DataArray::GetNumberOfItemGivenBES
6607  */
6608 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6609 {
6610   checkAllocated();
6611   if(getNumberOfComponents()!=1)
6612     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6613   int nbTuples(getNumberOfTuples());
6614   if(nbTuples==0)
6615     { strt=0; sttoopp=0; stteepp=1; return true; }
6616   const int *pt(begin());
6617   strt=*pt; 
6618   if(nbTuples==1)
6619     { sttoopp=strt+1; stteepp=1; return true; }
6620   strt=*pt; sttoopp=pt[nbTuples-1];
6621   if(strt==sttoopp)
6622     return false;
6623   if(sttoopp>strt)
6624     {
6625       sttoopp++;
6626       int a(sttoopp-1-strt),tmp(strt);
6627       if(a%(nbTuples-1)!=0)
6628         return false;
6629       stteepp=a/(nbTuples-1);
6630       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6631         if(pt[i]!=tmp)
6632           return false;
6633       return true;
6634     }
6635   else
6636     {
6637       sttoopp--;
6638       int a(strt-sttoopp-1),tmp(strt);
6639       if(a%(nbTuples-1)!=0)
6640         return false;
6641       stteepp=-(a/(nbTuples-1));
6642       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6643         if(pt[i]!=tmp)
6644           return false;
6645       return true;
6646     }
6647 }
6648
6649 /*!
6650  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6651  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6652  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6653  * new value in place \a indArr[ \a v ] is i.
6654  *  \param [in] indArrBg - the array holding indices within the result array to assign
6655  *         indices of values of \a this array pointing to values of \a indArrBg.
6656  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6657  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6658  *  \return DataArrayInt * - the new instance of DataArrayInt.
6659  *          The caller is to delete this result array using decrRef() as it is no more
6660  *          needed.
6661  *  \throw If \a this->getNumberOfComponents() != 1.
6662  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6663  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6664  */
6665 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6666 {
6667   checkAllocated();
6668   if(getNumberOfComponents()!=1)
6669     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6670   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6671   int nbOfTuples=getNumberOfTuples();
6672   const int *pt=getConstPointer();
6673   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6674   ret->alloc(nbOfTuples,1);
6675   ret->fillWithValue(-1);
6676   int *tmp=ret->getPointer();
6677   for(int i=0;i<nbOfTuples;i++,pt++)
6678     {
6679       if(*pt>=0 && *pt<nbElemsIn)
6680         {
6681           int pos=indArrBg[*pt];
6682           if(pos>=0 && pos<nbOfTuples)
6683             tmp[pos]=i;
6684           else
6685             {
6686               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6687               throw INTERP_KERNEL::Exception(oss.str().c_str());
6688             }
6689         }
6690       else
6691         {
6692           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6693           throw INTERP_KERNEL::Exception(oss.str().c_str());
6694         }
6695     }
6696   return ret.retn();
6697 }
6698
6699 /*!
6700  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6701  * from values of \a this array, which is supposed to contain a renumbering map in 
6702  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6703  * To know how to use the renumbering maps see \ref numbering.
6704  *  \param [in] newNbOfElem - the number of tuples in the result array.
6705  *  \return DataArrayInt * - the new instance of DataArrayInt.
6706  *          The caller is to delete this result array using decrRef() as it is no more
6707  *          needed.
6708  * 
6709  *  \if ENABLE_EXAMPLES
6710  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6711  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6712  *  \endif
6713  */
6714 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6715 {
6716   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6717   ret->alloc(newNbOfElem,1);
6718   int nbOfOldNodes=getNumberOfTuples();
6719   const int *old2New=getConstPointer();
6720   int *pt=ret->getPointer();
6721   for(int i=0;i!=nbOfOldNodes;i++)
6722     {
6723       int newp(old2New[i]);
6724       if(newp!=-1)
6725         {
6726           if(newp>=0 && newp<newNbOfElem)
6727             pt[newp]=i;
6728           else
6729             {
6730               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6731               throw INTERP_KERNEL::Exception(oss.str().c_str());
6732             }
6733         }
6734     }
6735   return ret.retn();
6736 }
6737
6738 /*!
6739  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6740  * 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]
6741  */
6742 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6743 {
6744   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6745   ret->alloc(newNbOfElem,1);
6746   int nbOfOldNodes=getNumberOfTuples();
6747   const int *old2New=getConstPointer();
6748   int *pt=ret->getPointer();
6749   for(int i=nbOfOldNodes-1;i>=0;i--)
6750     {
6751       int newp(old2New[i]);
6752       if(newp!=-1)
6753         {
6754           if(newp>=0 && newp<newNbOfElem)
6755             pt[newp]=i;
6756           else
6757             {
6758               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6759               throw INTERP_KERNEL::Exception(oss.str().c_str());
6760             }
6761         }
6762     }
6763   return ret.retn();
6764 }
6765
6766 /*!
6767  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6768  * from values of \a this array, which is supposed to contain a renumbering map in 
6769  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6770  * To know how to use the renumbering maps see \ref numbering.
6771  *  \param [in] newNbOfElem - the number of tuples in the result array.
6772  *  \return DataArrayInt * - the new instance of DataArrayInt.
6773  *          The caller is to delete this result array using decrRef() as it is no more
6774  *          needed.
6775  * 
6776  *  \if ENABLE_EXAMPLES
6777  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6778  *
6779  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6780  *  \endif
6781  */
6782 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6783 {
6784   checkAllocated();
6785   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6786   ret->alloc(oldNbOfElem,1);
6787   const int *new2Old=getConstPointer();
6788   int *pt=ret->getPointer();
6789   std::fill(pt,pt+oldNbOfElem,-1);
6790   int nbOfNewElems=getNumberOfTuples();
6791   for(int i=0;i<nbOfNewElems;i++)
6792     {
6793       int v(new2Old[i]);
6794       if(v>=0 && v<oldNbOfElem)
6795         pt[v]=i;
6796       else
6797         {
6798           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6799           throw INTERP_KERNEL::Exception(oss.str().c_str());
6800         }
6801     }
6802   return ret.retn();
6803 }
6804
6805 /*!
6806  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6807  * mismatch is given.
6808  * 
6809  * \param [in] other the instance to be compared with \a this
6810  * \param [out] reason In case of inequality returns the reason.
6811  * \sa DataArrayInt::isEqual
6812  */
6813 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6814 {
6815   if(!areInfoEqualsIfNotWhy(other,reason))
6816     return false;
6817   return _mem.isEqual(other._mem,0,reason);
6818 }
6819
6820 /*!
6821  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6822  * \ref MEDCouplingArrayBasicsCompare.
6823  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6824  *  \return bool - \a true if the two arrays are equal, \a false else.
6825  */
6826 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6827 {
6828   std::string tmp;
6829   return isEqualIfNotWhy(other,tmp);
6830 }
6831
6832 /*!
6833  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6834  * \ref MEDCouplingArrayBasicsCompare.
6835  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6836  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6837  */
6838 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6839 {
6840   std::string tmp;
6841   return _mem.isEqual(other._mem,0,tmp);
6842 }
6843
6844 /*!
6845  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6846  * performed on sorted value sequences.
6847  * For more info see\ref MEDCouplingArrayBasicsCompare.
6848  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6849  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6850  */
6851 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6852 {
6853   MCAuto<DataArrayInt> a=deepCopy();
6854   MCAuto<DataArrayInt> b=other.deepCopy();
6855   a->sort();
6856   b->sort();
6857   return a->isEqualWithoutConsideringStr(*b);
6858 }
6859
6860 /*!
6861  * This method compares content of input vector \a v and \a this.
6862  * 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.
6863  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6864  *
6865  * \param [in] v - the vector of 'flags' to be compared with \a this.
6866  *
6867  * \throw If \a this is not sorted ascendingly.
6868  * \throw If \a this has not exactly one component.
6869  * \throw If \a this is not allocated.
6870  */
6871 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6872 {
6873   checkAllocated();
6874   if(getNumberOfComponents()!=1)
6875     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6876   const int *w(begin()),*end2(end());
6877   int refVal=-std::numeric_limits<int>::max();
6878   int i=0;
6879   std::vector<bool>::const_iterator it(v.begin());
6880   for(;it!=v.end();it++,i++)
6881     {
6882       if(*it)
6883         {
6884           if(w!=end2)
6885             {
6886               if(*w++==i)
6887                 {
6888                   if(i>refVal)
6889                     refVal=i;
6890                   else
6891                     {
6892                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6893                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6894                     }
6895                 }
6896               else
6897                 return false;
6898             }
6899           else
6900             return false;
6901         }
6902     }
6903   return w==end2;
6904 }
6905
6906 /*!
6907  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
6908  * put True to the corresponding entry in \a vec.
6909  * \a vec is expected to be with the same size than the number of tuples of \a this.
6910  */
6911 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6912 {
6913   checkAllocated();
6914   if(getNumberOfComponents()!=1)
6915     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6916   int nbOfTuples(getNumberOfTuples());
6917   if(nbOfTuples!=(int)vec.size())
6918     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6919   const int *pt(begin());
6920   for(int i=0;i<nbOfTuples;i++)
6921     if(pt[i]==val)
6922       vec[i]=true;
6923 }
6924
6925 /*!
6926  * Sorts values of the array.
6927  *  \param [in] asc - \a true means ascending order, \a false, descending.
6928  *  \throw If \a this is not allocated.
6929  *  \throw If \a this->getNumberOfComponents() != 1.
6930  */
6931 void DataArrayInt::sort(bool asc)
6932 {
6933   checkAllocated();
6934   if(getNumberOfComponents()!=1)
6935     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6936   _mem.sort(asc);
6937   declareAsNew();
6938 }
6939
6940 /*!
6941  * Computes for each tuple the sum of number of components values in the tuple and return it.
6942  * 
6943  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6944  *          same number of tuples as \a this array and one component.
6945  *          The caller is to delete this result array using decrRef() as it is no more
6946  *          needed.
6947  *  \throw If \a this is not allocated.
6948  */
6949 DataArrayInt *DataArrayInt::sumPerTuple() const
6950 {
6951   checkAllocated();
6952   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6953   MCAuto<DataArrayInt> ret(DataArrayInt::New());
6954   ret->alloc(nbOfTuple,1);
6955   const int *src(getConstPointer());
6956   int *dest(ret->getPointer());
6957   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6958     *dest=std::accumulate(src,src+nbOfComp,0);
6959   return ret.retn();
6960 }
6961
6962 /*!
6963  * Reverse the array values.
6964  *  \throw If \a this->getNumberOfComponents() < 1.
6965  *  \throw If \a this is not allocated.
6966  */
6967 void DataArrayInt::reverse()
6968 {
6969   checkAllocated();
6970   _mem.reverse(getNumberOfComponents());
6971   declareAsNew();
6972 }
6973
6974 /*!
6975  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6976  * If not an exception is thrown.
6977  *  \param [in] increasing - if \a true, the array values should be increasing.
6978  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6979  *         increasing arg.
6980  *  \throw If \a this->getNumberOfComponents() != 1.
6981  *  \throw If \a this is not allocated.
6982  */
6983 void DataArrayInt::checkMonotonic(bool increasing) const
6984 {
6985   if(!isMonotonic(increasing))
6986     {
6987       if (increasing)
6988         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6989       else
6990         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6991     }
6992 }
6993
6994 /*!
6995  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6996  *  \param [in] increasing - if \a true, array values should be increasing.
6997  *  \return bool - \a true if values change in accordance with \a increasing arg.
6998  *  \throw If \a this->getNumberOfComponents() != 1.
6999  *  \throw If \a this is not allocated.
7000  */
7001 bool DataArrayInt::isMonotonic(bool increasing) const
7002 {
7003   checkAllocated();
7004   if(getNumberOfComponents()!=1)
7005     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
7006   int nbOfElements=getNumberOfTuples();
7007   const int *ptr=getConstPointer();
7008   if(nbOfElements==0)
7009     return true;
7010   int ref=ptr[0];
7011   if(increasing)
7012     {
7013       for(int i=1;i<nbOfElements;i++)
7014         {
7015           if(ptr[i]>=ref)
7016             ref=ptr[i];
7017           else
7018             return false;
7019         }
7020     }
7021   else
7022     {
7023       for(int i=1;i<nbOfElements;i++)
7024         {
7025           if(ptr[i]<=ref)
7026             ref=ptr[i];
7027           else
7028             return false;
7029         }
7030     }
7031   return true;
7032 }
7033
7034 /*!
7035  * This method check that array consistently INCREASING or DECREASING in value.
7036  */
7037 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
7038 {
7039   checkAllocated();
7040   if(getNumberOfComponents()!=1)
7041     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
7042   int nbOfElements=getNumberOfTuples();
7043   const int *ptr=getConstPointer();
7044   if(nbOfElements==0)
7045     return true;
7046   int ref=ptr[0];
7047   if(increasing)
7048     {
7049       for(int i=1;i<nbOfElements;i++)
7050         {
7051           if(ptr[i]>ref)
7052             ref=ptr[i];
7053           else
7054             return false;
7055         }
7056     }
7057   else
7058     {
7059       for(int i=1;i<nbOfElements;i++)
7060         {
7061           if(ptr[i]<ref)
7062             ref=ptr[i];
7063           else
7064             return false;
7065         }
7066     }
7067   return true;
7068 }
7069
7070 /*!
7071  * This method check that array consistently INCREASING or DECREASING in value.
7072  */
7073 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
7074 {
7075   if(!isStrictlyMonotonic(increasing))
7076     {
7077       if (increasing)
7078         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
7079       else
7080         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
7081     }
7082 }
7083
7084 /*!
7085  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
7086  * one-dimensional arrays that must be of the same length. The result array describes
7087  * correspondence between \a this and \a other arrays, so that 
7088  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
7089  * not possible because some element in \a other is not in \a this, an exception is thrown.
7090  *  \param [in] other - an array to compute permutation to.
7091  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
7092  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
7093  * no more needed.
7094  *  \throw If \a this->getNumberOfComponents() != 1.
7095  *  \throw If \a other->getNumberOfComponents() != 1.
7096  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
7097  *  \throw If \a other includes a value which is not in \a this array.
7098  * 
7099  *  \if ENABLE_EXAMPLES
7100  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
7101  *
7102  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
7103  *  \endif
7104  */
7105 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
7106 {
7107   checkAllocated();
7108   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
7109     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
7110   int nbTuple=getNumberOfTuples();
7111   other.checkAllocated();
7112   if(nbTuple!=other.getNumberOfTuples())
7113     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
7114   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7115   ret->alloc(nbTuple,1);
7116   ret->fillWithValue(-1);
7117   const int *pt=getConstPointer();
7118   std::map<int,int> mm;
7119   for(int i=0;i<nbTuple;i++)
7120     mm[pt[i]]=i;
7121   pt=other.getConstPointer();
7122   int *retToFill=ret->getPointer();
7123   for(int i=0;i<nbTuple;i++)
7124     {
7125       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7126       if(it==mm.end())
7127         {
7128           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7129           throw INTERP_KERNEL::Exception(oss.str().c_str());
7130         }
7131       retToFill[i]=(*it).second;
7132     }
7133   return ret.retn();
7134 }
7135
7136 /*!
7137  * Sets a C array to be used as raw data of \a this. The previously set info
7138  *  of components is retained and re-sized. 
7139  * For more info see \ref MEDCouplingArraySteps1.
7140  *  \param [in] array - the C array to be used as raw data of \a this.
7141  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7142  *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
7143  *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
7144  *                     \c free(\c array ) will be called.
7145  *  \param [in] nbOfTuple - new number of tuples in \a this.
7146  *  \param [in] nbOfCompo - new number of components in \a this.
7147  */
7148 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7149 {
7150   _info_on_compo.resize(nbOfCompo);
7151   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7152   declareAsNew();
7153 }
7154
7155 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7156 {
7157   _info_on_compo.resize(nbOfCompo);
7158   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7159   declareAsNew();
7160 }
7161
7162 /*!
7163  * Returns a new DataArrayInt holding the same values as \a this array but differently
7164  * arranged in memory. If \a this array holds 2 components of 3 values:
7165  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7166  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7167  *  \warning Do not confuse this method with transpose()!
7168  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7169  *          is to delete using decrRef() as it is no more needed.
7170  *  \throw If \a this is not allocated.
7171  */
7172 DataArrayInt *DataArrayInt::fromNoInterlace() const
7173 {
7174   checkAllocated();
7175   if(_mem.isNull())
7176     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7177   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7178   DataArrayInt *ret=DataArrayInt::New();
7179   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7180   return ret;
7181 }
7182
7183 /*!
7184  * Returns a new DataArrayInt holding the same values as \a this array but differently
7185  * arranged in memory. If \a this array holds 2 components of 3 values:
7186  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7187  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7188  *  \warning Do not confuse this method with transpose()!
7189  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7190  *          is to delete using decrRef() as it is no more needed.
7191  *  \throw If \a this is not allocated.
7192  */
7193 DataArrayInt *DataArrayInt::toNoInterlace() const
7194 {
7195   checkAllocated();
7196   if(_mem.isNull())
7197     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7198   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7199   DataArrayInt *ret=DataArrayInt::New();
7200   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7201   return ret;
7202 }
7203
7204 /*!
7205  * Permutes values of \a this array as required by \a old2New array. The values are
7206  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7207  * the same as in \c this one.
7208  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7209  * For more info on renumbering see \ref numbering.
7210  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7211  *     giving a new position for i-th old value.
7212  */
7213 void DataArrayInt::renumberInPlace(const int *old2New)
7214 {
7215   checkAllocated();
7216   int nbTuples=getNumberOfTuples();
7217   int nbOfCompo=getNumberOfComponents();
7218   int *tmp=new int[nbTuples*nbOfCompo];
7219   const int *iptr=getConstPointer();
7220   for(int i=0;i<nbTuples;i++)
7221     {
7222       int v=old2New[i];
7223       if(v>=0 && v<nbTuples)
7224         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7225       else
7226         {
7227           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7228           throw INTERP_KERNEL::Exception(oss.str().c_str());
7229         }
7230     }
7231   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7232   delete [] tmp;
7233   declareAsNew();
7234 }
7235
7236 /*!
7237  * Permutes values of \a this array as required by \a new2Old array. The values are
7238  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7239  * the same as in \c this one.
7240  * For more info on renumbering see \ref numbering.
7241  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7242  *     giving a previous position of i-th new value.
7243  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7244  *          is to delete using decrRef() as it is no more needed.
7245  */
7246 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7247 {
7248   checkAllocated();
7249   int nbTuples=getNumberOfTuples();
7250   int nbOfCompo=getNumberOfComponents();
7251   int *tmp=new int[nbTuples*nbOfCompo];
7252   const int *iptr=getConstPointer();
7253   for(int i=0;i<nbTuples;i++)
7254     {
7255       int v=new2Old[i];
7256       if(v>=0 && v<nbTuples)
7257         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7258       else
7259         {
7260           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7261           throw INTERP_KERNEL::Exception(oss.str().c_str());
7262         }
7263     }
7264   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7265   delete [] tmp;
7266   declareAsNew();
7267 }
7268
7269 /*!
7270  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7271  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7272  * Number of tuples in the result array remains the same as in \c this one.
7273  * If a permutation reduction is needed, renumberAndReduce() should be used.
7274  * For more info on renumbering see \ref numbering.
7275  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7276  *          giving a new position for i-th old value.
7277  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7278  *          is to delete using decrRef() as it is no more needed.
7279  *  \throw If \a this is not allocated.
7280  */
7281 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7282 {
7283   checkAllocated();
7284   int nbTuples=getNumberOfTuples();
7285   int nbOfCompo=getNumberOfComponents();
7286   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7287   ret->alloc(nbTuples,nbOfCompo);
7288   ret->copyStringInfoFrom(*this);
7289   const int *iptr=getConstPointer();
7290   int *optr=ret->getPointer();
7291   for(int i=0;i<nbTuples;i++)
7292     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7293   ret->copyStringInfoFrom(*this);
7294   return ret.retn();
7295 }
7296
7297 /*!
7298  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7299  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7300  * tuples in the result array remains the same as in \c this one.
7301  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7302  * For more info on renumbering see \ref numbering.
7303  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7304  *     giving a previous position of i-th new value.
7305  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7306  *          is to delete using decrRef() as it is no more needed.
7307  */
7308 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7309 {
7310   checkAllocated();
7311   int nbTuples=getNumberOfTuples();
7312   int nbOfCompo=getNumberOfComponents();
7313   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7314   ret->alloc(nbTuples,nbOfCompo);
7315   ret->copyStringInfoFrom(*this);
7316   const int *iptr=getConstPointer();
7317   int *optr=ret->getPointer();
7318   for(int i=0;i<nbTuples;i++)
7319     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7320   ret->copyStringInfoFrom(*this);
7321   return ret.retn();
7322 }
7323
7324 /*!
7325  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7326  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7327  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7328  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7329  * \a old2New[ i ] is negative, is missing from the result array.
7330  * For more info on renumbering see \ref numbering.
7331  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7332  *     giving a new position for i-th old tuple and giving negative position for
7333  *     for i-th old tuple that should be omitted.
7334  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7335  *          is to delete using decrRef() as it is no more needed.
7336  */
7337 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7338 {
7339   checkAllocated();
7340   int nbTuples=getNumberOfTuples();
7341   int nbOfCompo=getNumberOfComponents();
7342   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7343   ret->alloc(newNbOfTuple,nbOfCompo);
7344   const int *iptr=getConstPointer();
7345   int *optr=ret->getPointer();
7346   for(int i=0;i<nbTuples;i++)
7347     {
7348       int w=old2New[i];
7349       if(w>=0)
7350         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7351     }
7352   ret->copyStringInfoFrom(*this);
7353   return ret.retn();
7354 }
7355
7356 /*!
7357  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7358  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7359  * \a new2OldBg array.
7360  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7361  * This method is equivalent to renumberAndReduce() except that convention in input is
7362  * \c new2old and \b not \c old2new.
7363  * For more info on renumbering see \ref numbering.
7364  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7365  *              tuple index in \a this array to fill the i-th tuple in the new array.
7366  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7367  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7368  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7369  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7370  *          is to delete using decrRef() as it is no more needed.
7371  */
7372 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7373 {
7374   checkAllocated();
7375   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7376   int nbComp=getNumberOfComponents();
7377   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7378   ret->copyStringInfoFrom(*this);
7379   int *pt=ret->getPointer();
7380   const int *srcPt=getConstPointer();
7381   int i=0;
7382   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7383     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7384   ret->copyStringInfoFrom(*this);
7385   return ret.retn();
7386 }
7387
7388 /*!
7389  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7390  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7391  * \a new2OldBg array.
7392  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7393  * This method is equivalent to renumberAndReduce() except that convention in input is
7394  * \c new2old and \b not \c old2new.
7395  * This method is equivalent to selectByTupleId() except that it prevents coping data
7396  * from behind the end of \a this array.
7397  * For more info on renumbering see \ref numbering.
7398  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7399  *              tuple index in \a this array to fill the i-th tuple in the new array.
7400  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7401  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7402  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7403  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7404  *          is to delete using decrRef() as it is no more needed.
7405  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7406  */
7407 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7408 {
7409   checkAllocated();
7410   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7411   int nbComp=getNumberOfComponents();
7412   int oldNbOfTuples=getNumberOfTuples();
7413   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7414   ret->copyStringInfoFrom(*this);
7415   int *pt=ret->getPointer();
7416   const int *srcPt=getConstPointer();
7417   int i=0;
7418   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7419     if(*w>=0 && *w<oldNbOfTuples)
7420       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7421     else
7422       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7423   ret->copyStringInfoFrom(*this);
7424   return ret.retn();
7425 }
7426
7427 /*!
7428  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7429  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7430  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7431  * command \c range( \a bg, \a end2, \a step ).
7432  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7433  * not constructed explicitly.
7434  * For more info on renumbering see \ref numbering.
7435  *  \param [in] bg - index of the first tuple to copy from \a this array.
7436  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7437  *  \param [in] step - index increment to get index of the next tuple to copy.
7438  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7439  *          is to delete using decrRef() as it is no more needed.
7440  *  \sa DataArrayInt::subArray.
7441  */
7442 DataArrayInt *DataArrayInt::selectByTupleIdSafeSlice(int bg, int end2, int step) const
7443 {
7444   checkAllocated();
7445   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7446   int nbComp=getNumberOfComponents();
7447   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleIdSafeSlice : ");
7448   ret->alloc(newNbOfTuples,nbComp);
7449   int *pt=ret->getPointer();
7450   const int *srcPt=getConstPointer()+bg*nbComp;
7451   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7452     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7453   ret->copyStringInfoFrom(*this);
7454   return ret.retn();
7455 }
7456
7457 /*!
7458  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7459  * of tuples specified by \a ranges parameter.
7460  * For more info on renumbering see \ref numbering.
7461  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7462  *              of tuples in [\c begin,\c end) format.
7463  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7464  *          is to delete using decrRef() as it is no more needed.
7465  *  \throw If \a end < \a begin.
7466  *  \throw If \a end > \a this->getNumberOfTuples().
7467  *  \throw If \a this is not allocated.
7468  */
7469 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7470 {
7471   checkAllocated();
7472   int nbOfComp=getNumberOfComponents();
7473   int nbOfTuplesThis=getNumberOfTuples();
7474   if(ranges.empty())
7475     {
7476       MCAuto<DataArrayInt> ret=DataArrayInt::New();
7477       ret->alloc(0,nbOfComp);
7478       ret->copyStringInfoFrom(*this);
7479       return ret.retn();
7480     }
7481   int ref=ranges.front().first;
7482   int nbOfTuples=0;
7483   bool isIncreasing=true;
7484   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7485     {
7486       if((*it).first<=(*it).second)
7487         {
7488           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7489             {
7490               nbOfTuples+=(*it).second-(*it).first;
7491               if(isIncreasing)
7492                 isIncreasing=ref<=(*it).first;
7493               ref=(*it).second;
7494             }
7495           else
7496             {
7497               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7498               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7499               throw INTERP_KERNEL::Exception(oss.str().c_str());
7500             }
7501         }
7502       else
7503         {
7504           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7505           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7506           throw INTERP_KERNEL::Exception(oss.str().c_str());
7507         }
7508     }
7509   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7510     return deepCopy();
7511   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7512   ret->alloc(nbOfTuples,nbOfComp);
7513   ret->copyStringInfoFrom(*this);
7514   const int *src=getConstPointer();
7515   int *work=ret->getPointer();
7516   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7517     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7518   return ret.retn();
7519 }
7520
7521 /*!
7522  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7523  * This map, if applied to \a this array, would make it sorted. For example, if
7524  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7525  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7526  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7527  * This method is useful for renumbering (in MED file for example). For more info
7528  * on renumbering see \ref numbering.
7529  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7530  *          array using decrRef() as it is no more needed.
7531  *  \throw If \a this is not allocated.
7532  *  \throw If \a this->getNumberOfComponents() != 1.
7533  *  \throw If there are equal values in \a this array.
7534  */
7535 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7536 {
7537   checkAllocated();
7538   if(getNumberOfComponents()!=1)
7539     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7540   int nbTuples=getNumberOfTuples();
7541   const int *pt=getConstPointer();
7542   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7543   DataArrayInt *ret=DataArrayInt::New();
7544   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7545   return ret;
7546 }
7547
7548 /*!
7549  * 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
7550  * input array \a ids2.
7551  * \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.
7552  * 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
7553  * inversely.
7554  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7555  *
7556  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7557  *          array using decrRef() as it is no more needed.
7558  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7559  * 
7560  */
7561 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7562 {
7563   if(!ids1 || !ids2)
7564     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7565   if(!ids1->isAllocated() || !ids2->isAllocated())
7566     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7567   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7568     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7569   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7570     {
7571       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 !";
7572       throw INTERP_KERNEL::Exception(oss.str().c_str());
7573     }
7574   MCAuto<DataArrayInt> p1(ids1->deepCopy());
7575   MCAuto<DataArrayInt> p2(ids2->deepCopy());
7576   p1->sort(true); p2->sort(true);
7577   if(!p1->isEqualWithoutConsideringStr(*p2))
7578     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7579   p1=ids1->checkAndPreparePermutation();
7580   p2=ids2->checkAndPreparePermutation();
7581   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7582   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7583   return p2.retn();
7584 }
7585
7586 /*!
7587  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7588  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7589  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7590  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7591  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7592  * The first of out arrays returns indices of elements of \a this array, grouped by their
7593  * place in the set \a B. The second out array is the index of the first one; it shows how
7594  * many elements of \a A are mapped into each element of \a B. <br>
7595  * For more info on
7596  * mapping and its usage in renumbering see \ref numbering. <br>
7597  * \b Example:
7598  * - \a this: [0,3,2,3,2,2,1,2]
7599  * - \a targetNb: 4
7600  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7601  * - \a arrI: [0,1,2,6,8]
7602  *
7603  * This result means: <br>
7604  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7605  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7606  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7607  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7608  * \a arrI[ 2+1 ]]); <br> etc.
7609  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7610  *         than the maximal value of \a A.
7611  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7612  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7613  *         this array using decrRef() as it is no more needed.
7614  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7615  *         elements of \a this. The caller is to delete this array using decrRef() as it
7616  *         is no more needed.
7617  *  \throw If \a this is not allocated.
7618  *  \throw If \a this->getNumberOfComponents() != 1.
7619  *  \throw If any value in \a this is more or equal to \a targetNb.
7620  */
7621 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7622 {
7623   checkAllocated();
7624   if(getNumberOfComponents()!=1)
7625     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7626   int nbOfTuples=getNumberOfTuples();
7627   MCAuto<DataArrayInt> ret(DataArrayInt::New());
7628   MCAuto<DataArrayInt> retI(DataArrayInt::New());
7629   retI->alloc(targetNb+1,1);
7630   const int *input=getConstPointer();
7631   std::vector< std::vector<int> > tmp(targetNb);
7632   for(int i=0;i<nbOfTuples;i++)
7633     {
7634       int tmp2=input[i];
7635       if(tmp2>=0 && tmp2<targetNb)
7636         tmp[tmp2].push_back(i);
7637       else
7638         {
7639           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7640           throw INTERP_KERNEL::Exception(oss.str().c_str());
7641         }
7642     }
7643   int *retIPtr=retI->getPointer();
7644   *retIPtr=0;
7645   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7646     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7647   if(nbOfTuples!=retI->getIJ(targetNb,0))
7648     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7649   ret->alloc(nbOfTuples,1);
7650   int *retPtr=ret->getPointer();
7651   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7652     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7653   arr=ret.retn();
7654   arrI=retI.retn();
7655 }
7656
7657
7658 /*!
7659  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7660  * from a zip representation of a surjective format (returned e.g. by
7661  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7662  * for example). The result array minimizes the permutation. <br>
7663  * For more info on renumbering see \ref numbering. <br>
7664  * \b Example: <br>
7665  * - \a nbOfOldTuples: 10 
7666  * - \a arr          : [0,3, 5,7,9]
7667  * - \a arrIBg       : [0,2,5]
7668  * - \a newNbOfTuples: 7
7669  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7670  *
7671  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7672  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7673  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7674  *         (indices of) equal values. Its every element (except the last one) points to
7675  *         the first element of a group of equal values.
7676  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7677  *          arrIBg is \a arrIEnd[ -1 ].
7678  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7679  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7680  *          array using decrRef() as it is no more needed.
7681  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7682  */
7683 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7684 {
7685   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7686   ret->alloc(nbOfOldTuples,1);
7687   int *pt=ret->getPointer();
7688   std::fill(pt,pt+nbOfOldTuples,-1);
7689   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7690   const int *cIPtr=arrIBg;
7691   for(int i=0;i<nbOfGrps;i++)
7692     pt[arr[cIPtr[i]]]=-(i+2);
7693   int newNb=0;
7694   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7695     {
7696       if(pt[iNode]<0)
7697         {
7698           if(pt[iNode]==-1)
7699             pt[iNode]=newNb++;
7700           else
7701             {
7702               int grpId=-(pt[iNode]+2);
7703               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7704                 {
7705                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7706                     pt[arr[j]]=newNb;
7707                   else
7708                     {
7709                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7710                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7711                     }
7712                 }
7713               newNb++;
7714             }
7715         }
7716     }
7717   newNbOfTuples=newNb;
7718   return ret.retn();
7719 }
7720
7721 /*!
7722  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7723  * which if applied to \a this array would make it sorted ascendingly.
7724  * For more info on renumbering see \ref numbering. <br>
7725  * \b Example: <br>
7726  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7727  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7728  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7729  *
7730  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7731  *          array using decrRef() as it is no more needed.
7732  *  \throw If \a this is not allocated.
7733  *  \throw If \a this->getNumberOfComponents() != 1.
7734  */
7735 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7736 {
7737   checkAllocated();
7738   if(getNumberOfComponents()!=1)
7739     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7740   int nbOfTuples=getNumberOfTuples();
7741   const int *pt=getConstPointer();
7742   std::map<int,int> m;
7743   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7744   ret->alloc(nbOfTuples,1);
7745   int *opt=ret->getPointer();
7746   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7747     {
7748       int val=*pt;
7749       std::map<int,int>::iterator it=m.find(val);
7750       if(it!=m.end())
7751         {
7752           *opt=(*it).second;
7753           (*it).second++;
7754         }
7755       else
7756         {
7757           *opt=0;
7758           m.insert(std::pair<int,int>(val,1));
7759         }
7760     }
7761   int sum=0;
7762   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7763     {
7764       int vt=(*it).second;
7765       (*it).second=sum;
7766       sum+=vt;
7767     }
7768   pt=getConstPointer();
7769   opt=ret->getPointer();
7770   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7771     *opt+=m[*pt];
7772   //
7773   return ret.retn();
7774 }
7775
7776 /*!
7777  * Checks if contents of \a this array are equal to that of an array filled with
7778  * iota(). This method is particularly useful for DataArrayInt instances that represent
7779  * a renumbering array to check the real need in renumbering. This method checks than \a this can be considered as an identity function
7780  * of a set having \a sizeExpected elements into itself.
7781  *
7782  *  \param [in] sizeExpected - The number of elements expected.
7783  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7784  *  \throw If \a this is not allocated.
7785  *  \throw If \a this->getNumberOfComponents() != 1.
7786  */
7787 bool DataArrayInt::isIota(int sizeExpected) const
7788 {
7789   checkAllocated();
7790   if(getNumberOfComponents()!=1)
7791     return false;
7792   int nbOfTuples(getNumberOfTuples());
7793   if(nbOfTuples!=sizeExpected)
7794     return false;
7795   const int *pt=getConstPointer();
7796   for(int i=0;i<nbOfTuples;i++,pt++)
7797     if(*pt!=i)
7798       return false;
7799   return true;
7800 }
7801
7802 /*!
7803  * Checks if all values in \a this array are equal to \a val.
7804  *  \param [in] val - value to check equality of array values to.
7805  *  \return bool - \a true if all values are \a val.
7806  *  \throw If \a this is not allocated.
7807  *  \throw If \a this->getNumberOfComponents() != 1
7808  */
7809 bool DataArrayInt::isUniform(int val) const
7810 {
7811   checkAllocated();
7812   if(getNumberOfComponents()!=1)
7813     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7814   int nbOfTuples=getNumberOfTuples();
7815   const int *w=getConstPointer();
7816   const int *end2=w+nbOfTuples;
7817   for(;w!=end2;w++)
7818     if(*w!=val)
7819       return false;
7820   return true;
7821 }
7822
7823 /*!
7824  * Checks if all values in \a this array are unique.
7825  *  \return bool - \a true if condition above is true
7826  *  \throw If \a this is not allocated.
7827  *  \throw If \a this->getNumberOfComponents() != 1
7828  */
7829 bool DataArrayInt::hasUniqueValues() const
7830 {
7831   checkAllocated();
7832   if(getNumberOfComponents()!=1)
7833     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7834   int nbOfTuples(getNumberOfTuples());
7835   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
7836   if (s.size() != nbOfTuples)
7837     return false;
7838   return true;
7839 }
7840
7841 /*!
7842  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7843  * array to the new one.
7844  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7845  */
7846 DataArrayDouble *DataArrayInt::convertToDblArr() const
7847 {
7848   checkAllocated();
7849   DataArrayDouble *ret=DataArrayDouble::New();
7850   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7851   std::size_t nbOfVals=getNbOfElems();
7852   const int *src=getConstPointer();
7853   double *dest=ret->getPointer();
7854   std::copy(src,src+nbOfVals,dest);
7855   ret->copyStringInfoFrom(*this);
7856   return ret;
7857 }
7858
7859 /*!
7860  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7861  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7862  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7863  * This method is a specialization of selectByTupleIdSafeSlice().
7864  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7865  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7866  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7867  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7868  *          is to delete using decrRef() as it is no more needed.
7869  *  \throw If \a tupleIdBg < 0.
7870  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7871     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7872  *  \sa DataArrayInt::selectByTupleIdSafeSlice
7873  */
7874 DataArrayInt *DataArrayInt::subArray(int tupleIdBg, int tupleIdEnd) const
7875 {
7876   checkAllocated();
7877   int nbt=getNumberOfTuples();
7878   if(tupleIdBg<0)
7879     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter must be greater than 0 !");
7880   if(tupleIdBg>nbt)
7881     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater than number of tuples !");
7882   int trueEnd=tupleIdEnd;
7883   if(tupleIdEnd!=-1)
7884     {
7885       if(tupleIdEnd>nbt)
7886         throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
7887     }
7888   else
7889     trueEnd=nbt;
7890   int nbComp=getNumberOfComponents();
7891   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7892   ret->alloc(trueEnd-tupleIdBg,nbComp);
7893   ret->copyStringInfoFrom(*this);
7894   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7895   return ret.retn();
7896 }
7897
7898 /*!
7899  * Changes the number of components within \a this array so that its raw data **does
7900  * not** change, instead splitting this data into tuples changes.
7901  *  \warning This method erases all (name and unit) component info set before!
7902  *  \param [in] newNbOfComp - number of components for \a this array to have.
7903  *  \throw If \a this is not allocated
7904  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7905  *  \throw If \a newNbOfCompo is lower than 1.
7906  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7907  *  \warning This method erases all (name and unit) component info set before!
7908  */
7909 void DataArrayInt::rearrange(int newNbOfCompo)
7910 {
7911   checkAllocated();
7912   if(newNbOfCompo<1)
7913     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7914   std::size_t nbOfElems=getNbOfElems();
7915   if(nbOfElems%newNbOfCompo!=0)
7916     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7917   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7918     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7919   _info_on_compo.clear();
7920   _info_on_compo.resize(newNbOfCompo);
7921   declareAsNew();
7922 }
7923
7924 /*!
7925  * Changes the number of components within \a this array to be equal to its number
7926  * of tuples, and inversely its number of tuples to become equal to its number of 
7927  * components. So that its raw data **does not** change, instead splitting this
7928  * data into tuples changes.
7929  *  \warning This method erases all (name and unit) component info set before!
7930  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7931  *  \throw If \a this is not allocated.
7932  *  \sa rearrange()
7933  */
7934 void DataArrayInt::transpose()
7935 {
7936   checkAllocated();
7937   int nbOfTuples=getNumberOfTuples();
7938   rearrange(nbOfTuples);
7939 }
7940
7941 /*!
7942  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7943  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7944  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7945  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7946  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7947  * components.  
7948  *  \param [in] newNbOfComp - number of components for the new array to have.
7949  *  \param [in] dftValue - value assigned to new values added to the new array.
7950  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7951  *          is to delete using decrRef() as it is no more needed.
7952  *  \throw If \a this is not allocated.
7953  */
7954 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7955 {
7956   checkAllocated();
7957   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7958   ret->alloc(getNumberOfTuples(),newNbOfComp);
7959   const int *oldc=getConstPointer();
7960   int *nc=ret->getPointer();
7961   int nbOfTuples=getNumberOfTuples();
7962   int oldNbOfComp=getNumberOfComponents();
7963   int dim=std::min(oldNbOfComp,newNbOfComp);
7964   for(int i=0;i<nbOfTuples;i++)
7965     {
7966       int j=0;
7967       for(;j<dim;j++)
7968         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7969       for(;j<newNbOfComp;j++)
7970         nc[newNbOfComp*i+j]=dftValue;
7971     }
7972   ret->setName(getName());
7973   for(int i=0;i<dim;i++)
7974     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7975   ret->setName(getName());
7976   return ret.retn();
7977 }
7978
7979 /*!
7980  * Changes number of tuples in the array. If the new number of tuples is smaller
7981  * than the current number the array is truncated, otherwise the array is extended.
7982  *  \param [in] nbOfTuples - new number of tuples. 
7983  *  \throw If \a this is not allocated.
7984  *  \throw If \a nbOfTuples is negative.
7985  */
7986 void DataArrayInt::reAlloc(int nbOfTuples)
7987 {
7988   if(nbOfTuples<0)
7989     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7990   checkAllocated();
7991   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7992   declareAsNew();
7993 }
7994
7995
7996 /*!
7997  * Returns a copy of \a this array composed of selected components.
7998  * The new DataArrayInt has the same number of tuples but includes components
7999  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
8000  * can be either less, same or more than \a this->getNbOfElems().
8001  *  \param [in] compoIds - sequence of zero based indices of components to include
8002  *              into the new array.
8003  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
8004  *          is to delete using decrRef() as it is no more needed.
8005  *  \throw If \a this is not allocated.
8006  *  \throw If a component index (\a i) is not valid: 
8007  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
8008  *
8009  *  \if ENABLE_EXAMPLES
8010  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
8011  *  \endif
8012  */
8013 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
8014 {
8015   checkAllocated();
8016   MCAuto<DataArrayInt> ret(DataArrayInt::New());
8017   int newNbOfCompo=(int)compoIds.size();
8018   int oldNbOfCompo=getNumberOfComponents();
8019   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
8020     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
8021   int nbOfTuples=getNumberOfTuples();
8022   ret->alloc(nbOfTuples,newNbOfCompo);
8023   ret->copyPartOfStringInfoFrom(*this,compoIds);
8024   const int *oldc=getConstPointer();
8025   int *nc=ret->getPointer();
8026   for(int i=0;i<nbOfTuples;i++)
8027     for(int j=0;j<newNbOfCompo;j++,nc++)
8028       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
8029   return ret.retn();
8030 }
8031
8032 /*!
8033  * Appends components of another array to components of \a this one, tuple by tuple.
8034  * So that the number of tuples of \a this array remains the same and the number of 
8035  * components increases.
8036  *  \param [in] other - the DataArrayInt to append to \a this one.
8037  *  \throw If \a this is not allocated.
8038  *  \throw If \a this and \a other arrays have different number of tuples.
8039  *
8040  *  \if ENABLE_EXAMPLES
8041  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
8042  *
8043  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
8044  *  \endif
8045  */
8046 void DataArrayInt::meldWith(const DataArrayInt *other)
8047 {
8048   if(!other)
8049     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
8050   checkAllocated();
8051   other->checkAllocated();
8052   int nbOfTuples=getNumberOfTuples();
8053   if(nbOfTuples!=other->getNumberOfTuples())
8054     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
8055   int nbOfComp1=getNumberOfComponents();
8056   int nbOfComp2=other->getNumberOfComponents();
8057   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
8058   int *w=newArr;
8059   const int *inp1=getConstPointer();
8060   const int *inp2=other->getConstPointer();
8061   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
8062     {
8063       w=std::copy(inp1,inp1+nbOfComp1,w);
8064       w=std::copy(inp2,inp2+nbOfComp2,w);
8065     }
8066   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
8067   std::vector<int> compIds(nbOfComp2);
8068   for(int i=0;i<nbOfComp2;i++)
8069     compIds[i]=nbOfComp1+i;
8070   copyPartOfStringInfoFrom2(compIds,*other);
8071 }
8072
8073 /*!
8074  * Copy all components in a specified order from another DataArrayInt.
8075  * The specified components become the first ones in \a this array.
8076  * Both numerical and textual data is copied. The number of tuples in \a this and
8077  * the other array can be different.
8078  *  \param [in] a - the array to copy data from.
8079  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
8080  *              to be copied.
8081  *  \throw If \a a is NULL.
8082  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
8083  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
8084  *
8085  *  \if ENABLE_EXAMPLES
8086  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
8087  *  \endif
8088  */
8089 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
8090 {
8091   if(!a)
8092     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
8093   checkAllocated();
8094   a->checkAllocated();
8095   copyPartOfStringInfoFrom2(compoIds,*a);
8096   std::size_t partOfCompoSz=compoIds.size();
8097   int nbOfCompo=getNumberOfComponents();
8098   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
8099   const int *ac=a->getConstPointer();
8100   int *nc=getPointer();
8101   for(int i=0;i<nbOfTuples;i++)
8102     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
8103       nc[nbOfCompo*i+compoIds[j]]=*ac;
8104 }
8105
8106 /*!
8107  * Copy all values from another DataArrayInt into specified tuples and components
8108  * of \a this array. Textual data is not copied.
8109  * The tree parameters defining set of indices of tuples and components are similar to
8110  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
8111  *  \param [in] a - the array to copy values from.
8112  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
8113  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8114  *              are located.
8115  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8116  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
8117  *  \param [in] endComp - index of the component before which the components to assign
8118  *              to are located.
8119  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8120  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
8121  *              must be equal to the number of columns to assign to, else an
8122  *              exception is thrown; if \a false, then it is only required that \a
8123  *              a->getNbOfElems() equals to number of values to assign to (this condition
8124  *              must be respected even if \a strictCompoCompare is \a true). The number of 
8125  *              values to assign to is given by following Python expression:
8126  *              \a nbTargetValues = 
8127  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
8128  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8129  *  \throw If \a a is NULL.
8130  *  \throw If \a a is not allocated.
8131  *  \throw If \a this is not allocated.
8132  *  \throw If parameters specifying tuples and components to assign to do not give a
8133  *            non-empty range of increasing indices.
8134  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
8135  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
8136  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8137  *
8138  *  \if ENABLE_EXAMPLES
8139  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
8140  *  \endif
8141  */
8142 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8143 {
8144   if(!a)
8145     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8146   const char msg[]="DataArrayInt::setPartOfValues1";
8147   checkAllocated();
8148   a->checkAllocated();
8149   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8150   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8151   int nbComp=getNumberOfComponents();
8152   int nbOfTuples=getNumberOfTuples();
8153   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8154   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8155   bool assignTech=true;
8156   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8157     {
8158       if(strictCompoCompare)
8159         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8160     }
8161   else
8162     {
8163       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8164       assignTech=false;
8165     }
8166   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8167   const int *srcPt=a->getConstPointer();
8168   if(assignTech)
8169     {
8170       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8171         for(int j=0;j<newNbOfComp;j++,srcPt++)
8172           pt[j*stepComp]=*srcPt;
8173     }
8174   else
8175     {
8176       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8177         {
8178           const int *srcPt2=srcPt;
8179           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8180             pt[j*stepComp]=*srcPt2;
8181         }
8182     }
8183 }
8184
8185 /*!
8186  * Assign a given value to values at specified tuples and components of \a this array.
8187  * The tree parameters defining set of indices of tuples and components are similar to
8188  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8189  *  \param [in] a - the value to assign.
8190  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8191  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8192  *              are located.
8193  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8194  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8195  *  \param [in] endComp - index of the component before which the components to assign
8196  *              to are located.
8197  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8198  *  \throw If \a this is not allocated.
8199  *  \throw If parameters specifying tuples and components to assign to, do not give a
8200  *            non-empty range of increasing indices or indices are out of a valid range
8201  *            for \c this array.
8202  *
8203  *  \if ENABLE_EXAMPLES
8204  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8205  *  \endif
8206  */
8207 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8208 {
8209   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8210   checkAllocated();
8211   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8212   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8213   int nbComp=getNumberOfComponents();
8214   int nbOfTuples=getNumberOfTuples();
8215   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8216   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8217   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8218   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8219     for(int j=0;j<newNbOfComp;j++)
8220       pt[j*stepComp]=a;
8221 }
8222
8223
8224 /*!
8225  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8226  * components of \a this array. Textual data is not copied.
8227  * The tuples and components to assign to are defined by C arrays of indices.
8228  * There are two *modes of usage*:
8229  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8230  *   of \a a is assigned to its own location within \a this array. 
8231  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8232  *   components of every specified tuple of \a this array. In this mode it is required
8233  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8234  * 
8235  *  \param [in] a - the array to copy values from.
8236  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8237  *              assign values of \a a to.
8238  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8239  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8240  *              \a bgTuples <= \a pi < \a endTuples.
8241  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8242  *              assign values of \a a to.
8243  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8244  *              pointer to a component index <em>(pi)</em> varies as this: 
8245  *              \a bgComp <= \a pi < \a endComp.
8246  *  \param [in] strictCompoCompare - this parameter is checked only if the
8247  *               *mode of usage* is the first; if it is \a true (default), 
8248  *               then \a a->getNumberOfComponents() must be equal 
8249  *               to the number of specified columns, else this is not required.
8250  *  \throw If \a a is NULL.
8251  *  \throw If \a a is not allocated.
8252  *  \throw If \a this is not allocated.
8253  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8254  *         out of a valid range for \a this array.
8255  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8256  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8257  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8258  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8259  *
8260  *  \if ENABLE_EXAMPLES
8261  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8262  *  \endif
8263  */
8264 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8265 {
8266   if(!a)
8267     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8268   const char msg[]="DataArrayInt::setPartOfValues2";
8269   checkAllocated();
8270   a->checkAllocated();
8271   int nbComp=getNumberOfComponents();
8272   int nbOfTuples=getNumberOfTuples();
8273   for(const int *z=bgComp;z!=endComp;z++)
8274     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8275   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8276   int newNbOfComp=(int)std::distance(bgComp,endComp);
8277   bool assignTech=true;
8278   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8279     {
8280       if(strictCompoCompare)
8281         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8282     }
8283   else
8284     {
8285       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8286       assignTech=false;
8287     }
8288   int *pt=getPointer();
8289   const int *srcPt=a->getConstPointer();
8290   if(assignTech)
8291     {    
8292       for(const int *w=bgTuples;w!=endTuples;w++)
8293         {
8294           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8295           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8296             {    
8297               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8298             }
8299         }
8300     }
8301   else
8302     {
8303       for(const int *w=bgTuples;w!=endTuples;w++)
8304         {
8305           const int *srcPt2=srcPt;
8306           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8307           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8308             {    
8309               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8310             }
8311         }
8312     }
8313 }
8314
8315 /*!
8316  * Assign a given value to values at specified tuples and components of \a this array.
8317  * The tuples and components to assign to are defined by C arrays of indices.
8318  *  \param [in] a - the value to assign.
8319  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8320  *              assign \a a to.
8321  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8322  *              pointer to a tuple index (\a pi) varies as this: 
8323  *              \a bgTuples <= \a pi < \a endTuples.
8324  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8325  *              assign \a a to.
8326  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8327  *              pointer to a component index (\a pi) varies as this: 
8328  *              \a bgComp <= \a pi < \a endComp.
8329  *  \throw If \a this is not allocated.
8330  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8331  *         out of a valid range for \a this array.
8332  *
8333  *  \if ENABLE_EXAMPLES
8334  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8335  *  \endif
8336  */
8337 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8338 {
8339   checkAllocated();
8340   int nbComp=getNumberOfComponents();
8341   int nbOfTuples=getNumberOfTuples();
8342   for(const int *z=bgComp;z!=endComp;z++)
8343     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8344   int *pt=getPointer();
8345   for(const int *w=bgTuples;w!=endTuples;w++)
8346     for(const int *z=bgComp;z!=endComp;z++)
8347       {
8348         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8349         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8350       }
8351 }
8352
8353 /*!
8354  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8355  * components of \a this array. Textual data is not copied.
8356  * The tuples to assign to are defined by a C array of indices.
8357  * The components to assign to are defined by three values similar to parameters of
8358  * the Python function \c range(\c start,\c stop,\c step).
8359  * There are two *modes of usage*:
8360  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8361  *   of \a a is assigned to its own location within \a this array. 
8362  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8363  *   components of every specified tuple of \a this array. In this mode it is required
8364  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8365  *
8366  *  \param [in] a - the array to copy values from.
8367  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8368  *              assign values of \a a to.
8369  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8370  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8371  *              \a bgTuples <= \a pi < \a endTuples.
8372  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8373  *  \param [in] endComp - index of the component before which the components to assign
8374  *              to are located.
8375  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8376  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8377  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8378  *               then \a a->getNumberOfComponents() must be equal 
8379  *               to the number of specified columns, else this is not required.
8380  *  \throw If \a a is NULL.
8381  *  \throw If \a a is not allocated.
8382  *  \throw If \a this is not allocated.
8383  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8384  *         \a this array.
8385  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8386  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8387  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8388  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8389  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8390  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8391  *  \throw If parameters specifying components to assign to, do not give a
8392  *            non-empty range of increasing indices or indices are out of a valid range
8393  *            for \c this array.
8394  *
8395  *  \if ENABLE_EXAMPLES
8396  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8397  *  \endif
8398  */
8399 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8400 {
8401   if(!a)
8402     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8403   const char msg[]="DataArrayInt::setPartOfValues3";
8404   checkAllocated();
8405   a->checkAllocated();
8406   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8407   int nbComp=getNumberOfComponents();
8408   int nbOfTuples=getNumberOfTuples();
8409   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8410   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8411   bool assignTech=true;
8412   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8413     {
8414       if(strictCompoCompare)
8415         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8416     }
8417   else
8418     {
8419       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8420       assignTech=false;
8421     }
8422   int *pt=getPointer()+bgComp;
8423   const int *srcPt=a->getConstPointer();
8424   if(assignTech)
8425     {
8426       for(const int *w=bgTuples;w!=endTuples;w++)
8427         for(int j=0;j<newNbOfComp;j++,srcPt++)
8428           {
8429             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8430             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8431           }
8432     }
8433   else
8434     {
8435       for(const int *w=bgTuples;w!=endTuples;w++)
8436         {
8437           const int *srcPt2=srcPt;
8438           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8439             {
8440               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8441               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8442             }
8443         }
8444     }
8445 }
8446
8447 /*!
8448  * Assign a given value to values at specified tuples and components of \a this array.
8449  * The tuples to assign to are defined by a C array of indices.
8450  * The components to assign to are defined by three values similar to parameters of
8451  * the Python function \c range(\c start,\c stop,\c step).
8452  *  \param [in] a - the value to assign.
8453  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8454  *              assign \a a to.
8455  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8456  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8457  *              \a bgTuples <= \a pi < \a endTuples.
8458  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8459  *  \param [in] endComp - index of the component before which the components to assign
8460  *              to are located.
8461  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8462  *  \throw If \a this is not allocated.
8463  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8464  *         \a this array.
8465  *  \throw If parameters specifying components to assign to, do not give a
8466  *            non-empty range of increasing indices or indices are out of a valid range
8467  *            for \c this array.
8468  *
8469  *  \if ENABLE_EXAMPLES
8470  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8471  *  \endif
8472  */
8473 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8474 {
8475   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8476   checkAllocated();
8477   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8478   int nbComp=getNumberOfComponents();
8479   int nbOfTuples=getNumberOfTuples();
8480   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8481   int *pt=getPointer()+bgComp;
8482   for(const int *w=bgTuples;w!=endTuples;w++)
8483     for(int j=0;j<newNbOfComp;j++)
8484       {
8485         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8486         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8487       }
8488 }
8489
8490 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8491 {
8492   if(!a)
8493     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8494   const char msg[]="DataArrayInt::setPartOfValues4";
8495   checkAllocated();
8496   a->checkAllocated();
8497   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8498   int newNbOfComp=(int)std::distance(bgComp,endComp);
8499   int nbComp=getNumberOfComponents();
8500   for(const int *z=bgComp;z!=endComp;z++)
8501     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8502   int nbOfTuples=getNumberOfTuples();
8503   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8504   bool assignTech=true;
8505   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8506     {
8507       if(strictCompoCompare)
8508         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8509     }
8510   else
8511     {
8512       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8513       assignTech=false;
8514     }
8515   const int *srcPt=a->getConstPointer();
8516   int *pt=getPointer()+bgTuples*nbComp;
8517   if(assignTech)
8518     {
8519       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8520         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8521           pt[*z]=*srcPt;
8522     }
8523   else
8524     {
8525       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8526         {
8527           const int *srcPt2=srcPt;
8528           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8529             pt[*z]=*srcPt2;
8530         }
8531     }
8532 }
8533
8534 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8535 {
8536   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8537   checkAllocated();
8538   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8539   int nbComp=getNumberOfComponents();
8540   for(const int *z=bgComp;z!=endComp;z++)
8541     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8542   int nbOfTuples=getNumberOfTuples();
8543   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8544   int *pt=getPointer()+bgTuples*nbComp;
8545   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8546     for(const int *z=bgComp;z!=endComp;z++)
8547       pt[*z]=a;
8548 }
8549
8550 /*!
8551  * Copy some tuples from another DataArrayInt into specified tuples
8552  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8553  * components.
8554  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8555  * All components of selected tuples are copied.
8556  *  \param [in] a - the array to copy values from.
8557  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8558  *              target tuples of \a this. \a tuplesSelec has two components, and the
8559  *              first component specifies index of the source tuple and the second
8560  *              one specifies index of the target tuple.
8561  *  \throw If \a this is not allocated.
8562  *  \throw If \a a is NULL.
8563  *  \throw If \a a is not allocated.
8564  *  \throw If \a tuplesSelec is NULL.
8565  *  \throw If \a tuplesSelec is not allocated.
8566  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8567  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8568  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8569  *         the corresponding (\a this or \a a) array.
8570  */
8571 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8572 {
8573   if(!a || !tuplesSelec)
8574     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8575   checkAllocated();
8576   a->checkAllocated();
8577   tuplesSelec->checkAllocated();
8578   int nbOfComp=getNumberOfComponents();
8579   if(nbOfComp!=a->getNumberOfComponents())
8580     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8581   if(tuplesSelec->getNumberOfComponents()!=2)
8582     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8583   int thisNt=getNumberOfTuples();
8584   int aNt=a->getNumberOfTuples();
8585   int *valsToSet=getPointer();
8586   const int *valsSrc=a->getConstPointer();
8587   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8588     {
8589       if(tuple[1]>=0 && tuple[1]<aNt)
8590         {
8591           if(tuple[0]>=0 && tuple[0]<thisNt)
8592             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8593           else
8594             {
8595               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8596               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8597               throw INTERP_KERNEL::Exception(oss.str().c_str());
8598             }
8599         }
8600       else
8601         {
8602           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8603           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8604           throw INTERP_KERNEL::Exception(oss.str().c_str());
8605         }
8606     }
8607 }
8608
8609 /*!
8610  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8611  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8612  * components.
8613  * The tuples to assign to are defined by index of the first tuple, and
8614  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8615  * The tuples to copy are defined by values of a DataArrayInt.
8616  * All components of selected tuples are copied.
8617  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8618  *              values to.
8619  *  \param [in] aBase - the array to copy values from.
8620  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8621  *  \throw If \a this is not allocated.
8622  *  \throw If \a aBase is NULL.
8623  *  \throw If \a aBase is not allocated.
8624  *  \throw If \a tuplesSelec is NULL.
8625  *  \throw If \a tuplesSelec is not allocated.
8626  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8627  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8628  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8629  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8630  *         \a aBase array.
8631  */
8632 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8633 {
8634   if(!aBase || !tuplesSelec)
8635     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8636   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8637   if(!a)
8638     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8639   checkAllocated();
8640   a->checkAllocated();
8641   tuplesSelec->checkAllocated();
8642   int nbOfComp=getNumberOfComponents();
8643   if(nbOfComp!=a->getNumberOfComponents())
8644     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8645   if(tuplesSelec->getNumberOfComponents()!=1)
8646     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8647   int thisNt=getNumberOfTuples();
8648   int aNt=a->getNumberOfTuples();
8649   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8650   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8651   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8652     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8653   const int *valsSrc=a->getConstPointer();
8654   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8655     {
8656       if(*tuple>=0 && *tuple<aNt)
8657         {
8658           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8659         }
8660       else
8661         {
8662           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8663           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8664           throw INTERP_KERNEL::Exception(oss.str().c_str());
8665         }
8666     }
8667 }
8668
8669 /*!
8670  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8671  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8672  * components.
8673  * The tuples to copy are defined by three values similar to parameters of
8674  * the Python function \c range(\c start,\c stop,\c step).
8675  * The tuples to assign to are defined by index of the first tuple, and
8676  * their number is defined by number of tuples to copy.
8677  * All components of selected tuples are copied.
8678  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8679  *              values to.
8680  *  \param [in] aBase - the array to copy values from.
8681  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8682  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8683  *              are located.
8684  *  \param [in] step - index increment to get index of the next tuple to copy.
8685  *  \throw If \a this is not allocated.
8686  *  \throw If \a aBase is NULL.
8687  *  \throw If \a aBase is not allocated.
8688  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8689  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8690  *  \throw If parameters specifying tuples to copy, do not give a
8691  *            non-empty range of increasing indices or indices are out of a valid range
8692  *            for the array \a aBase.
8693  */
8694 void DataArrayInt::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8695 {
8696   if(!aBase)
8697     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
8698   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8699   if(!a)
8700     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayInt !");
8701   checkAllocated();
8702   a->checkAllocated();
8703   int nbOfComp=getNumberOfComponents();
8704   const char msg[]="DataArrayInt::setContigPartOfSelectedValuesSlice";
8705   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8706   if(nbOfComp!=a->getNumberOfComponents())
8707     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
8708   int thisNt=getNumberOfTuples();
8709   int aNt=a->getNumberOfTuples();
8710   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8711   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8712     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
8713   if(end2>aNt)
8714     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
8715   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8716   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8717     {
8718       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8719     }
8720 }
8721
8722 /*!
8723  * Returns a value located at specified tuple and component.
8724  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8725  * parameters is checked. So this method is safe but expensive if used to go through
8726  * all values of \a this.
8727  *  \param [in] tupleId - index of tuple of interest.
8728  *  \param [in] compoId - index of component of interest.
8729  *  \return double - value located by \a tupleId and \a compoId.
8730  *  \throw If \a this is not allocated.
8731  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8732  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8733  */
8734 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8735 {
8736   checkAllocated();
8737   if(tupleId<0 || tupleId>=getNumberOfTuples())
8738     {
8739       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8740       throw INTERP_KERNEL::Exception(oss.str().c_str());
8741     }
8742   if(compoId<0 || compoId>=getNumberOfComponents())
8743     {
8744       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8745       throw INTERP_KERNEL::Exception(oss.str().c_str());
8746     }
8747   return _mem[tupleId*_info_on_compo.size()+compoId];
8748 }
8749
8750 /*!
8751  * Returns the first value of \a this. 
8752  *  \return int - the last value of \a this array.
8753  *  \throw If \a this is not allocated.
8754  *  \throw If \a this->getNumberOfComponents() != 1.
8755  *  \throw If \a this->getNumberOfTuples() < 1.
8756  */
8757 int DataArrayInt::front() const
8758 {
8759   checkAllocated();
8760   if(getNumberOfComponents()!=1)
8761     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8762   int nbOfTuples=getNumberOfTuples();
8763   if(nbOfTuples<1)
8764     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8765   return *(getConstPointer());
8766 }
8767
8768 /*!
8769  * Returns the last value of \a this. 
8770  *  \return int - the last value of \a this array.
8771  *  \throw If \a this is not allocated.
8772  *  \throw If \a this->getNumberOfComponents() != 1.
8773  *  \throw If \a this->getNumberOfTuples() < 1.
8774  */
8775 int DataArrayInt::back() const
8776 {
8777   checkAllocated();
8778   if(getNumberOfComponents()!=1)
8779     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8780   int nbOfTuples=getNumberOfTuples();
8781   if(nbOfTuples<1)
8782     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8783   return *(getConstPointer()+nbOfTuples-1);
8784 }
8785
8786 /*!
8787  * Assign pointer to one array to a pointer to another appay. Reference counter of
8788  * \a arrayToSet is incremented / decremented.
8789  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8790  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8791  */
8792 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8793 {
8794   if(newArray!=arrayToSet)
8795     {
8796       if(arrayToSet)
8797         arrayToSet->decrRef();
8798       arrayToSet=newArray;
8799       if(arrayToSet)
8800         arrayToSet->incrRef();
8801     }
8802 }
8803
8804 DataArrayIntIterator *DataArrayInt::iterator()
8805 {
8806   return new DataArrayIntIterator(this);
8807 }
8808
8809 /*!
8810  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8811  * given one. The ids are sorted in the ascending order.
8812  *  \param [in] val - the value to find within \a this.
8813  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8814  *          array using decrRef() as it is no more needed.
8815  *  \throw If \a this is not allocated.
8816  *  \throw If \a this->getNumberOfComponents() != 1.
8817  *  \sa DataArrayInt::findIdsEqualTuple
8818  */
8819 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
8820 {
8821   checkAllocated();
8822   if(getNumberOfComponents()!=1)
8823     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8824   const int *cptr(getConstPointer());
8825   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8826   int nbOfTuples=getNumberOfTuples();
8827   for(int i=0;i<nbOfTuples;i++,cptr++)
8828     if(*cptr==val)
8829       ret->pushBackSilent(i);
8830   return ret.retn();
8831 }
8832
8833 /*!
8834  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8835  * equal to a given one. 
8836  *  \param [in] val - the value to ignore within \a this.
8837  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8838  *          array using decrRef() as it is no more needed.
8839  *  \throw If \a this is not allocated.
8840  *  \throw If \a this->getNumberOfComponents() != 1.
8841  */
8842 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
8843 {
8844   checkAllocated();
8845   if(getNumberOfComponents()!=1)
8846     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8847   const int *cptr(getConstPointer());
8848   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8849   int nbOfTuples=getNumberOfTuples();
8850   for(int i=0;i<nbOfTuples;i++,cptr++)
8851     if(*cptr!=val)
8852       ret->pushBackSilent(i);
8853   return ret.retn();
8854 }
8855
8856 /*!
8857  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8858  * This method is an extension of  DataArrayInt::findIdsEqual method.
8859  *
8860  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8861  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8862  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8863  *          array using decrRef() as it is no more needed.
8864  *  \throw If \a this is not allocated.
8865  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8866  * \throw If \a this->getNumberOfComponents() is equal to 0.
8867  * \sa DataArrayInt::findIdsEqual
8868  */
8869 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8870 {
8871   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8872   checkAllocated();
8873   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8874     {
8875       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8876       throw INTERP_KERNEL::Exception(oss.str().c_str());
8877     }
8878   if(nbOfCompoExp==0)
8879     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
8880   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8881   const int *bg(begin()),*end2(end()),*work(begin());
8882   while(work!=end2)
8883     {
8884       work=std::search(work,end2,tupleBg,tupleEnd);
8885       if(work!=end2)
8886         {
8887           std::size_t pos(std::distance(bg,work));
8888           if(pos%nbOfCompoExp==0)
8889             ret->pushBackSilent(pos/nbOfCompoExp);
8890           work++;
8891         }
8892     }
8893   return ret.retn();
8894 }
8895
8896 /*!
8897  * Assigns \a newValue to all elements holding \a oldValue within \a this
8898  * one-dimensional array.
8899  *  \param [in] oldValue - the value to replace.
8900  *  \param [in] newValue - the value to assign.
8901  *  \return int - number of replacements performed.
8902  *  \throw If \a this is not allocated.
8903  *  \throw If \a this->getNumberOfComponents() != 1.
8904  */
8905 int DataArrayInt::changeValue(int oldValue, int newValue)
8906 {
8907   checkAllocated();
8908   if(getNumberOfComponents()!=1)
8909     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8910   if(oldValue==newValue)
8911     return 0;
8912   int *start(getPointer()),*end2(start+getNbOfElems());
8913   int ret(0);
8914   for(int *val=start;val!=end2;val++)
8915     {
8916       if(*val==oldValue)
8917         {
8918           *val=newValue;
8919           ret++;
8920         }
8921     }
8922   if(ret>0)
8923     declareAsNew();
8924   return ret;
8925 }
8926
8927 /*!
8928  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8929  * one of given values.
8930  *  \param [in] valsBg - an array of values to find within \a this array.
8931  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8932  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8933  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8934  *          array using decrRef() as it is no more needed.
8935  *  \throw If \a this->getNumberOfComponents() != 1.
8936  */
8937 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
8938 {
8939   if(getNumberOfComponents()!=1)
8940     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8941   std::set<int> vals2(valsBg,valsEnd);
8942   const int *cptr(getConstPointer());
8943   std::vector<int> res;
8944   int nbOfTuples(getNumberOfTuples());
8945   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8946   for(int i=0;i<nbOfTuples;i++,cptr++)
8947     if(vals2.find(*cptr)!=vals2.end())
8948       ret->pushBackSilent(i);
8949   return ret.retn();
8950 }
8951
8952 /*!
8953  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8954  * equal to any of given values.
8955  *  \param [in] valsBg - an array of values to ignore within \a this array.
8956  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8957  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8958  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8959  *          array using decrRef() as it is no more needed.
8960  *  \throw If \a this->getNumberOfComponents() != 1.
8961  */
8962 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8963 {
8964   if(getNumberOfComponents()!=1)
8965     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8966   std::set<int> vals2(valsBg,valsEnd);
8967   const int *cptr=getConstPointer();
8968   std::vector<int> res;
8969   int nbOfTuples=getNumberOfTuples();
8970   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8971   for(int i=0;i<nbOfTuples;i++,cptr++)
8972     if(vals2.find(*cptr)==vals2.end())
8973       ret->pushBackSilent(i);
8974   return ret.retn();
8975 }
8976
8977 /*!
8978  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
8979  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8980  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8981  * If any the tuple id is returned. If not -1 is returned.
8982  * 
8983  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8984  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8985  *
8986  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8987  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
8988  */
8989 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
8990 {
8991   checkAllocated();
8992   int nbOfCompo=getNumberOfComponents();
8993   if(nbOfCompo==0)
8994     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
8995   if(nbOfCompo!=(int)tupl.size())
8996     {
8997       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8998       throw INTERP_KERNEL::Exception(oss.str().c_str());
8999     }
9000   const int *cptr=getConstPointer();
9001   std::size_t nbOfVals=getNbOfElems();
9002   for(const int *work=cptr;work!=cptr+nbOfVals;)
9003     {
9004       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
9005       if(work!=cptr+nbOfVals)
9006         {
9007           if(std::distance(cptr,work)%nbOfCompo!=0)
9008             work++;
9009           else
9010             return std::distance(cptr,work)/nbOfCompo;
9011         }
9012     }
9013   return -1;
9014 }
9015
9016 /*!
9017  * This method searches the sequence specified in input parameter \b vals in \b this.
9018  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
9019  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
9020  * \sa DataArrayInt::findIdFirstEqualTuple
9021  */
9022 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
9023 {
9024   checkAllocated();
9025   int nbOfCompo=getNumberOfComponents();
9026   if(nbOfCompo!=1)
9027     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
9028   const int *cptr=getConstPointer();
9029   std::size_t nbOfVals=getNbOfElems();
9030   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
9031   if(loc!=cptr+nbOfVals)
9032     return std::distance(cptr,loc);
9033   return -1;
9034 }
9035
9036 /*!
9037  * This method expects to be called when number of components of this is equal to one.
9038  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
9039  * If not any tuple contains \b value -1 is returned.
9040  * \sa DataArrayInt::presenceOfValue
9041  */
9042 int DataArrayInt::findIdFirstEqual(int value) const
9043 {
9044   checkAllocated();
9045   if(getNumberOfComponents()!=1)
9046     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9047   const int *cptr=getConstPointer();
9048   int nbOfTuples=getNumberOfTuples();
9049   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
9050   if(ret!=cptr+nbOfTuples)
9051     return std::distance(cptr,ret);
9052   return -1;
9053 }
9054
9055 /*!
9056  * This method expects to be called when number of components of this is equal to one.
9057  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
9058  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
9059  * \sa DataArrayInt::presenceOfValue
9060  */
9061 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
9062 {
9063   checkAllocated();
9064   if(getNumberOfComponents()!=1)
9065     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9066   std::set<int> vals2(vals.begin(),vals.end());
9067   const int *cptr=getConstPointer();
9068   int nbOfTuples=getNumberOfTuples();
9069   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
9070     if(vals2.find(*w)!=vals2.end())
9071       return std::distance(cptr,w);
9072   return -1;
9073 }
9074
9075 /*!
9076  * This method returns the number of values in \a this that are equals to input parameter \a value.
9077  * This method only works for single component array.
9078  *
9079  * \return a value in [ 0, \c this->getNumberOfTuples() )
9080  *
9081  * \throw If \a this is not allocated
9082  *
9083  */
9084 int DataArrayInt::count(int value) const
9085 {
9086   int ret=0;
9087   checkAllocated();
9088   if(getNumberOfComponents()!=1)
9089     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
9090   const int *vals=begin();
9091   int nbOfTuples=getNumberOfTuples();
9092   for(int i=0;i<nbOfTuples;i++,vals++)
9093     if(*vals==value)
9094       ret++;
9095   return ret;
9096 }
9097
9098 /*!
9099  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
9100  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9101  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9102  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9103  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9104  * \sa DataArrayInt::findIdFirstEqualTuple
9105  */
9106 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
9107 {
9108   return findIdFirstEqualTuple(tupl)!=-1;
9109 }
9110
9111
9112 /*!
9113  * Returns \a true if a given value is present within \a this one-dimensional array.
9114  *  \param [in] value - the value to find within \a this array.
9115  *  \return bool - \a true in case if \a value is present within \a this array.
9116  *  \throw If \a this is not allocated.
9117  *  \throw If \a this->getNumberOfComponents() != 1.
9118  *  \sa findIdFirstEqual()
9119  */
9120 bool DataArrayInt::presenceOfValue(int value) const
9121 {
9122   return findIdFirstEqual(value)!=-1;
9123 }
9124
9125 /*!
9126  * This method expects to be called when number of components of this is equal to one.
9127  * This method returns true if it exists a tuple so that the value is contained in \b vals.
9128  * If not any tuple contains one of the values contained in 'vals' false is returned.
9129  * \sa DataArrayInt::findIdFirstEqual
9130  */
9131 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
9132 {
9133   return findIdFirstEqual(vals)!=-1;
9134 }
9135
9136 /*!
9137  * Accumulates values of each component of \a this array.
9138  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
9139  *         by the caller, that is filled by this method with sum value for each
9140  *         component.
9141  *  \throw If \a this is not allocated.
9142  */
9143 void DataArrayInt::accumulate(int *res) const
9144 {
9145   checkAllocated();
9146   const int *ptr=getConstPointer();
9147   int nbTuple=getNumberOfTuples();
9148   int nbComps=getNumberOfComponents();
9149   std::fill(res,res+nbComps,0);
9150   for(int i=0;i<nbTuple;i++)
9151     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9152 }
9153
9154 int DataArrayInt::accumulate(int compId) const
9155 {
9156   checkAllocated();
9157   const int *ptr=getConstPointer();
9158   int nbTuple=getNumberOfTuples();
9159   int nbComps=getNumberOfComponents();
9160   if(compId<0 || compId>=nbComps)
9161     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9162   int ret=0;
9163   for(int i=0;i<nbTuple;i++)
9164     ret+=ptr[i*nbComps+compId];
9165   return ret;
9166 }
9167
9168 /*!
9169  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9170  * The returned array will have same number of components than \a this and number of tuples equal to
9171  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9172  *
9173  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9174  *
9175  * \param [in] bgOfIndex - begin (included) of the input index array.
9176  * \param [in] endOfIndex - end (excluded) of the input index array.
9177  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9178  * 
9179  * \throw If bgOfIndex or end is NULL.
9180  * \throw If input index array is not ascendingly sorted.
9181  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9182  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9183  */
9184 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9185 {
9186   if(!bgOfIndex || !endOfIndex)
9187     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9188   checkAllocated();
9189   int nbCompo=getNumberOfComponents();
9190   int nbOfTuples=getNumberOfTuples();
9191   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9192   if(sz<1)
9193     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9194   sz--;
9195   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9196   const int *w=bgOfIndex;
9197   if(*w<0 || *w>=nbOfTuples)
9198     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9199   const int *srcPt=begin()+(*w)*nbCompo;
9200   int *tmp=ret->getPointer();
9201   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9202     {
9203       std::fill(tmp,tmp+nbCompo,0);
9204       if(w[1]>=w[0])
9205         {
9206           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9207             {
9208               if(j>=0 && j<nbOfTuples)
9209                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9210               else
9211                 {
9212                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9213                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9214                 }
9215             }
9216         }
9217       else
9218         {
9219           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9220           throw INTERP_KERNEL::Exception(oss.str().c_str());
9221         }
9222     }
9223   ret->copyStringInfoFrom(*this);
9224   return ret.retn();
9225 }
9226
9227 /*!
9228  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9229  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9230  * offsetA2</em> and (2)
9231  * the number of component in the result array is same as that of each of given arrays.
9232  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9233  * Info on components is copied from the first of the given arrays. Number of components
9234  * in the given arrays must be the same.
9235  *  \param [in] a1 - an array to include in the result array.
9236  *  \param [in] a2 - another array to include in the result array.
9237  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9238  *  \return DataArrayInt * - the new instance of DataArrayInt.
9239  *          The caller is to delete this result array using decrRef() as it is no more
9240  *          needed.
9241  *  \throw If either \a a1 or \a a2 is NULL.
9242  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9243  */
9244 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9245 {
9246   if(!a1 || !a2)
9247     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9248   int nbOfComp=a1->getNumberOfComponents();
9249   if(nbOfComp!=a2->getNumberOfComponents())
9250     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9251   int nbOfTuple1=a1->getNumberOfTuples();
9252   int nbOfTuple2=a2->getNumberOfTuples();
9253   DataArrayInt *ret=DataArrayInt::New();
9254   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9255   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9256   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9257   ret->copyStringInfoFrom(*a1);
9258   return ret;
9259 }
9260
9261 /*!
9262  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9263  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9264  * the number of component in the result array is same as that of each of given arrays.
9265  * Info on components is copied from the first of the given arrays. Number of components
9266  * in the given arrays must be  the same.
9267  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9268  * not the object itself.
9269  *  \param [in] arr - a sequence of arrays to include in the result array.
9270  *  \return DataArrayInt * - the new instance of DataArrayInt.
9271  *          The caller is to delete this result array using decrRef() as it is no more
9272  *          needed.
9273  *  \throw If all arrays within \a arr are NULL.
9274  *  \throw If getNumberOfComponents() of arrays within \a arr.
9275  */
9276 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9277 {
9278   std::vector<const DataArrayInt *> a;
9279   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9280     if(*it4)
9281       a.push_back(*it4);
9282   if(a.empty())
9283     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9284   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9285   int nbOfComp=(*it)->getNumberOfComponents();
9286   int nbt=(*it++)->getNumberOfTuples();
9287   for(int i=1;it!=a.end();it++,i++)
9288     {
9289       if((*it)->getNumberOfComponents()!=nbOfComp)
9290         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9291       nbt+=(*it)->getNumberOfTuples();
9292     }
9293   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9294   ret->alloc(nbt,nbOfComp);
9295   int *pt=ret->getPointer();
9296   for(it=a.begin();it!=a.end();it++)
9297     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9298   ret->copyStringInfoFrom(*(a[0]));
9299   return ret.retn();
9300 }
9301
9302 /*!
9303  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9304  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9305  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9306  * 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.
9307  * 
9308  * \return DataArrayInt * - a new object to be managed by the caller.
9309  */
9310 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9311 {
9312   int retSz=1;
9313   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9314     {
9315       if(*it4)
9316         {
9317           (*it4)->checkAllocated();
9318           if((*it4)->getNumberOfComponents()!=1)
9319             {
9320               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9321               throw INTERP_KERNEL::Exception(oss.str().c_str());
9322             }
9323           int nbTupl=(*it4)->getNumberOfTuples();
9324           if(nbTupl<1)
9325             {
9326               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9327               throw INTERP_KERNEL::Exception(oss.str().c_str());
9328             }
9329           if((*it4)->front()!=0)
9330             {
9331               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9332               throw INTERP_KERNEL::Exception(oss.str().c_str());
9333             }
9334           retSz+=nbTupl-1;
9335         }
9336       else
9337         {
9338           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9339           throw INTERP_KERNEL::Exception(oss.str().c_str());
9340         }
9341     }
9342   if(arrs.empty())
9343     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9344   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9345   ret->alloc(retSz,1);
9346   int *pt=ret->getPointer(); *pt++=0;
9347   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9348     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9349   ret->copyStringInfoFrom(*(arrs[0]));
9350   return ret.retn();
9351 }
9352
9353 /*!
9354  * Returns the maximal value and its location within \a this one-dimensional array.
9355  *  \param [out] tupleId - index of the tuple holding the maximal value.
9356  *  \return int - the maximal value among all values of \a this array.
9357  *  \throw If \a this->getNumberOfComponents() != 1
9358  *  \throw If \a this->getNumberOfTuples() < 1
9359  */
9360 int DataArrayInt::getMaxValue(int& tupleId) const
9361 {
9362   checkAllocated();
9363   if(getNumberOfComponents()!=1)
9364     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9365   int nbOfTuples=getNumberOfTuples();
9366   if(nbOfTuples<=0)
9367     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9368   const int *vals=getConstPointer();
9369   const int *loc=std::max_element(vals,vals+nbOfTuples);
9370   tupleId=(int)std::distance(vals,loc);
9371   return *loc;
9372 }
9373
9374 /*!
9375  * Returns the maximal value within \a this array that is allowed to have more than
9376  *  one component.
9377  *  \return int - the maximal value among all values of \a this array.
9378  *  \throw If \a this is not allocated.
9379  */
9380 int DataArrayInt::getMaxValueInArray() const
9381 {
9382   checkAllocated();
9383   const int *loc=std::max_element(begin(),end());
9384   return *loc;
9385 }
9386
9387 /*!
9388  * Returns the minimal value and its location within \a this one-dimensional array.
9389  *  \param [out] tupleId - index of the tuple holding the minimal value.
9390  *  \return int - the minimal value among all values of \a this array.
9391  *  \throw If \a this->getNumberOfComponents() != 1
9392  *  \throw If \a this->getNumberOfTuples() < 1
9393  */
9394 int DataArrayInt::getMinValue(int& tupleId) const
9395 {
9396   checkAllocated();
9397   if(getNumberOfComponents()!=1)
9398     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9399   int nbOfTuples=getNumberOfTuples();
9400   if(nbOfTuples<=0)
9401     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9402   const int *vals=getConstPointer();
9403   const int *loc=std::min_element(vals,vals+nbOfTuples);
9404   tupleId=(int)std::distance(vals,loc);
9405   return *loc;
9406 }
9407
9408 /*!
9409  * Returns the minimal value within \a this array that is allowed to have more than
9410  *  one component.
9411  *  \return int - the minimal value among all values of \a this array.
9412  *  \throw If \a this is not allocated.
9413  */
9414 int DataArrayInt::getMinValueInArray() const
9415 {
9416   checkAllocated();
9417   const int *loc=std::min_element(begin(),end());
9418   return *loc;
9419 }
9420
9421 /*!
9422  * Returns in a single walk in \a this the min value and the max value in \a this.
9423  * \a this is expected to be single component array.
9424  *
9425  * \param [out] minValue - the min value in \a this.
9426  * \param [out] maxValue - the max value in \a this.
9427  *
9428  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9429  */
9430 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9431 {
9432   checkAllocated();
9433   if(getNumberOfComponents()!=1)
9434     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9435   int nbTuples(getNumberOfTuples());
9436   const int *pt(begin());
9437   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9438   for(int i=0;i<nbTuples;i++,pt++)
9439     {
9440       if(*pt<minValue)
9441         minValue=*pt;
9442       if(*pt>maxValue)
9443         maxValue=*pt;
9444     }
9445 }
9446
9447 /*!
9448  * Converts every value of \a this array to its absolute value.
9449  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9450  * should be called instead.
9451  *
9452  * \throw If \a this is not allocated.
9453  * \sa DataArrayInt::computeAbs
9454  */
9455 void DataArrayInt::abs()
9456 {
9457   checkAllocated();
9458   int *ptr(getPointer());
9459   std::size_t nbOfElems(getNbOfElems());
9460   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9461   declareAsNew();
9462 }
9463
9464 /*!
9465  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9466  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9467  *
9468  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9469  *         same number of tuples and component as \a this array.
9470  *         The caller is to delete this result array using decrRef() as it is no more
9471  *         needed.
9472  * \throw If \a this is not allocated.
9473  * \sa DataArrayInt::abs
9474  */
9475 DataArrayInt *DataArrayInt::computeAbs() const
9476 {
9477   checkAllocated();
9478   DataArrayInt *newArr(DataArrayInt::New());
9479   int nbOfTuples(getNumberOfTuples());
9480   int nbOfComp(getNumberOfComponents());
9481   newArr->alloc(nbOfTuples,nbOfComp);
9482   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9483   newArr->copyStringInfoFrom(*this);
9484   return newArr;
9485 }
9486
9487 /*!
9488  * Apply a liner function to a given component of \a this array, so that
9489  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9490  *  \param [in] a - the first coefficient of the function.
9491  *  \param [in] b - the second coefficient of the function.
9492  *  \param [in] compoId - the index of component to modify.
9493  *  \throw If \a this is not allocated.
9494  */
9495 void DataArrayInt::applyLin(int a, int b, int compoId)
9496 {
9497   checkAllocated();
9498   int *ptr=getPointer()+compoId;
9499   int nbOfComp=getNumberOfComponents();
9500   int nbOfTuple=getNumberOfTuples();
9501   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9502     *ptr=a*(*ptr)+b;
9503   declareAsNew();
9504 }
9505
9506 /*!
9507  * Apply a liner function to all elements of \a this array, so that
9508  * an element _x_ becomes \f$ a * x + b \f$.
9509  *  \param [in] a - the first coefficient of the function.
9510  *  \param [in] b - the second coefficient of the function.
9511  *  \throw If \a this is not allocated.
9512  */
9513 void DataArrayInt::applyLin(int a, int b)
9514 {
9515   checkAllocated();
9516   int *ptr=getPointer();
9517   std::size_t nbOfElems=getNbOfElems();
9518   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9519     *ptr=a*(*ptr)+b;
9520   declareAsNew();
9521 }
9522
9523 /*!
9524  * Returns a full copy of \a this array except that sign of all elements is reversed.
9525  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9526  *          same number of tuples and component as \a this array.
9527  *          The caller is to delete this result array using decrRef() as it is no more
9528  *          needed.
9529  *  \throw If \a this is not allocated.
9530  */
9531 DataArrayInt *DataArrayInt::negate() const
9532 {
9533   checkAllocated();
9534   DataArrayInt *newArr=DataArrayInt::New();
9535   int nbOfTuples=getNumberOfTuples();
9536   int nbOfComp=getNumberOfComponents();
9537   newArr->alloc(nbOfTuples,nbOfComp);
9538   const int *cptr=getConstPointer();
9539   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9540   newArr->copyStringInfoFrom(*this);
9541   return newArr;
9542 }
9543
9544 /*!
9545  * Modify all elements of \a this array, so that
9546  * an element _x_ becomes \f$ numerator / x \f$.
9547  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9548  *           array, all elements processed before detection of the zero element remain
9549  *           modified.
9550  *  \param [in] numerator - the numerator used to modify array elements.
9551  *  \throw If \a this is not allocated.
9552  *  \throw If there is an element equal to 0 in \a this array.
9553  */
9554 void DataArrayInt::applyInv(int numerator)
9555 {
9556   checkAllocated();
9557   int *ptr=getPointer();
9558   std::size_t nbOfElems=getNbOfElems();
9559   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9560     {
9561       if(*ptr!=0)
9562         {
9563           *ptr=numerator/(*ptr);
9564         }
9565       else
9566         {
9567           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9568           oss << " !";
9569           throw INTERP_KERNEL::Exception(oss.str().c_str());
9570         }
9571     }
9572   declareAsNew();
9573 }
9574
9575 /*!
9576  * Modify all elements of \a this array, so that
9577  * an element _x_ becomes \f$ x / val \f$.
9578  *  \param [in] val - the denominator used to modify array elements.
9579  *  \throw If \a this is not allocated.
9580  *  \throw If \a val == 0.
9581  */
9582 void DataArrayInt::applyDivideBy(int val)
9583 {
9584   if(val==0)
9585     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9586   checkAllocated();
9587   int *ptr=getPointer();
9588   std::size_t nbOfElems=getNbOfElems();
9589   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9590   declareAsNew();
9591 }
9592
9593 /*!
9594  * Modify all elements of \a this array, so that
9595  * an element _x_ becomes  <em> x % val </em>.
9596  *  \param [in] val - the divisor used to modify array elements.
9597  *  \throw If \a this is not allocated.
9598  *  \throw If \a val <= 0.
9599  */
9600 void DataArrayInt::applyModulus(int val)
9601 {
9602   if(val<=0)
9603     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9604   checkAllocated();
9605   int *ptr=getPointer();
9606   std::size_t nbOfElems=getNbOfElems();
9607   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9608   declareAsNew();
9609 }
9610
9611 /*!
9612  * This method works only on data array with one component.
9613  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9614  * this[*id] in [\b vmin,\b vmax)
9615  * 
9616  * \param [in] vmin begin of range. This value is included in range (included).
9617  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9618  * \return a newly allocated data array that the caller should deal with.
9619  *
9620  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
9621  */
9622 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
9623 {
9624   checkAllocated();
9625   if(getNumberOfComponents()!=1)
9626     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
9627   const int *cptr(begin());
9628   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9629   int nbOfTuples(getNumberOfTuples());
9630   for(int i=0;i<nbOfTuples;i++,cptr++)
9631     if(*cptr>=vmin && *cptr<vmax)
9632       ret->pushBackSilent(i);
9633   return ret.retn();
9634 }
9635
9636 /*!
9637  * This method works only on data array with one component.
9638  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9639  * this[*id] \b not in [\b vmin,\b vmax)
9640  * 
9641  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9642  * \param [in] vmax end of range. This value is included in range (included).
9643  * \return a newly allocated data array that the caller should deal with.
9644  * 
9645  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
9646  */
9647 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
9648 {
9649   checkAllocated();
9650   if(getNumberOfComponents()!=1)
9651     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
9652   const int *cptr(getConstPointer());
9653   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9654   int nbOfTuples(getNumberOfTuples());
9655   for(int i=0;i<nbOfTuples;i++,cptr++)
9656     if(*cptr<vmin || *cptr>=vmax)
9657       ret->pushBackSilent(i);
9658   return ret.retn();
9659 }
9660
9661 /*!
9662  * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
9663  *
9664  * \return a newly allocated data array that the caller should deal with.
9665  * \sa DataArrayInt::findIdsInRange
9666  */
9667 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
9668 {
9669   checkAllocated();
9670   if(getNumberOfComponents()!=1)
9671     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
9672   const int *cptr(getConstPointer());
9673   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9674   int nbOfTuples(getNumberOfTuples());
9675   for(int i=0;i<nbOfTuples;i++,cptr++)
9676     if(*cptr<0)
9677       ret->pushBackSilent(i);
9678   return ret.retn();
9679 }
9680
9681 /*!
9682  * This method works only on data array with one component.
9683  * 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.
9684  * 
9685  * \param [in] vmin begin of range. This value is included in range (included).
9686  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9687  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9688 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9689 {
9690   checkAllocated();
9691   if(getNumberOfComponents()!=1)
9692     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9693   int nbOfTuples=getNumberOfTuples();
9694   bool ret=true;
9695   const int *cptr=getConstPointer();
9696   for(int i=0;i<nbOfTuples;i++,cptr++)
9697     {
9698       if(*cptr>=vmin && *cptr<vmax)
9699         { ret=ret && *cptr==i; }
9700       else
9701         {
9702           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9703           throw INTERP_KERNEL::Exception(oss.str().c_str());
9704         }
9705     }
9706   return ret;
9707 }
9708
9709 /*!
9710  * Modify all elements of \a this array, so that
9711  * an element _x_ becomes <em> val % x </em>.
9712  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9713  *           array, all elements processed before detection of the zero element remain
9714  *           modified.
9715  *  \param [in] val - the divident used to modify array elements.
9716  *  \throw If \a this is not allocated.
9717  *  \throw If there is an element equal to or less than 0 in \a this array.
9718  */
9719 void DataArrayInt::applyRModulus(int val)
9720 {
9721   checkAllocated();
9722   int *ptr=getPointer();
9723   std::size_t nbOfElems=getNbOfElems();
9724   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9725     {
9726       if(*ptr>0)
9727         {
9728           *ptr=val%(*ptr);
9729         }
9730       else
9731         {
9732           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9733           oss << " !";
9734           throw INTERP_KERNEL::Exception(oss.str().c_str());
9735         }
9736     }
9737   declareAsNew();
9738 }
9739
9740 /*!
9741  * Modify all elements of \a this array, so that
9742  * an element _x_ becomes <em> val ^ x </em>.
9743  *  \param [in] val - the value used to apply pow on all array elements.
9744  *  \throw If \a this is not allocated.
9745  *  \throw If \a val < 0.
9746  */
9747 void DataArrayInt::applyPow(int val)
9748 {
9749   checkAllocated();
9750   if(val<0)
9751     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9752   int *ptr=getPointer();
9753   std::size_t nbOfElems=getNbOfElems();
9754   if(val==0)
9755     {
9756       std::fill(ptr,ptr+nbOfElems,1);
9757       return ;
9758     }
9759   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9760     {
9761       int tmp=1;
9762       for(int j=0;j<val;j++)
9763         tmp*=*ptr;
9764       *ptr=tmp;
9765     }
9766   declareAsNew();
9767 }
9768
9769 /*!
9770  * Modify all elements of \a this array, so that
9771  * an element _x_ becomes \f$ val ^ x \f$.
9772  *  \param [in] val - the value used to apply pow on all array elements.
9773  *  \throw If \a this is not allocated.
9774  *  \throw If there is an element < 0 in \a this array.
9775  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9776  *           array, all elements processed before detection of the zero element remain
9777  *           modified.
9778  */
9779 void DataArrayInt::applyRPow(int val)
9780 {
9781   checkAllocated();
9782   int *ptr=getPointer();
9783   std::size_t nbOfElems=getNbOfElems();
9784   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9785     {
9786       if(*ptr>=0)
9787         {
9788           int tmp=1;
9789           for(int j=0;j<*ptr;j++)
9790             tmp*=val;
9791           *ptr=tmp;
9792         }
9793       else
9794         {
9795           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9796           oss << " !";
9797           throw INTERP_KERNEL::Exception(oss.str().c_str());
9798         }
9799     }
9800   declareAsNew();
9801 }
9802
9803 /*!
9804  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9805  * of components in the result array is a sum of the number of components of given arrays
9806  * and (2) the number of tuples in the result array is same as that of each of given
9807  * arrays. In other words the i-th tuple of result array includes all components of
9808  * i-th tuples of all given arrays.
9809  * Number of tuples in the given arrays must be the same.
9810  *  \param [in] a1 - an array to include in the result array.
9811  *  \param [in] a2 - another array to include in the result array.
9812  *  \return DataArrayInt * - the new instance of DataArrayInt.
9813  *          The caller is to delete this result array using decrRef() as it is no more
9814  *          needed.
9815  *  \throw If both \a a1 and \a a2 are NULL.
9816  *  \throw If any given array is not allocated.
9817  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9818  */
9819 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9820 {
9821   std::vector<const DataArrayInt *> arr(2);
9822   arr[0]=a1; arr[1]=a2;
9823   return Meld(arr);
9824 }
9825
9826 /*!
9827  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9828  * of components in the result array is a sum of the number of components of given arrays
9829  * and (2) the number of tuples in the result array is same as that of each of given
9830  * arrays. In other words the i-th tuple of result array includes all components of
9831  * i-th tuples of all given arrays.
9832  * Number of tuples in the given arrays must be  the same.
9833  *  \param [in] arr - a sequence of arrays to include in the result array.
9834  *  \return DataArrayInt * - the new instance of DataArrayInt.
9835  *          The caller is to delete this result array using decrRef() as it is no more
9836  *          needed.
9837  *  \throw If all arrays within \a arr are NULL.
9838  *  \throw If any given array is not allocated.
9839  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9840  */
9841 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9842 {
9843   std::vector<const DataArrayInt *> a;
9844   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9845     if(*it4)
9846       a.push_back(*it4);
9847   if(a.empty())
9848     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9849   std::vector<const DataArrayInt *>::const_iterator it;
9850   for(it=a.begin();it!=a.end();it++)
9851     (*it)->checkAllocated();
9852   it=a.begin();
9853   int nbOfTuples=(*it)->getNumberOfTuples();
9854   std::vector<int> nbc(a.size());
9855   std::vector<const int *> pts(a.size());
9856   nbc[0]=(*it)->getNumberOfComponents();
9857   pts[0]=(*it++)->getConstPointer();
9858   for(int i=1;it!=a.end();it++,i++)
9859     {
9860       if(nbOfTuples!=(*it)->getNumberOfTuples())
9861         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9862       nbc[i]=(*it)->getNumberOfComponents();
9863       pts[i]=(*it)->getConstPointer();
9864     }
9865   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9866   DataArrayInt *ret=DataArrayInt::New();
9867   ret->alloc(nbOfTuples,totalNbOfComp);
9868   int *retPtr=ret->getPointer();
9869   for(int i=0;i<nbOfTuples;i++)
9870     for(int j=0;j<(int)a.size();j++)
9871       {
9872         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9873         pts[j]+=nbc[j];
9874       }
9875   int k=0;
9876   for(int i=0;i<(int)a.size();i++)
9877     for(int j=0;j<nbc[i];j++,k++)
9878       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9879   return ret;
9880 }
9881
9882 /*!
9883  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9884  * The i-th item of the result array is an ID of a set of elements belonging to a
9885  * unique set of groups, which the i-th element is a part of. This set of elements
9886  * belonging to a unique set of groups is called \a family, so the result array contains
9887  * IDs of families each element belongs to.
9888  *
9889  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9890  * then there are 3 families:
9891  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9892  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9893  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9894  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9895  * stands for the element #3 which is in none of groups.
9896  *
9897  *  \param [in] groups - sequence of groups of element IDs.
9898  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9899  *         in \a groups.
9900  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9901  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9902  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9903  *         delete this array using decrRef() as it is no more needed.
9904  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9905  */
9906 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9907 {
9908   std::vector<const DataArrayInt *> groups2;
9909   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9910     if(*it4)
9911       groups2.push_back(*it4);
9912   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9913   ret->alloc(newNb,1);
9914   int *retPtr=ret->getPointer();
9915   std::fill(retPtr,retPtr+newNb,0);
9916   int fid=1;
9917   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9918     {
9919       const int *ptr=(*iter)->getConstPointer();
9920       std::size_t nbOfElem=(*iter)->getNbOfElems();
9921       int sfid=fid;
9922       for(int j=0;j<sfid;j++)
9923         {
9924           bool found=false;
9925           for(std::size_t i=0;i<nbOfElem;i++)
9926             {
9927               if(ptr[i]>=0 && ptr[i]<newNb)
9928                 {
9929                   if(retPtr[ptr[i]]==j)
9930                     {
9931                       retPtr[ptr[i]]=fid;
9932                       found=true;
9933                     }
9934                 }
9935               else
9936                 {
9937                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9938                   oss << ") !";
9939                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9940                 }
9941             }
9942           if(found)
9943             fid++;
9944         }
9945     }
9946   fidsOfGroups.clear();
9947   fidsOfGroups.resize(groups2.size());
9948   int grId=0;
9949   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9950     {
9951       std::set<int> tmp;
9952       const int *ptr=(*iter)->getConstPointer();
9953       std::size_t nbOfElem=(*iter)->getNbOfElems();
9954       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9955         tmp.insert(retPtr[*p]);
9956       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9957     }
9958   return ret.retn();
9959 }
9960
9961 /*!
9962  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9963  * arrays. The result array does not contain any duplicates and its values
9964  * are sorted in ascending order.
9965  *  \param [in] arr - sequence of DataArrayInt's to unite.
9966  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9967  *         array using decrRef() as it is no more needed.
9968  *  \throw If any \a arr[i] is not allocated.
9969  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9970  */
9971 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9972 {
9973   std::vector<const DataArrayInt *> a;
9974   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9975     if(*it4)
9976       a.push_back(*it4);
9977   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9978     {
9979       (*it)->checkAllocated();
9980       if((*it)->getNumberOfComponents()!=1)
9981         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9982     }
9983   //
9984   std::set<int> r;
9985   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9986     {
9987       const int *pt=(*it)->getConstPointer();
9988       int nbOfTuples=(*it)->getNumberOfTuples();
9989       r.insert(pt,pt+nbOfTuples);
9990     }
9991   DataArrayInt *ret=DataArrayInt::New();
9992   ret->alloc((int)r.size(),1);
9993   std::copy(r.begin(),r.end(),ret->getPointer());
9994   return ret;
9995 }
9996
9997 /*!
9998  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9999  * arrays. The result array does not contain any duplicates and its values
10000  * are sorted in ascending order.
10001  *  \param [in] arr - sequence of DataArrayInt's to intersect.
10002  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10003  *         array using decrRef() as it is no more needed.
10004  *  \throw If any \a arr[i] is not allocated.
10005  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
10006  */
10007 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
10008 {
10009   std::vector<const DataArrayInt *> a;
10010   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
10011     if(*it4)
10012       a.push_back(*it4);
10013   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10014     {
10015       (*it)->checkAllocated();
10016       if((*it)->getNumberOfComponents()!=1)
10017         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
10018     }
10019   //
10020   std::set<int> r;
10021   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10022     {
10023       const int *pt=(*it)->getConstPointer();
10024       int nbOfTuples=(*it)->getNumberOfTuples();
10025       std::set<int> s1(pt,pt+nbOfTuples);
10026       if(it!=a.begin())
10027         {
10028           std::set<int> r2;
10029           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
10030           r=r2;
10031         }
10032       else
10033         r=s1;
10034     }
10035   DataArrayInt *ret(DataArrayInt::New());
10036   ret->alloc((int)r.size(),1);
10037   std::copy(r.begin(),r.end(),ret->getPointer());
10038   return ret;
10039 }
10040
10041 /// @cond INTERNAL
10042 namespace MEDCouplingImpl
10043 {
10044   class OpSwitchedOn
10045   {
10046   public:
10047     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
10048     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
10049   private:
10050     int *_pt;
10051     int _cnt;
10052   };
10053
10054   class OpSwitchedOff
10055   {
10056   public:
10057     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
10058     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
10059   private:
10060     int *_pt;
10061     int _cnt;
10062   };
10063 }
10064 /// @endcond
10065
10066 /*!
10067  * This method returns the list of ids in ascending mode so that v[id]==true.
10068  */
10069 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
10070 {
10071   int sz((int)std::count(v.begin(),v.end(),true));
10072   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10073   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
10074   return ret.retn();
10075 }
10076
10077 /*!
10078  * This method returns the list of ids in ascending mode so that v[id]==false.
10079  */
10080 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
10081 {
10082   int sz((int)std::count(v.begin(),v.end(),false));
10083   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10084   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
10085   return ret.retn();
10086 }
10087
10088 /*!
10089  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
10090  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
10091  *
10092  * \param [in] v the input data structure to be translate into skyline format.
10093  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
10094  * \param [out] dataIndex the second element of the skyline format.
10095  */
10096 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
10097 {
10098   int sz((int)v.size());
10099   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
10100   ret1->alloc(sz+1,1);
10101   int *pt(ret1->getPointer()); *pt=0;
10102   for(int i=0;i<sz;i++,pt++)
10103     pt[1]=pt[0]+(int)v[i].size();
10104   ret0->alloc(ret1->back(),1);
10105   pt=ret0->getPointer();
10106   for(int i=0;i<sz;i++)
10107     pt=std::copy(v[i].begin(),v[i].end(),pt);
10108   data=ret0.retn(); dataIndex=ret1.retn();
10109 }
10110
10111 /*!
10112  * Returns a new DataArrayInt which contains a complement of elements of \a this
10113  * one-dimensional array. I.e. the result array contains all elements from the range [0,
10114  * \a nbOfElement) not present in \a this array.
10115  *  \param [in] nbOfElement - maximal size of the result array.
10116  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10117  *         array using decrRef() as it is no more needed.
10118  *  \throw If \a this is not allocated.
10119  *  \throw If \a this->getNumberOfComponents() != 1.
10120  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
10121  *         nbOfElement ).
10122  */
10123 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
10124 {
10125   checkAllocated();
10126   if(getNumberOfComponents()!=1)
10127     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
10128   std::vector<bool> tmp(nbOfElement);
10129   const int *pt=getConstPointer();
10130   int nbOfTuples=getNumberOfTuples();
10131   for(const int *w=pt;w!=pt+nbOfTuples;w++)
10132     if(*w>=0 && *w<nbOfElement)
10133       tmp[*w]=true;
10134     else
10135       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
10136   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
10137   DataArrayInt *ret=DataArrayInt::New();
10138   ret->alloc(nbOfRetVal,1);
10139   int j=0;
10140   int *retPtr=ret->getPointer();
10141   for(int i=0;i<nbOfElement;i++)
10142     if(!tmp[i])
10143       retPtr[j++]=i;
10144   return ret;
10145 }
10146
10147 /*!
10148  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10149  * from an \a other one-dimensional array.
10150  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10151  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10152  *         caller is to delete this array using decrRef() as it is no more needed.
10153  *  \throw If \a other is NULL.
10154  *  \throw If \a other is not allocated.
10155  *  \throw If \a other->getNumberOfComponents() != 1.
10156  *  \throw If \a this is not allocated.
10157  *  \throw If \a this->getNumberOfComponents() != 1.
10158  *  \sa DataArrayInt::buildSubstractionOptimized()
10159  */
10160 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10161 {
10162   if(!other)
10163     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10164   checkAllocated();
10165   other->checkAllocated();
10166   if(getNumberOfComponents()!=1)
10167     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10168   if(other->getNumberOfComponents()!=1)
10169     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10170   const int *pt=getConstPointer();
10171   int nbOfTuples=getNumberOfTuples();
10172   std::set<int> s1(pt,pt+nbOfTuples);
10173   pt=other->getConstPointer();
10174   nbOfTuples=other->getNumberOfTuples();
10175   std::set<int> s2(pt,pt+nbOfTuples);
10176   std::vector<int> r;
10177   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10178   DataArrayInt *ret=DataArrayInt::New();
10179   ret->alloc((int)r.size(),1);
10180   std::copy(r.begin(),r.end(),ret->getPointer());
10181   return ret;
10182 }
10183
10184 /*!
10185  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10186  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10187  * 
10188  * \param [in] other an array with one component and expected to be sorted ascendingly.
10189  * \ret list of ids in \a this but not in \a other.
10190  * \sa DataArrayInt::buildSubstraction
10191  */
10192 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10193 {
10194   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10195   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10196   checkAllocated(); other->checkAllocated();
10197   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10198   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10199   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10200   const int *work1(pt1Bg),*work2(pt2Bg);
10201   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10202   for(;work1!=pt1End;work1++)
10203     {
10204       if(work2!=pt2End && *work1==*work2)
10205         work2++;
10206       else
10207         ret->pushBackSilent(*work1);
10208     }
10209   return ret.retn();
10210 }
10211
10212
10213 /*!
10214  * Returns a new DataArrayInt which contains all elements of \a this and a given
10215  * one-dimensional arrays. The result array does not contain any duplicates
10216  * and its values are sorted in ascending order.
10217  *  \param [in] other - an array to unite with \a this one.
10218  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10219  *         array using decrRef() as it is no more needed.
10220  *  \throw If \a this or \a other is not allocated.
10221  *  \throw If \a this->getNumberOfComponents() != 1.
10222  *  \throw If \a other->getNumberOfComponents() != 1.
10223  */
10224 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10225 {
10226   std::vector<const DataArrayInt *>arrs(2);
10227   arrs[0]=this; arrs[1]=other;
10228   return BuildUnion(arrs);
10229 }
10230
10231
10232 /*!
10233  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10234  * one-dimensional arrays. The result array does not contain any duplicates
10235  * and its values are sorted in ascending order.
10236  *  \param [in] other - an array to intersect with \a this one.
10237  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10238  *         array using decrRef() as it is no more needed.
10239  *  \throw If \a this or \a other is not allocated.
10240  *  \throw If \a this->getNumberOfComponents() != 1.
10241  *  \throw If \a other->getNumberOfComponents() != 1.
10242  */
10243 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10244 {
10245   std::vector<const DataArrayInt *>arrs(2);
10246   arrs[0]=this; arrs[1]=other;
10247   return BuildIntersection(arrs);
10248 }
10249
10250 /*!
10251  * This method can be applied on allocated with one component DataArrayInt instance.
10252  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10253  * 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]
10254  * 
10255  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10256  * \throw if \a this is not allocated or if \a this has not exactly one component.
10257  * \sa DataArrayInt::buildUniqueNotSorted
10258  */
10259 DataArrayInt *DataArrayInt::buildUnique() const
10260 {
10261   checkAllocated();
10262   if(getNumberOfComponents()!=1)
10263     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10264   int nbOfTuples=getNumberOfTuples();
10265   MCAuto<DataArrayInt> tmp=deepCopy();
10266   int *data=tmp->getPointer();
10267   int *last=std::unique(data,data+nbOfTuples);
10268   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10269   ret->alloc(std::distance(data,last),1);
10270   std::copy(data,last,ret->getPointer());
10271   return ret.retn();
10272 }
10273
10274 /*!
10275  * This method can be applied on allocated with one component DataArrayInt instance.
10276  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10277  *
10278  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10279  *
10280  * \throw if \a this is not allocated or if \a this has not exactly one component.
10281  *
10282  * \sa DataArrayInt::buildUnique
10283  */
10284 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10285 {
10286   checkAllocated();
10287     if(getNumberOfComponents()!=1)
10288       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10289   int minVal,maxVal;
10290   getMinMaxValues(minVal,maxVal);
10291   std::vector<bool> b(maxVal-minVal+1,false);
10292   const int *ptBg(begin()),*endBg(end());
10293   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10294   for(const int *pt=ptBg;pt!=endBg;pt++)
10295     {
10296       if(!b[*pt-minVal])
10297         {
10298           ret->pushBackSilent(*pt);
10299           b[*pt-minVal]=true;
10300         }
10301     }
10302   ret->copyStringInfoFrom(*this);
10303   return ret.retn();
10304 }
10305
10306 /*!
10307  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10308  * "index" array. Such "index" array is returned for example by 
10309  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
10310  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10311  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
10312  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10313  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
10314  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10315  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10316  *          The caller is to delete this array using decrRef() as it is no more needed. 
10317  *  \throw If \a this is not allocated.
10318  *  \throw If \a this->getNumberOfComponents() != 1.
10319  *  \throw If \a this->getNumberOfTuples() < 2.
10320  *
10321  *  \b Example: <br> 
10322  *         - this contains [1,3,6,7,7,9,15]
10323  *         - result array contains [2,3,1,0,2,6],
10324  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10325  *
10326  * \sa DataArrayInt::computeOffsetsFull
10327  */
10328 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10329 {
10330   checkAllocated();
10331   if(getNumberOfComponents()!=1)
10332     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10333   int nbOfTuples=getNumberOfTuples();
10334   if(nbOfTuples<2)
10335     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10336   const int *ptr=getConstPointer();
10337   DataArrayInt *ret=DataArrayInt::New();
10338   ret->alloc(nbOfTuples-1,1);
10339   int *out=ret->getPointer();
10340   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10341   return ret;
10342 }
10343
10344 /*!
10345  * Modifies \a this one-dimensional array so that value of each element \a x
10346  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10347  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10348  * and components remains the same.<br>
10349  * This method is useful for allToAllV in MPI with contiguous policy. This method
10350  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
10351  * this one.
10352  *  \throw If \a this is not allocated.
10353  *  \throw If \a this->getNumberOfComponents() != 1.
10354  *
10355  *  \b Example: <br>
10356  *          - Before \a this contains [3,5,1,2,0,8]
10357  *          - After \a this contains  [0,3,8,9,11,11]<br>
10358  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10359  *          array is retained and thus there is no space to store the last element.
10360  */
10361 void DataArrayInt::computeOffsets()
10362 {
10363   checkAllocated();
10364   if(getNumberOfComponents()!=1)
10365     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10366   int nbOfTuples=getNumberOfTuples();
10367   if(nbOfTuples==0)
10368     return ;
10369   int *work=getPointer();
10370   int tmp=work[0];
10371   work[0]=0;
10372   for(int i=1;i<nbOfTuples;i++)
10373     {
10374       int tmp2=work[i];
10375       work[i]=work[i-1]+tmp;
10376       tmp=tmp2;
10377     }
10378   declareAsNew();
10379 }
10380
10381
10382 /*!
10383  * Modifies \a this one-dimensional array so that value of each element \a x
10384  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10385  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10386  * components remains the same and number of tuples is inceamented by one.<br>
10387  * This method is useful for allToAllV in MPI with contiguous policy. This method
10388  * differs from computeOffsets() in that the number of tuples is changed by this one.
10389  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10390  *  \throw If \a this is not allocated.
10391  *  \throw If \a this->getNumberOfComponents() != 1.
10392  *
10393  *  \b Example: <br>
10394  *          - Before \a this contains [3,5,1,2,0,8]
10395  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10396  * \sa DataArrayInt::deltaShiftIndex
10397  */
10398 void DataArrayInt::computeOffsetsFull()
10399 {
10400   checkAllocated();
10401   if(getNumberOfComponents()!=1)
10402     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
10403   int nbOfTuples=getNumberOfTuples();
10404   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10405   const int *work=getConstPointer();
10406   ret[0]=0;
10407   for(int i=0;i<nbOfTuples;i++)
10408     ret[i+1]=work[i]+ret[i];
10409   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10410   declareAsNew();
10411 }
10412
10413 /*!
10414  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10415  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
10416  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10417  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10418  * filling completely one of the ranges in \a this.
10419  *
10420  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10421  * \param [out] rangeIdsFetched the range ids fetched
10422  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10423  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10424  *
10425  * \sa DataArrayInt::computeOffsetsFull
10426  *
10427  *  \b Example: <br>
10428  *          - \a this : [0,3,7,9,15,18]
10429  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10430  *          - \a rangeIdsFetched result array: [0,2,4]
10431  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10432  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10433  * <br>
10434  */
10435 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10436 {
10437   if(!listOfIds)
10438     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
10439   listOfIds->checkAllocated(); checkAllocated();
10440   if(listOfIds->getNumberOfComponents()!=1)
10441     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
10442   if(getNumberOfComponents()!=1)
10443     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
10444   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10445   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10446   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10447   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10448   while(tupPtr!=tupEnd && offPtr!=offEnd)
10449     {
10450       if(*tupPtr==*offPtr)
10451         {
10452           int i=offPtr[0];
10453           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10454           if(i==offPtr[1])
10455             {
10456               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10457               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10458               offPtr++;
10459             }
10460         }
10461       else
10462         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10463     }
10464   rangeIdsFetched=ret0.retn();
10465   idsInInputListThatFetch=ret1.retn();
10466 }
10467
10468 /*!
10469  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10470  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10471  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10472  * beginning within the "iota" array. And \a this is a one-dimensional array
10473  * considered as a selector of groups described by \a offsets to include into the result array.
10474  *  \throw If \a offsets is NULL.
10475  *  \throw If \a offsets is not allocated.
10476  *  \throw If \a offsets->getNumberOfComponents() != 1.
10477  *  \throw If \a offsets is not monotonically increasing.
10478  *  \throw If \a this is not allocated.
10479  *  \throw If \a this->getNumberOfComponents() != 1.
10480  *  \throw If any element of \a this is not a valid index for \a offsets array.
10481  *
10482  *  \b Example: <br>
10483  *          - \a this: [0,2,3]
10484  *          - \a offsets: [0,3,6,10,14,20]
10485  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10486  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10487  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10488  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10489  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10490  */
10491 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10492 {
10493   if(!offsets)
10494     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10495   checkAllocated();
10496   if(getNumberOfComponents()!=1)
10497     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10498   offsets->checkAllocated();
10499   if(offsets->getNumberOfComponents()!=1)
10500     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10501   int othNbTuples=offsets->getNumberOfTuples()-1;
10502   int nbOfTuples=getNumberOfTuples();
10503   int retNbOftuples=0;
10504   const int *work=getConstPointer();
10505   const int *offPtr=offsets->getConstPointer();
10506   for(int i=0;i<nbOfTuples;i++)
10507     {
10508       int val=work[i];
10509       if(val>=0 && val<othNbTuples)
10510         {
10511           int delta=offPtr[val+1]-offPtr[val];
10512           if(delta>=0)
10513             retNbOftuples+=delta;
10514           else
10515             {
10516               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10517               throw INTERP_KERNEL::Exception(oss.str().c_str());
10518             }
10519         }
10520       else
10521         {
10522           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10523           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10524           throw INTERP_KERNEL::Exception(oss.str().c_str());
10525         }
10526     }
10527   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10528   ret->alloc(retNbOftuples,1);
10529   int *retPtr=ret->getPointer();
10530   for(int i=0;i<nbOfTuples;i++)
10531     {
10532       int val=work[i];
10533       int start=offPtr[val];
10534       int off=offPtr[val+1]-start;
10535       for(int j=0;j<off;j++,retPtr++)
10536         *retPtr=start+j;
10537     }
10538   return ret.retn();
10539 }
10540
10541 /*!
10542  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10543  * scaled array (monotonically increasing).
10544 from that of \a this and \a
10545  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10546  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10547  * beginning within the "iota" array. And \a this is a one-dimensional array
10548  * considered as a selector of groups described by \a offsets to include into the result array.
10549  *  \throw If \a  is NULL.
10550  *  \throw If \a this is not allocated.
10551  *  \throw If \a this->getNumberOfComponents() != 1.
10552  *  \throw If \a this->getNumberOfTuples() == 0.
10553  *  \throw If \a this is not monotonically increasing.
10554  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10555  *
10556  *  \b Example: <br>
10557  *          - \a bg , \a stop and \a step : (0,5,2)
10558  *          - \a this: [0,3,6,10,14,20]
10559  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10560  */
10561 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10562 {
10563   if(!isAllocated())
10564     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10565   if(getNumberOfComponents()!=1)
10566     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10567   int nbOfTuples(getNumberOfTuples());
10568   if(nbOfTuples==0)
10569     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10570   const int *ids(begin());
10571   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10572   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10573     {
10574       if(pos>=0 && pos<nbOfTuples-1)
10575         {
10576           int delta(ids[pos+1]-ids[pos]);
10577           sz+=delta;
10578           if(delta<0)
10579             {
10580               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10581               throw INTERP_KERNEL::Exception(oss.str().c_str());
10582             }          
10583         }
10584       else
10585         {
10586           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10587           throw INTERP_KERNEL::Exception(oss.str().c_str());
10588         }
10589     }
10590   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10591   int *retPtr(ret->getPointer());
10592   pos=bg;
10593   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10594     {
10595       int delta(ids[pos+1]-ids[pos]);
10596       for(int j=0;j<delta;j++,retPtr++)
10597         *retPtr=pos;
10598     }
10599   return ret.retn();
10600 }
10601
10602 /*!
10603  * 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.
10604  * 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
10605  * in tuple **i** of returned DataArrayInt.
10606  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10607  *
10608  * 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)]
10609  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10610  * 
10611  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10612  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10613  * \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
10614  *        is thrown if no ranges in \a ranges contains value in \a this.
10615  * 
10616  * \sa DataArrayInt::findIdInRangeForEachTuple
10617  */
10618 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10619 {
10620   if(!ranges)
10621     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10622   if(ranges->getNumberOfComponents()!=2)
10623     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10624   checkAllocated();
10625   if(getNumberOfComponents()!=1)
10626     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10627   int nbTuples=getNumberOfTuples();
10628   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10629   int nbOfRanges=ranges->getNumberOfTuples();
10630   const int *rangesPtr=ranges->getConstPointer();
10631   int *retPtr=ret->getPointer();
10632   const int *inPtr=getConstPointer();
10633   for(int i=0;i<nbTuples;i++,retPtr++)
10634     {
10635       int val=inPtr[i];
10636       bool found=false;
10637       for(int j=0;j<nbOfRanges && !found;j++)
10638         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10639           { *retPtr=j; found=true; }
10640       if(found)
10641         continue;
10642       else
10643         {
10644           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10645           throw INTERP_KERNEL::Exception(oss.str().c_str());
10646         }
10647     }
10648   return ret.retn();
10649 }
10650
10651 /*!
10652  * 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.
10653  * 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
10654  * in tuple **i** of returned DataArrayInt.
10655  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10656  *
10657  * 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)]
10658  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10659  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10660  * 
10661  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10662  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10663  * \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
10664  *        is thrown if no ranges in \a ranges contains value in \a this.
10665  * \sa DataArrayInt::findRangeIdForEachTuple
10666  */
10667 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10668 {
10669   if(!ranges)
10670     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10671   if(ranges->getNumberOfComponents()!=2)
10672     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10673   checkAllocated();
10674   if(getNumberOfComponents()!=1)
10675     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10676   int nbTuples=getNumberOfTuples();
10677   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10678   int nbOfRanges=ranges->getNumberOfTuples();
10679   const int *rangesPtr=ranges->getConstPointer();
10680   int *retPtr=ret->getPointer();
10681   const int *inPtr=getConstPointer();
10682   for(int i=0;i<nbTuples;i++,retPtr++)
10683     {
10684       int val=inPtr[i];
10685       bool found=false;
10686       for(int j=0;j<nbOfRanges && !found;j++)
10687         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10688           { *retPtr=val-rangesPtr[2*j]; found=true; }
10689       if(found)
10690         continue;
10691       else
10692         {
10693           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10694           throw INTERP_KERNEL::Exception(oss.str().c_str());
10695         }
10696     }
10697   return ret.retn();
10698 }
10699
10700 /*!
10701  * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2).
10702  * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0).
10703  * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified !
10704  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10705  * This method does nothing if number of tuples is lower of equal to 1.
10706  *
10707  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10708  *
10709  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10710  */
10711 void DataArrayInt::sortEachPairToMakeALinkedList()
10712 {
10713   checkAllocated();
10714   if(getNumberOfComponents()!=2)
10715     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10716   int nbOfTuples(getNumberOfTuples());
10717   if(nbOfTuples<=1)
10718     return ;
10719   int *conn(getPointer());
10720   for(int i=1;i<nbOfTuples;i++,conn+=2)
10721     {
10722       if(i>1)
10723         {
10724           if(conn[2]==conn[3])
10725             {
10726               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10727               throw INTERP_KERNEL::Exception(oss.str().c_str());
10728             }
10729           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10730             std::swap(conn[2],conn[3]);
10731           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10732           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10733             {
10734               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10735               throw INTERP_KERNEL::Exception(oss.str().c_str());
10736             }
10737         }
10738       else
10739         {
10740           if(conn[0]==conn[1] || conn[2]==conn[3])
10741             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10742           int tmp[4];
10743           std::set<int> s;
10744           s.insert(conn,conn+4);
10745           if(s.size()!=3)
10746             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10747           if(std::count(conn,conn+4,conn[0])==2)
10748             {
10749               tmp[0]=conn[1];
10750               tmp[1]=conn[0];
10751               tmp[2]=conn[0];
10752               if(conn[2]==conn[0])
10753                 { tmp[3]=conn[3]; }
10754               else
10755                 { tmp[3]=conn[2];}
10756               std::copy(tmp,tmp+4,conn);
10757             }
10758         }
10759     }
10760 }
10761
10762 /*!
10763  * 
10764  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10765  *             \a nbTimes  should be at least equal to 1.
10766  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10767  * \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.
10768  */
10769 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10770 {
10771   checkAllocated();
10772   if(getNumberOfComponents()!=1)
10773     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10774   if(nbTimes<1)
10775     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10776   int nbTuples=getNumberOfTuples();
10777   const int *inPtr=getConstPointer();
10778   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10779   int *retPtr=ret->getPointer();
10780   for(int i=0;i<nbTuples;i++,inPtr++)
10781     {
10782       int val=*inPtr;
10783       for(int j=0;j<nbTimes;j++,retPtr++)
10784         *retPtr=val;
10785     }
10786   ret->copyStringInfoFrom(*this);
10787   return ret.retn();
10788 }
10789
10790 /*!
10791  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10792  * But the number of components can be different from one.
10793  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10794  */
10795 DataArrayInt *DataArrayInt::getDifferentValues() const
10796 {
10797   checkAllocated();
10798   std::set<int> ret;
10799   ret.insert(begin(),end());
10800   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10801   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10802   return ret2.retn();
10803 }
10804
10805 /*!
10806  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10807  * them it tells which tuple id have this id.
10808  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10809  * This method returns two arrays having same size.
10810  * 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.
10811  * 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]]
10812  */
10813 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10814 {
10815   checkAllocated();
10816   if(getNumberOfComponents()!=1)
10817     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10818   int id=0;
10819   std::map<int,int> m,m2,m3;
10820   for(const int *w=begin();w!=end();w++)
10821     m[*w]++;
10822   differentIds.resize(m.size());
10823   std::vector<DataArrayInt *> ret(m.size());
10824   std::vector<int *> retPtr(m.size());
10825   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10826     {
10827       m2[(*it).first]=id;
10828       ret[id]=DataArrayInt::New();
10829       ret[id]->alloc((*it).second,1);
10830       retPtr[id]=ret[id]->getPointer();
10831       differentIds[id]=(*it).first;
10832     }
10833   id=0;
10834   for(const int *w=begin();w!=end();w++,id++)
10835     {
10836       retPtr[m2[*w]][m3[*w]++]=id;
10837     }
10838   return ret;
10839 }
10840
10841 /*!
10842  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10843  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10844  *
10845  * \param [in] nbOfSlices - number of slices expected.
10846  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10847  * 
10848  * \sa DataArray::GetSlice
10849  * \throw If \a this is not allocated or not with exactly one component.
10850  * \throw If an element in \a this if < 0.
10851  */
10852 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10853 {
10854   if(!isAllocated() || getNumberOfComponents()!=1)
10855     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10856   if(nbOfSlices<=0)
10857     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10858   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10859   int sumPerSlc(sum/nbOfSlices),pos(0);
10860   const int *w(begin());
10861   std::vector< std::pair<int,int> > ret(nbOfSlices);
10862   for(int i=0;i<nbOfSlices;i++)
10863     {
10864       std::pair<int,int> p(pos,-1);
10865       int locSum(0);
10866       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10867       if(i!=nbOfSlices-1)
10868         p.second=pos;
10869       else
10870         p.second=nbOfTuples;
10871       ret[i]=p;
10872     }
10873   return ret;
10874 }
10875
10876 /*!
10877  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10878  * valid cases.
10879  * 1.  The arrays have same number of tuples and components. Then each value of
10880  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10881  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10882  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10883  *   component. Then
10884  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10885  * 3.  The arrays have same number of components and one array, say _a2_, has one
10886  *   tuple. Then
10887  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10888  *
10889  * Info on components is copied either from the first array (in the first case) or from
10890  * the array with maximal number of elements (getNbOfElems()).
10891  *  \param [in] a1 - an array to sum up.
10892  *  \param [in] a2 - another array to sum up.
10893  *  \return DataArrayInt * - the new instance of DataArrayInt.
10894  *          The caller is to delete this result array using decrRef() as it is no more
10895  *          needed.
10896  *  \throw If either \a a1 or \a a2 is NULL.
10897  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10898  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10899  *         none of them has number of tuples or components equal to 1.
10900  */
10901 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10902 {
10903   if(!a1 || !a2)
10904     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10905   int nbOfTuple=a1->getNumberOfTuples();
10906   int nbOfTuple2=a2->getNumberOfTuples();
10907   int nbOfComp=a1->getNumberOfComponents();
10908   int nbOfComp2=a2->getNumberOfComponents();
10909   MCAuto<DataArrayInt> ret=0;
10910   if(nbOfTuple==nbOfTuple2)
10911     {
10912       if(nbOfComp==nbOfComp2)
10913         {
10914           ret=DataArrayInt::New();
10915           ret->alloc(nbOfTuple,nbOfComp);
10916           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10917           ret->copyStringInfoFrom(*a1);
10918         }
10919       else
10920         {
10921           int nbOfCompMin,nbOfCompMax;
10922           const DataArrayInt *aMin, *aMax;
10923           if(nbOfComp>nbOfComp2)
10924             {
10925               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10926               aMin=a2; aMax=a1;
10927             }
10928           else
10929             {
10930               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10931               aMin=a1; aMax=a2;
10932             }
10933           if(nbOfCompMin==1)
10934             {
10935               ret=DataArrayInt::New();
10936               ret->alloc(nbOfTuple,nbOfCompMax);
10937               const int *aMinPtr=aMin->getConstPointer();
10938               const int *aMaxPtr=aMax->getConstPointer();
10939               int *res=ret->getPointer();
10940               for(int i=0;i<nbOfTuple;i++)
10941                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10942               ret->copyStringInfoFrom(*aMax);
10943             }
10944           else
10945             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10946         }
10947     }
10948   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10949     {
10950       if(nbOfComp==nbOfComp2)
10951         {
10952           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10953           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10954           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10955           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10956           ret=DataArrayInt::New();
10957           ret->alloc(nbOfTupleMax,nbOfComp);
10958           int *res=ret->getPointer();
10959           for(int i=0;i<nbOfTupleMax;i++)
10960             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10961           ret->copyStringInfoFrom(*aMax);
10962         }
10963       else
10964         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10965     }
10966   else
10967     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10968   return ret.retn();
10969 }
10970
10971 /*!
10972  * Adds values of another DataArrayInt to values of \a this one. There are 3
10973  * valid cases.
10974  * 1.  The arrays have same number of tuples and components. Then each value of
10975  *   \a other array is added to the corresponding value of \a this array, i.e.:
10976  *   _a_ [ i, j ] += _other_ [ i, j ].
10977  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10978  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10979  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10980  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10981  *
10982  *  \param [in] other - an array to add to \a this one.
10983  *  \throw If \a other is NULL.
10984  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10985  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10986  *         \a other has number of both tuples and components not equal to 1.
10987  */
10988 void DataArrayInt::addEqual(const DataArrayInt *other)
10989 {
10990   if(!other)
10991     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10992   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10993   checkAllocated(); other->checkAllocated();
10994   int nbOfTuple=getNumberOfTuples();
10995   int nbOfTuple2=other->getNumberOfTuples();
10996   int nbOfComp=getNumberOfComponents();
10997   int nbOfComp2=other->getNumberOfComponents();
10998   if(nbOfTuple==nbOfTuple2)
10999     {
11000       if(nbOfComp==nbOfComp2)
11001         {
11002           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
11003         }
11004       else if(nbOfComp2==1)
11005         {
11006           int *ptr=getPointer();
11007           const int *ptrc=other->getConstPointer();
11008           for(int i=0;i<nbOfTuple;i++)
11009             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
11010         }
11011       else
11012         throw INTERP_KERNEL::Exception(msg);
11013     }
11014   else if(nbOfTuple2==1)
11015     {
11016       if(nbOfComp2==nbOfComp)
11017         {
11018           int *ptr=getPointer();
11019           const int *ptrc=other->getConstPointer();
11020           for(int i=0;i<nbOfTuple;i++)
11021             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
11022         }
11023       else
11024         throw INTERP_KERNEL::Exception(msg);
11025     }
11026   else
11027     throw INTERP_KERNEL::Exception(msg);
11028   declareAsNew();
11029 }
11030
11031 /*!
11032  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
11033  * valid cases.
11034  * 1.  The arrays have same number of tuples and components. Then each value of
11035  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
11036  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
11037  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11038  *   component. Then
11039  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
11040  * 3.  The arrays have same number of components and one array, say _a2_, has one
11041  *   tuple. Then
11042  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
11043  *
11044  * Info on components is copied either from the first array (in the first case) or from
11045  * the array with maximal number of elements (getNbOfElems()).
11046  *  \param [in] a1 - an array to subtract from.
11047  *  \param [in] a2 - an array to subtract.
11048  *  \return DataArrayInt * - the new instance of DataArrayInt.
11049  *          The caller is to delete this result array using decrRef() as it is no more
11050  *          needed.
11051  *  \throw If either \a a1 or \a a2 is NULL.
11052  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11053  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11054  *         none of them has number of tuples or components equal to 1.
11055  */
11056 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
11057 {
11058   if(!a1 || !a2)
11059     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
11060   int nbOfTuple1=a1->getNumberOfTuples();
11061   int nbOfTuple2=a2->getNumberOfTuples();
11062   int nbOfComp1=a1->getNumberOfComponents();
11063   int nbOfComp2=a2->getNumberOfComponents();
11064   if(nbOfTuple2==nbOfTuple1)
11065     {
11066       if(nbOfComp1==nbOfComp2)
11067         {
11068           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11069           ret->alloc(nbOfTuple2,nbOfComp1);
11070           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
11071           ret->copyStringInfoFrom(*a1);
11072           return ret.retn();
11073         }
11074       else if(nbOfComp2==1)
11075         {
11076           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11077           ret->alloc(nbOfTuple1,nbOfComp1);
11078           const int *a2Ptr=a2->getConstPointer();
11079           const int *a1Ptr=a1->getConstPointer();
11080           int *res=ret->getPointer();
11081           for(int i=0;i<nbOfTuple1;i++)
11082             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
11083           ret->copyStringInfoFrom(*a1);
11084           return ret.retn();
11085         }
11086       else
11087         {
11088           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11089           return 0;
11090         }
11091     }
11092   else if(nbOfTuple2==1)
11093     {
11094       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11095       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11096       ret->alloc(nbOfTuple1,nbOfComp1);
11097       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11098       int *pt=ret->getPointer();
11099       for(int i=0;i<nbOfTuple1;i++)
11100         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
11101       ret->copyStringInfoFrom(*a1);
11102       return ret.retn();
11103     }
11104   else
11105     {
11106       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
11107       return 0;
11108     }
11109 }
11110
11111 /*!
11112  * Subtract values of another DataArrayInt from values of \a this one. There are 3
11113  * valid cases.
11114  * 1.  The arrays have same number of tuples and components. Then each value of
11115  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
11116  *   _a_ [ i, j ] -= _other_ [ i, j ].
11117  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11118  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
11119  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11120  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
11121  *
11122  *  \param [in] other - an array to subtract from \a this one.
11123  *  \throw If \a other is NULL.
11124  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11125  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11126  *         \a other has number of both tuples and components not equal to 1.
11127  */
11128 void DataArrayInt::substractEqual(const DataArrayInt *other)
11129 {
11130   if(!other)
11131     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
11132   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
11133   checkAllocated(); other->checkAllocated();
11134   int nbOfTuple=getNumberOfTuples();
11135   int nbOfTuple2=other->getNumberOfTuples();
11136   int nbOfComp=getNumberOfComponents();
11137   int nbOfComp2=other->getNumberOfComponents();
11138   if(nbOfTuple==nbOfTuple2)
11139     {
11140       if(nbOfComp==nbOfComp2)
11141         {
11142           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
11143         }
11144       else if(nbOfComp2==1)
11145         {
11146           int *ptr=getPointer();
11147           const int *ptrc=other->getConstPointer();
11148           for(int i=0;i<nbOfTuple;i++)
11149             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11150         }
11151       else
11152         throw INTERP_KERNEL::Exception(msg);
11153     }
11154   else if(nbOfTuple2==1)
11155     {
11156       int *ptr=getPointer();
11157       const int *ptrc=other->getConstPointer();
11158       for(int i=0;i<nbOfTuple;i++)
11159         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11160     }
11161   else
11162     throw INTERP_KERNEL::Exception(msg);
11163   declareAsNew();
11164 }
11165
11166 /*!
11167  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11168  * valid cases.
11169  * 1.  The arrays have same number of tuples and components. Then each value of
11170  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11171  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11172  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11173  *   component. Then
11174  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11175  * 3.  The arrays have same number of components and one array, say _a2_, has one
11176  *   tuple. Then
11177  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11178  *
11179  * Info on components is copied either from the first array (in the first case) or from
11180  * the array with maximal number of elements (getNbOfElems()).
11181  *  \param [in] a1 - a factor array.
11182  *  \param [in] a2 - another factor array.
11183  *  \return DataArrayInt * - the new instance of DataArrayInt.
11184  *          The caller is to delete this result array using decrRef() as it is no more
11185  *          needed.
11186  *  \throw If either \a a1 or \a a2 is NULL.
11187  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11188  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11189  *         none of them has number of tuples or components equal to 1.
11190  */
11191 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11192 {
11193   if(!a1 || !a2)
11194     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11195   int nbOfTuple=a1->getNumberOfTuples();
11196   int nbOfTuple2=a2->getNumberOfTuples();
11197   int nbOfComp=a1->getNumberOfComponents();
11198   int nbOfComp2=a2->getNumberOfComponents();
11199   MCAuto<DataArrayInt> ret=0;
11200   if(nbOfTuple==nbOfTuple2)
11201     {
11202       if(nbOfComp==nbOfComp2)
11203         {
11204           ret=DataArrayInt::New();
11205           ret->alloc(nbOfTuple,nbOfComp);
11206           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11207           ret->copyStringInfoFrom(*a1);
11208         }
11209       else
11210         {
11211           int nbOfCompMin,nbOfCompMax;
11212           const DataArrayInt *aMin, *aMax;
11213           if(nbOfComp>nbOfComp2)
11214             {
11215               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11216               aMin=a2; aMax=a1;
11217             }
11218           else
11219             {
11220               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11221               aMin=a1; aMax=a2;
11222             }
11223           if(nbOfCompMin==1)
11224             {
11225               ret=DataArrayInt::New();
11226               ret->alloc(nbOfTuple,nbOfCompMax);
11227               const int *aMinPtr=aMin->getConstPointer();
11228               const int *aMaxPtr=aMax->getConstPointer();
11229               int *res=ret->getPointer();
11230               for(int i=0;i<nbOfTuple;i++)
11231                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11232               ret->copyStringInfoFrom(*aMax);
11233             }
11234           else
11235             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11236         }
11237     }
11238   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11239     {
11240       if(nbOfComp==nbOfComp2)
11241         {
11242           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11243           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11244           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11245           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11246           ret=DataArrayInt::New();
11247           ret->alloc(nbOfTupleMax,nbOfComp);
11248           int *res=ret->getPointer();
11249           for(int i=0;i<nbOfTupleMax;i++)
11250             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11251           ret->copyStringInfoFrom(*aMax);
11252         }
11253       else
11254         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11255     }
11256   else
11257     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11258   return ret.retn();
11259 }
11260
11261
11262 /*!
11263  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11264  * valid cases.
11265  * 1.  The arrays have same number of tuples and components. Then each value of
11266  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11267  *   _a_ [ i, j ] *= _other_ [ i, j ].
11268  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11269  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11270  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11271  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11272  *
11273  *  \param [in] other - an array to multiply to \a this one.
11274  *  \throw If \a other is NULL.
11275  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11276  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11277  *         \a other has number of both tuples and components not equal to 1.
11278  */
11279 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11280 {
11281   if(!other)
11282     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11283   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11284   checkAllocated(); other->checkAllocated();
11285   int nbOfTuple=getNumberOfTuples();
11286   int nbOfTuple2=other->getNumberOfTuples();
11287   int nbOfComp=getNumberOfComponents();
11288   int nbOfComp2=other->getNumberOfComponents();
11289   if(nbOfTuple==nbOfTuple2)
11290     {
11291       if(nbOfComp==nbOfComp2)
11292         {
11293           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11294         }
11295       else if(nbOfComp2==1)
11296         {
11297           int *ptr=getPointer();
11298           const int *ptrc=other->getConstPointer();
11299           for(int i=0;i<nbOfTuple;i++)
11300             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11301         }
11302       else
11303         throw INTERP_KERNEL::Exception(msg);
11304     }
11305   else if(nbOfTuple2==1)
11306     {
11307       if(nbOfComp2==nbOfComp)
11308         {
11309           int *ptr=getPointer();
11310           const int *ptrc=other->getConstPointer();
11311           for(int i=0;i<nbOfTuple;i++)
11312             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11313         }
11314       else
11315         throw INTERP_KERNEL::Exception(msg);
11316     }
11317   else
11318     throw INTERP_KERNEL::Exception(msg);
11319   declareAsNew();
11320 }
11321
11322
11323 /*!
11324  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11325  * valid cases.
11326  * 1.  The arrays have same number of tuples and components. Then each value of
11327  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11328  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11329  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11330  *   component. Then
11331  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11332  * 3.  The arrays have same number of components and one array, say _a2_, has one
11333  *   tuple. Then
11334  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11335  *
11336  * Info on components is copied either from the first array (in the first case) or from
11337  * the array with maximal number of elements (getNbOfElems()).
11338  *  \warning No check of division by zero is performed!
11339  *  \param [in] a1 - a numerator array.
11340  *  \param [in] a2 - a denominator array.
11341  *  \return DataArrayInt * - the new instance of DataArrayInt.
11342  *          The caller is to delete this result array using decrRef() as it is no more
11343  *          needed.
11344  *  \throw If either \a a1 or \a a2 is NULL.
11345  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11346  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11347  *         none of them has number of tuples or components equal to 1.
11348  */
11349 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11350 {
11351   if(!a1 || !a2)
11352     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11353   int nbOfTuple1=a1->getNumberOfTuples();
11354   int nbOfTuple2=a2->getNumberOfTuples();
11355   int nbOfComp1=a1->getNumberOfComponents();
11356   int nbOfComp2=a2->getNumberOfComponents();
11357   if(nbOfTuple2==nbOfTuple1)
11358     {
11359       if(nbOfComp1==nbOfComp2)
11360         {
11361           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11362           ret->alloc(nbOfTuple2,nbOfComp1);
11363           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11364           ret->copyStringInfoFrom(*a1);
11365           return ret.retn();
11366         }
11367       else if(nbOfComp2==1)
11368         {
11369           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11370           ret->alloc(nbOfTuple1,nbOfComp1);
11371           const int *a2Ptr=a2->getConstPointer();
11372           const int *a1Ptr=a1->getConstPointer();
11373           int *res=ret->getPointer();
11374           for(int i=0;i<nbOfTuple1;i++)
11375             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11376           ret->copyStringInfoFrom(*a1);
11377           return ret.retn();
11378         }
11379       else
11380         {
11381           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11382           return 0;
11383         }
11384     }
11385   else if(nbOfTuple2==1)
11386     {
11387       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11388       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11389       ret->alloc(nbOfTuple1,nbOfComp1);
11390       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11391       int *pt=ret->getPointer();
11392       for(int i=0;i<nbOfTuple1;i++)
11393         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11394       ret->copyStringInfoFrom(*a1);
11395       return ret.retn();
11396     }
11397   else
11398     {
11399       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11400       return 0;
11401     }
11402 }
11403
11404 /*!
11405  * Divide values of \a this array by values of another DataArrayInt. There are 3
11406  * valid cases.
11407  * 1.  The arrays have same number of tuples and components. Then each value of
11408  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11409  *   _a_ [ i, j ] /= _other_ [ i, j ].
11410  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11411  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11412  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11413  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11414  *
11415  *  \warning No check of division by zero is performed!
11416  *  \param [in] other - an array to divide \a this one by.
11417  *  \throw If \a other is NULL.
11418  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11419  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11420  *         \a other has number of both tuples and components not equal to 1.
11421  */
11422 void DataArrayInt::divideEqual(const DataArrayInt *other)
11423 {
11424   if(!other)
11425     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11426   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11427   checkAllocated(); other->checkAllocated();
11428   int nbOfTuple=getNumberOfTuples();
11429   int nbOfTuple2=other->getNumberOfTuples();
11430   int nbOfComp=getNumberOfComponents();
11431   int nbOfComp2=other->getNumberOfComponents();
11432   if(nbOfTuple==nbOfTuple2)
11433     {
11434       if(nbOfComp==nbOfComp2)
11435         {
11436           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11437         }
11438       else if(nbOfComp2==1)
11439         {
11440           int *ptr=getPointer();
11441           const int *ptrc=other->getConstPointer();
11442           for(int i=0;i<nbOfTuple;i++)
11443             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11444         }
11445       else
11446         throw INTERP_KERNEL::Exception(msg);
11447     }
11448   else if(nbOfTuple2==1)
11449     {
11450       if(nbOfComp2==nbOfComp)
11451         {
11452           int *ptr=getPointer();
11453           const int *ptrc=other->getConstPointer();
11454           for(int i=0;i<nbOfTuple;i++)
11455             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11456         }
11457       else
11458         throw INTERP_KERNEL::Exception(msg);
11459     }
11460   else
11461     throw INTERP_KERNEL::Exception(msg);
11462   declareAsNew();
11463 }
11464
11465
11466 /*!
11467  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11468  * valid cases.
11469  * 1.  The arrays have same number of tuples and components. Then each value of
11470  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11471  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11472  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11473  *   component. Then
11474  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11475  * 3.  The arrays have same number of components and one array, say _a2_, has one
11476  *   tuple. Then
11477  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11478  *
11479  * Info on components is copied either from the first array (in the first case) or from
11480  * the array with maximal number of elements (getNbOfElems()).
11481  *  \warning No check of division by zero is performed!
11482  *  \param [in] a1 - a dividend array.
11483  *  \param [in] a2 - a divisor array.
11484  *  \return DataArrayInt * - the new instance of DataArrayInt.
11485  *          The caller is to delete this result array using decrRef() as it is no more
11486  *          needed.
11487  *  \throw If either \a a1 or \a a2 is NULL.
11488  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11489  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11490  *         none of them has number of tuples or components equal to 1.
11491  */
11492 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11493 {
11494   if(!a1 || !a2)
11495     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11496   int nbOfTuple1=a1->getNumberOfTuples();
11497   int nbOfTuple2=a2->getNumberOfTuples();
11498   int nbOfComp1=a1->getNumberOfComponents();
11499   int nbOfComp2=a2->getNumberOfComponents();
11500   if(nbOfTuple2==nbOfTuple1)
11501     {
11502       if(nbOfComp1==nbOfComp2)
11503         {
11504           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11505           ret->alloc(nbOfTuple2,nbOfComp1);
11506           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11507           ret->copyStringInfoFrom(*a1);
11508           return ret.retn();
11509         }
11510       else if(nbOfComp2==1)
11511         {
11512           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11513           ret->alloc(nbOfTuple1,nbOfComp1);
11514           const int *a2Ptr=a2->getConstPointer();
11515           const int *a1Ptr=a1->getConstPointer();
11516           int *res=ret->getPointer();
11517           for(int i=0;i<nbOfTuple1;i++)
11518             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11519           ret->copyStringInfoFrom(*a1);
11520           return ret.retn();
11521         }
11522       else
11523         {
11524           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11525           return 0;
11526         }
11527     }
11528   else if(nbOfTuple2==1)
11529     {
11530       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11531       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11532       ret->alloc(nbOfTuple1,nbOfComp1);
11533       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11534       int *pt=ret->getPointer();
11535       for(int i=0;i<nbOfTuple1;i++)
11536         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11537       ret->copyStringInfoFrom(*a1);
11538       return ret.retn();
11539     }
11540   else
11541     {
11542       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11543       return 0;
11544     }
11545 }
11546
11547 /*!
11548  * Modify \a this array so that each value becomes a modulus of division of this value by
11549  * a value of another DataArrayInt. There are 3 valid cases.
11550  * 1.  The arrays have same number of tuples and components. Then each value of
11551  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11552  *   _a_ [ i, j ] %= _other_ [ i, j ].
11553  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11554  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11555  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11556  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11557  *
11558  *  \warning No check of division by zero is performed!
11559  *  \param [in] other - a divisor array.
11560  *  \throw If \a other is NULL.
11561  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11562  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11563  *         \a other has number of both tuples and components not equal to 1.
11564  */
11565 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11566 {
11567   if(!other)
11568     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11569   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11570   checkAllocated(); other->checkAllocated();
11571   int nbOfTuple=getNumberOfTuples();
11572   int nbOfTuple2=other->getNumberOfTuples();
11573   int nbOfComp=getNumberOfComponents();
11574   int nbOfComp2=other->getNumberOfComponents();
11575   if(nbOfTuple==nbOfTuple2)
11576     {
11577       if(nbOfComp==nbOfComp2)
11578         {
11579           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11580         }
11581       else if(nbOfComp2==1)
11582         {
11583           if(nbOfComp2==nbOfComp)
11584             {
11585               int *ptr=getPointer();
11586               const int *ptrc=other->getConstPointer();
11587               for(int i=0;i<nbOfTuple;i++)
11588                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11589             }
11590           else
11591             throw INTERP_KERNEL::Exception(msg);
11592         }
11593       else
11594         throw INTERP_KERNEL::Exception(msg);
11595     }
11596   else if(nbOfTuple2==1)
11597     {
11598       int *ptr=getPointer();
11599       const int *ptrc=other->getConstPointer();
11600       for(int i=0;i<nbOfTuple;i++)
11601         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11602     }
11603   else
11604     throw INTERP_KERNEL::Exception(msg);
11605   declareAsNew();
11606 }
11607
11608 /*!
11609  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11610  * valid cases.
11611  *
11612  *  \param [in] a1 - an array to pow up.
11613  *  \param [in] a2 - another array to sum up.
11614  *  \return DataArrayInt * - the new instance of DataArrayInt.
11615  *          The caller is to delete this result array using decrRef() as it is no more
11616  *          needed.
11617  *  \throw If either \a a1 or \a a2 is NULL.
11618  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11619  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11620  *  \throw If there is a negative value in \a a2.
11621  */
11622 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11623 {
11624   if(!a1 || !a2)
11625     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11626   int nbOfTuple=a1->getNumberOfTuples();
11627   int nbOfTuple2=a2->getNumberOfTuples();
11628   int nbOfComp=a1->getNumberOfComponents();
11629   int nbOfComp2=a2->getNumberOfComponents();
11630   if(nbOfTuple!=nbOfTuple2)
11631     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11632   if(nbOfComp!=1 || nbOfComp2!=1)
11633     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11634   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11635   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11636   int *ptr=ret->getPointer();
11637   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11638     {
11639       if(*ptr2>=0)
11640         {
11641           int tmp=1;
11642           for(int j=0;j<*ptr2;j++)
11643             tmp*=*ptr1;
11644           *ptr=tmp;
11645         }
11646       else
11647         {
11648           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11649           throw INTERP_KERNEL::Exception(oss.str().c_str());
11650         }
11651     }
11652   return ret.retn();
11653 }
11654
11655 /*!
11656  * Apply pow on values of another DataArrayInt to values of \a this one.
11657  *
11658  *  \param [in] other - an array to pow to \a this one.
11659  *  \throw If \a other is NULL.
11660  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11661  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11662  *  \throw If there is a negative value in \a other.
11663  */
11664 void DataArrayInt::powEqual(const DataArrayInt *other)
11665 {
11666   if(!other)
11667     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11668   int nbOfTuple=getNumberOfTuples();
11669   int nbOfTuple2=other->getNumberOfTuples();
11670   int nbOfComp=getNumberOfComponents();
11671   int nbOfComp2=other->getNumberOfComponents();
11672   if(nbOfTuple!=nbOfTuple2)
11673     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11674   if(nbOfComp!=1 || nbOfComp2!=1)
11675     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11676   int *ptr=getPointer();
11677   const int *ptrc=other->begin();
11678   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11679     {
11680       if(*ptrc>=0)
11681         {
11682           int tmp=1;
11683           for(int j=0;j<*ptrc;j++)
11684             tmp*=*ptr;
11685           *ptr=tmp;
11686         }
11687       else
11688         {
11689           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11690           throw INTERP_KERNEL::Exception(oss.str().c_str());
11691         }
11692     }
11693   declareAsNew();
11694 }
11695
11696 /*!
11697  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11698  * This map, if applied to \a start array, would make it sorted. For example, if
11699  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11700  * [5,6,0,3,2,7,1,4].
11701  *  \param [in] start - pointer to the first element of the array for which the
11702  *         permutation map is computed.
11703  *  \param [in] end - pointer specifying the end of the array \a start, so that
11704  *         the last value of \a start is \a end[ -1 ].
11705  *  \return int * - the result permutation array that the caller is to delete as it is no
11706  *         more needed.
11707  *  \throw If there are equal values in the input array.
11708  */
11709 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11710 {
11711   std::size_t sz=std::distance(start,end);
11712   int *ret=(int *)malloc(sz*sizeof(int));
11713   int *work=new int[sz];
11714   std::copy(start,end,work);
11715   std::sort(work,work+sz);
11716   if(std::unique(work,work+sz)!=work+sz)
11717     {
11718       delete [] work;
11719       free(ret);
11720       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11721     }
11722   std::map<int,int> m;
11723   for(int *workPt=work;workPt!=work+sz;workPt++)
11724     m[*workPt]=(int)std::distance(work,workPt);
11725   int *iter2=ret;
11726   for(const int *iter=start;iter!=end;iter++,iter2++)
11727     *iter2=m[*iter];
11728   delete [] work;
11729   return ret;
11730 }
11731
11732 /*!
11733  * Returns a new DataArrayInt containing an arithmetic progression
11734  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11735  * function.
11736  *  \param [in] begin - the start value of the result sequence.
11737  *  \param [in] end - limiting value, so that every value of the result array is less than
11738  *              \a end.
11739  *  \param [in] step - specifies the increment or decrement.
11740  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11741  *          array using decrRef() as it is no more needed.
11742  *  \throw If \a step == 0.
11743  *  \throw If \a end < \a begin && \a step > 0.
11744  *  \throw If \a end > \a begin && \a step < 0.
11745  */
11746 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11747 {
11748   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11749   MCAuto<DataArrayInt> ret=DataArrayInt::New();
11750   ret->alloc(nbOfTuples,1);
11751   int *ptr=ret->getPointer();
11752   if(step>0)
11753     {
11754       for(int i=begin;i<end;i+=step,ptr++)
11755         *ptr=i;
11756     }
11757   else
11758     {
11759       for(int i=begin;i>end;i+=step,ptr++)
11760         *ptr=i;
11761     }
11762   return ret.retn();
11763 }
11764
11765 /*!
11766  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11767  * Server side.
11768  */
11769 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11770 {
11771   tinyInfo.resize(2);
11772   if(isAllocated())
11773     {
11774       tinyInfo[0]=getNumberOfTuples();
11775       tinyInfo[1]=getNumberOfComponents();
11776     }
11777   else
11778     {
11779       tinyInfo[0]=-1;
11780       tinyInfo[1]=-1;
11781     }
11782 }
11783
11784 /*!
11785  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11786  * Server side.
11787  */
11788 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11789 {
11790   if(isAllocated())
11791     {
11792       int nbOfCompo=getNumberOfComponents();
11793       tinyInfo.resize(nbOfCompo+1);
11794       tinyInfo[0]=getName();
11795       for(int i=0;i<nbOfCompo;i++)
11796         tinyInfo[i+1]=getInfoOnComponent(i);
11797     }
11798   else
11799     {
11800       tinyInfo.resize(1);
11801       tinyInfo[0]=getName();
11802     }
11803 }
11804
11805 /*!
11806  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11807  * This method returns if a feeding is needed.
11808  */
11809 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11810 {
11811   int nbOfTuple=tinyInfoI[0];
11812   int nbOfComp=tinyInfoI[1];
11813   if(nbOfTuple!=-1 || nbOfComp!=-1)
11814     {
11815       alloc(nbOfTuple,nbOfComp);
11816       return true;
11817     }
11818   return false;
11819 }
11820
11821 /*!
11822  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11823  * This method returns if a feeding is needed.
11824  */
11825 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11826 {
11827   setName(tinyInfoS[0]);
11828   if(isAllocated())
11829     {
11830       int nbOfCompo=tinyInfoI[1];
11831       for(int i=0;i<nbOfCompo;i++)
11832         setInfoOnComponent(i,tinyInfoS[i+1]);
11833     }
11834 }
11835
11836 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11837 {
11838   if(_da)
11839     {
11840       _da->incrRef();
11841       if(_da->isAllocated())
11842         {
11843           _nb_comp=da->getNumberOfComponents();
11844           _nb_tuple=da->getNumberOfTuples();
11845           _pt=da->getPointer();
11846         }
11847     }
11848 }
11849
11850 DataArrayIntIterator::~DataArrayIntIterator()
11851 {
11852   if(_da)
11853     _da->decrRef();
11854 }
11855
11856 DataArrayIntTuple *DataArrayIntIterator::nextt()
11857 {
11858   if(_tuple_id<_nb_tuple)
11859     {
11860       _tuple_id++;
11861       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11862       _pt+=_nb_comp;
11863       return ret;
11864     }
11865   else
11866     return 0;
11867 }
11868
11869 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11870 {
11871 }
11872
11873 std::string DataArrayIntTuple::repr() const
11874 {
11875   std::ostringstream oss; oss << "(";
11876   for(int i=0;i<_nb_of_compo-1;i++)
11877     oss << _pt[i] << ", ";
11878   oss << _pt[_nb_of_compo-1] << ")";
11879   return oss.str();
11880 }
11881
11882 int DataArrayIntTuple::intValue() const
11883 {
11884   if(_nb_of_compo==1)
11885     return *_pt;
11886   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11887 }
11888
11889 /*!
11890  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
11891  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
11892  * 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
11893  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11894  */
11895 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11896 {
11897   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11898     {
11899       DataArrayInt *ret=DataArrayInt::New();
11900       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11901       return ret;
11902     }
11903   else
11904     {
11905       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11906       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11907       throw INTERP_KERNEL::Exception(oss.str().c_str());
11908     }
11909 }