Salome HOME
Some useful tools for MEDCouplingMappedExtrudedMesh users that needs to store it...
[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
23 #include "BBTree.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
27
28 #include <set>
29 #include <cmath>
30 #include <limits>
31 #include <numeric>
32 #include <algorithm>
33 #include <functional>
34
35 typedef double (*MYFUNCPTR)(double);
36
37 using namespace MEDCoupling;
38
39 template class DataArrayTemplate<int>;
40 template class DataArrayTemplate<double>;
41
42 template<int SPACEDIM>
43 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
44 {
45   const double *coordsPtr=getConstPointer();
46   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
47   std::vector<bool> isDone(nbNodes);
48   for(int i=0;i<nbNodes;i++)
49     {
50       if(!isDone[i])
51         {
52           std::vector<int> intersectingElems;
53           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
54           if(intersectingElems.size()>1)
55             {
56               std::vector<int> commonNodes;
57               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
58                 if(*it!=i)
59                   if(*it>=limitNodeId)
60                     {
61                       commonNodes.push_back(*it);
62                       isDone[*it]=true;
63                     }
64               if(!commonNodes.empty())
65                 {
66                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
67                   c->pushBackSilent(i);
68                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
69                 }
70             }
71         }
72     }
73 }
74
75 template<int SPACEDIM>
76 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
77                                                 DataArrayInt *c, DataArrayInt *cI)
78 {
79   for(int i=0;i<nbOfTuples;i++)
80     {
81       std::vector<int> intersectingElems;
82       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
83       std::vector<int> commonNodes;
84       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
85         commonNodes.push_back(*it);
86       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
87       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
88     }
89 }
90
91 template<int SPACEDIM>
92 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
93 {
94   double distOpt(dist);
95   const double *p(pos);
96   int *r(res);
97   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
98     {
99       while(true)
100         {
101           int elem=-1;
102           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
103           if(ret!=std::numeric_limits<double>::max())
104             {
105               distOpt=std::max(ret,1e-4);
106               *r=elem;
107               break;
108             }
109           else
110             { distOpt=2*distOpt; continue; }
111         }
112     }
113 }
114
115 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
116 {
117   std::size_t sz1=_name.capacity();
118   std::size_t sz2=_info_on_compo.capacity();
119   std::size_t sz3=0;
120   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
121     sz3+=(*it).capacity();
122   return sz1+sz2+sz3;
123 }
124
125 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
126 {
127   return std::vector<const BigMemoryObject *>();
128 }
129
130 /*!
131  * Sets the attribute \a _name of \a this array.
132  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
133  *  \param [in] name - new array name
134  */
135 void DataArray::setName(const std::string& name)
136 {
137   _name=name;
138 }
139
140 /*!
141  * Copies textual data from an \a other DataArray. The copied data are
142  * - the name attribute,
143  * - the information of components.
144  *
145  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
146  *
147  *  \param [in] other - another instance of DataArray to copy the textual data from.
148  *  \throw If number of components of \a this array differs from that of the \a other.
149  */
150 void DataArray::copyStringInfoFrom(const DataArray& other)
151 {
152   if(_info_on_compo.size()!=other._info_on_compo.size())
153     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
154   _name=other._name;
155   _info_on_compo=other._info_on_compo;
156 }
157
158 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
159 {
160   int nbOfCompoOth=other.getNumberOfComponents();
161   std::size_t newNbOfCompo=compoIds.size();
162   for(std::size_t i=0;i<newNbOfCompo;i++)
163     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
164       {
165         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
166         throw INTERP_KERNEL::Exception(oss.str().c_str());
167       }
168   for(std::size_t i=0;i<newNbOfCompo;i++)
169     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
170 }
171
172 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
173 {
174   int nbOfCompo=getNumberOfComponents();
175   std::size_t partOfCompoToSet=compoIds.size();
176   if((int)partOfCompoToSet!=other.getNumberOfComponents())
177     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
178   for(std::size_t i=0;i<partOfCompoToSet;i++)
179     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
180       {
181         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
182         throw INTERP_KERNEL::Exception(oss.str().c_str());
183       }
184   for(std::size_t i=0;i<partOfCompoToSet;i++)
185     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
186 }
187
188 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
189 {
190   std::ostringstream oss;
191   if(_name!=other._name)
192     {
193       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
194       reason=oss.str();
195       return false;
196     }
197   if(_info_on_compo!=other._info_on_compo)
198     {
199       oss << "Components DataArray mismatch : \nThis components=";
200       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
201         oss << "\"" << *it << "\",";
202       oss << "\nOther components=";
203       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
204         oss << "\"" << *it << "\",";
205       reason=oss.str();
206       return false;
207     }
208   return true;
209 }
210
211 /*!
212  * Compares textual information of \a this DataArray with that of an \a other one.
213  * The compared data are
214  * - the name attribute,
215  * - the information of components.
216  *
217  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
218  *  \param [in] other - another instance of DataArray to compare the textual data of.
219  *  \return bool - \a true if the textual information is same, \a false else.
220  */
221 bool DataArray::areInfoEquals(const DataArray& other) const
222 {
223   std::string tmp;
224   return areInfoEqualsIfNotWhy(other,tmp);
225 }
226
227 void DataArray::reprWithoutNameStream(std::ostream& stream) const
228 {
229   stream << "Number of components : "<< getNumberOfComponents() << "\n";
230   stream << "Info of these components : ";
231   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
232     stream << "\"" << *iter << "\"   ";
233   stream << "\n";
234 }
235
236 std::string DataArray::cppRepr(const std::string& varName) const
237 {
238   std::ostringstream ret;
239   reprCppStream(varName,ret);
240   return ret.str();
241 }
242
243 /*!
244  * Sets information on all components. To know more on format of this information
245  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
246  *  \param [in] info - a vector of strings.
247  *  \throw If size of \a info differs from the number of components of \a this.
248  */
249 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
250 {
251   if(getNumberOfComponents()!=(int)info.size())
252     {
253       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
254       throw INTERP_KERNEL::Exception(oss.str().c_str());
255     }
256   _info_on_compo=info;
257 }
258
259 /*!
260  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
261  * type of \a this and \a aBase.
262  *
263  * \throw If \a aBase and \a this do not have the same type.
264  *
265  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
266  */
267 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
268 {
269   if(!aBase)
270     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
271   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
272   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
273   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
274   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
275   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
276   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
277   if(this1 && a1)
278     {
279       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
280       return ;
281     }
282   if(this2 && a2)
283     {
284       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
285       return ;
286     }
287   if(this3 && a3)
288     {
289       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
290       return ;
291     }
292   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
293 }
294
295 std::vector<std::string> DataArray::getVarsOnComponent() const
296 {
297   int nbOfCompo=(int)_info_on_compo.size();
298   std::vector<std::string> ret(nbOfCompo);
299   for(int i=0;i<nbOfCompo;i++)
300     ret[i]=getVarOnComponent(i);
301   return ret;
302 }
303
304 std::vector<std::string> DataArray::getUnitsOnComponent() const
305 {
306   int nbOfCompo=(int)_info_on_compo.size();
307   std::vector<std::string> ret(nbOfCompo);
308   for(int i=0;i<nbOfCompo;i++)
309     ret[i]=getUnitOnComponent(i);
310   return ret;
311 }
312
313 /*!
314  * Returns information on a component specified by an index.
315  * To know more on format of this information
316  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
317  *  \param [in] i - the index (zero based) of the component of interest.
318  *  \return std::string - a string containing the information on \a i-th component.
319  *  \throw If \a i is not a valid component index.
320  */
321 std::string DataArray::getInfoOnComponent(int i) const
322 {
323   if(i<(int)_info_on_compo.size() && i>=0)
324     return _info_on_compo[i];
325   else
326     {
327       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();
328       throw INTERP_KERNEL::Exception(oss.str().c_str());
329     }
330 }
331
332 /*!
333  * Returns the var part of the full information of the \a i-th component.
334  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
335  * \c getVarOnComponent(0) returns "SIGXY".
336  * If a unit part of information is not detected by presence of
337  * two square brackets, then the full information is returned.
338  * To read more about the component information format, see
339  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
340  *  \param [in] i - the index (zero based) of the component of interest.
341  *  \return std::string - a string containing the var information, or the full info.
342  *  \throw If \a i is not a valid component index.
343  */
344 std::string DataArray::getVarOnComponent(int i) const
345 {
346   if(i<(int)_info_on_compo.size() && i>=0)
347     {
348       return GetVarNameFromInfo(_info_on_compo[i]);
349     }
350   else
351     {
352       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();
353       throw INTERP_KERNEL::Exception(oss.str().c_str());
354     }
355 }
356
357 /*!
358  * Returns the unit part of the full information of the \a i-th component.
359  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
360  * \c getUnitOnComponent(0) returns " N/m^2".
361  * If a unit part of information is not detected by presence of
362  * two square brackets, then an empty string is returned.
363  * To read more about the component information format, see
364  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
365  *  \param [in] i - the index (zero based) of the component of interest.
366  *  \return std::string - a string containing the unit information, if any, or "".
367  *  \throw If \a i is not a valid component index.
368  */
369 std::string DataArray::getUnitOnComponent(int i) const
370 {
371   if(i<(int)_info_on_compo.size() && i>=0)
372     {
373       return GetUnitFromInfo(_info_on_compo[i]);
374     }
375   else
376     {
377       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();
378       throw INTERP_KERNEL::Exception(oss.str().c_str());
379     }
380 }
381
382 /*!
383  * Returns the var part of the full component information.
384  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
385  * If a unit part of information is not detected by presence of
386  * two square brackets, then the whole \a info is returned.
387  * To read more about the component information format, see
388  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
389  *  \param [in] info - the full component information.
390  *  \return std::string - a string containing only var information, or the \a info.
391  */
392 std::string DataArray::GetVarNameFromInfo(const std::string& info)
393 {
394   std::size_t p1=info.find_last_of('[');
395   std::size_t p2=info.find_last_of(']');
396   if(p1==std::string::npos || p2==std::string::npos)
397     return info;
398   if(p1>p2)
399     return info;
400   if(p1==0)
401     return std::string();
402   std::size_t p3=info.find_last_not_of(' ',p1-1);
403   return info.substr(0,p3+1);
404 }
405
406 /*!
407  * Returns the unit part of the full component information.
408  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
409  * If a unit part of information is not detected by presence of
410  * two square brackets, then an empty string is returned.
411  * To read more about the component information format, see
412  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
413  *  \param [in] info - the full component information.
414  *  \return std::string - a string containing only unit information, if any, or "".
415  */
416 std::string DataArray::GetUnitFromInfo(const std::string& info)
417 {
418   std::size_t p1=info.find_last_of('[');
419   std::size_t p2=info.find_last_of(']');
420   if(p1==std::string::npos || p2==std::string::npos)
421     return std::string();
422   if(p1>p2)
423     return std::string();
424   return info.substr(p1+1,p2-p1-1);
425 }
426
427 /*!
428  * This method put in info format the result of the merge of \a var and \a unit.
429  * The standard format for that is "var [unit]".
430  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
431  */
432 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
433 {
434   std::ostringstream oss;
435   oss << var << " [" << unit << "]";
436   return oss.str();
437 }
438
439 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
440 {
441   switch(at)
442     {
443     case AX_CART:
444       return std::string("AX_CART");
445     case AX_CYL:
446       return std::string("AX_CYL");
447     case AX_SPHER:
448       return std::string("AX_SPHER");
449     default:
450       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
451     }
452 }
453
454 /*!
455  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
456  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
457  * the number of component in the result array is same as that of each of given arrays.
458  * Info on components is copied from the first of the given arrays. Number of components
459  * in the given arrays must be  the same.
460  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
461  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
462  *          The caller is to delete this result array using decrRef() as it is no more
463  *          needed.
464  *  \throw If all arrays within \a arrs are NULL.
465  *  \throw If all not null arrays in \a arrs have not the same type.
466  *  \throw If getNumberOfComponents() of arrays within \a arrs.
467  */
468 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
469 {
470   std::vector<const DataArray *> arr2;
471   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
472     if(*it)
473       arr2.push_back(*it);
474   if(arr2.empty())
475     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
476   std::vector<const DataArrayDouble *> arrd;
477   std::vector<const DataArrayInt *> arri;
478   std::vector<const DataArrayChar *> arrc;
479   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
480     {
481       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
482       if(a)
483         { arrd.push_back(a); continue; }
484       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
485       if(b)
486         { arri.push_back(b); continue; }
487       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
488       if(c)
489         { arrc.push_back(c); continue; }
490       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
491     }
492   if(arr2.size()==arrd.size())
493     return DataArrayDouble::Aggregate(arrd);
494   if(arr2.size()==arri.size())
495     return DataArrayInt::Aggregate(arri);
496   if(arr2.size()==arrc.size())
497     return DataArrayChar::Aggregate(arrc);
498   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
499 }
500
501 /*!
502  * Sets information on a component specified by an index.
503  * To know more on format of this information
504  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
505  *  \warning Don't pass NULL as \a info!
506  *  \param [in] i - the index (zero based) of the component of interest.
507  *  \param [in] info - the string containing the information.
508  *  \throw If \a i is not a valid component index.
509  */
510 void DataArray::setInfoOnComponent(int i, const std::string& info)
511 {
512   if(i<(int)_info_on_compo.size() && i>=0)
513     _info_on_compo[i]=info;
514   else
515     {
516       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();
517       throw INTERP_KERNEL::Exception(oss.str().c_str());
518     }
519 }
520
521 /*!
522  * Sets information on all components. This method can change number of components
523  * at certain conditions; if the conditions are not respected, an exception is thrown.
524  * The number of components can be changed in \a this only if \a this is not allocated.
525  * The condition of number of components must not be changed.
526  *
527  * To know more on format of the component information see
528  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
529  *  \param [in] info - a vector of component infos.
530  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
531  */
532 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
533 {
534   if(getNumberOfComponents()!=(int)info.size())
535     {
536       if(!isAllocated())
537         _info_on_compo=info;
538       else
539         {
540           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 !";
541           throw INTERP_KERNEL::Exception(oss.str().c_str());
542         }
543     }
544   else
545     _info_on_compo=info;
546 }
547
548 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
549 {
550   if(getNumberOfTuples()!=nbOfTuples)
551     {
552       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
553       throw INTERP_KERNEL::Exception(oss.str().c_str());
554     }
555 }
556
557 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
558 {
559   if(getNumberOfComponents()!=nbOfCompo)
560     {
561       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
562       throw INTERP_KERNEL::Exception(oss.str().c_str());
563     }
564 }
565
566 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
567 {
568   if(getNbOfElems()!=nbOfElems)
569     {
570       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
571       throw INTERP_KERNEL::Exception(oss.str().c_str());
572     }
573 }
574
575 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
576 {
577   if(getNumberOfTuples()!=other.getNumberOfTuples())
578     {
579       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582   if(getNumberOfComponents()!=other.getNumberOfComponents())
583     {
584       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
585       throw INTERP_KERNEL::Exception(oss.str().c_str());
586     }
587 }
588
589 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
590 {
591   checkNbOfTuples(nbOfTuples,msg);
592   checkNbOfComps(nbOfCompo,msg);
593 }
594
595 /*!
596  * Simply this method checks that \b value is in [0,\b ref).
597  */
598 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
599 {
600   if(value<0 || value>=ref)
601     {
602       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
603       throw INTERP_KERNEL::Exception(oss.str().c_str());
604     }
605 }
606
607 /*!
608  * This method checks that [\b start, \b end) is compliant with ref length \b value.
609  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
610  */
611 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
612 {
613   if(start<0 || start>=value)
614     {
615       if(value!=start || end!=start)
616         {
617           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
618           throw INTERP_KERNEL::Exception(oss.str().c_str());
619         }
620     }
621   if(end<0 || end>value)
622     {
623       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
624       throw INTERP_KERNEL::Exception(oss.str().c_str());
625     }
626 }
627
628 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
629 {
630   if(value<0 || value>ref)
631     {
632       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
633       throw INTERP_KERNEL::Exception(oss.str().c_str());
634     }
635 }
636
637 /*!
638  * 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, 
639  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
640  *
641  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
642  *
643  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
644  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
645  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
646  * \param [in] sliceId - the slice id considered
647  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
648  * \param [out] startSlice - the start of the slice considered
649  * \param [out] stopSlice - the stop of the slice consided
650  * 
651  * \throw If \a step == 0
652  * \throw If \a nbOfSlices not > 0
653  * \throw If \a sliceId not in [0,nbOfSlices)
654  */
655 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
656 {
657   if(nbOfSlices<=0)
658     {
659       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
660       throw INTERP_KERNEL::Exception(oss.str().c_str());
661     }
662   if(sliceId<0 || sliceId>=nbOfSlices)
663     {
664       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
665       throw INTERP_KERNEL::Exception(oss.str().c_str());
666     }
667   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
668   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
669   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
670   if(sliceId<nbOfSlices-1)
671     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
672   else
673     stopSlice=stop;
674 }
675
676 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
677 {
678   if(end<begin)
679     {
680       std::ostringstream oss; oss << msg << " : end before begin !";
681       throw INTERP_KERNEL::Exception(oss.str().c_str());
682     }
683   if(end==begin)
684     return 0;
685   if(step<=0)
686     {
687       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   return (end-1-begin)/step+1;
691 }
692
693 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
694 {
695   if(step==0)
696     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
697   if(end<begin && step>0)
698     {
699       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
700       throw INTERP_KERNEL::Exception(oss.str().c_str());
701     }
702   if(begin<end && step<0)
703     {
704       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
705       throw INTERP_KERNEL::Exception(oss.str().c_str());
706     }
707   if(begin!=end)
708     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
709   else
710     return 0;
711 }
712
713 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
714 {
715   if(step!=0)
716     {
717       if(step>0)
718         {
719           if(begin<=value && value<end)
720             {
721               if((value-begin)%step==0)
722                 return (value-begin)/step;
723               else
724                 return -1;
725             }
726           else
727             return -1;
728         }
729       else
730         {
731           if(begin>=value && value>end)
732             {
733               if((begin-value)%(-step)==0)
734                 return (begin-value)/(-step);
735               else
736                 return -1;
737             }
738           else
739             return -1;
740         }
741     }
742   else
743     return -1;
744 }
745
746 /*!
747  * Returns a new instance of DataArrayDouble. The caller is to delete this array
748  * using decrRef() as it is no more needed. 
749  */
750 DataArrayDouble *DataArrayDouble::New()
751 {
752   return new DataArrayDouble;
753 }
754
755 /*!
756  * Returns the only one value in \a this, if and only if number of elements
757  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
758  *  \return double - the sole value stored in \a this array.
759  *  \throw If at least one of conditions stated above is not fulfilled.
760  */
761 double DataArrayDouble::doubleValue() const
762 {
763   if(isAllocated())
764     {
765       if(getNbOfElems()==1)
766         {
767           return *getConstPointer();
768         }
769       else
770         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
771     }
772   else
773     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
774 }
775
776 /*!
777  * Returns a full copy of \a this. For more info on copying data arrays see
778  * \ref MEDCouplingArrayBasicsCopyDeep.
779  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
780  *          delete this array using decrRef() as it is no more needed. 
781  */
782 DataArrayDouble *DataArrayDouble::deepCopy() const
783 {
784   return new DataArrayDouble(*this);
785 }
786
787 /*!
788  * Returns either a \a deep or \a shallow copy of this array. For more info see
789  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
790  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
791  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
792  *          == \a true) or \a this instance (if \a dCpy == \a false).
793  */
794 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
795 {
796   if(dCpy)
797     return deepCopy();
798   else
799     {
800       incrRef();
801       return const_cast<DataArrayDouble *>(this);
802     }
803 }
804
805 /*!
806  * Assign zero to all values in \a this array. To know more on filling arrays see
807  * \ref MEDCouplingArrayFill.
808  * \throw If \a this is not allocated.
809  */
810 void DataArrayDouble::fillWithZero()
811 {
812   fillWithValue(0.);
813 }
814
815 /*!
816  * Set all values in \a this array so that the i-th element equals to \a init + i
817  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
818  *  \param [in] init - value to assign to the first element of array.
819  *  \throw If \a this->getNumberOfComponents() != 1
820  *  \throw If \a this is not allocated.
821  */
822 void DataArrayDouble::iota(double init)
823 {
824   checkAllocated();
825   if(getNumberOfComponents()!=1)
826     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
827   double *ptr=getPointer();
828   int ntuples=getNumberOfTuples();
829   for(int i=0;i<ntuples;i++)
830     ptr[i]=init+double(i);
831   declareAsNew();
832 }
833
834 /*!
835  * Checks if all values in \a this array are equal to \a val at precision \a eps.
836  *  \param [in] val - value to check equality of array values to.
837  *  \param [in] eps - precision to check the equality.
838  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
839  *                 \a false else.
840  *  \throw If \a this->getNumberOfComponents() != 1
841  *  \throw If \a this is not allocated.
842  */
843 bool DataArrayDouble::isUniform(double val, double eps) const
844 {
845   checkAllocated();
846   if(getNumberOfComponents()!=1)
847     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
848   int nbOfTuples=getNumberOfTuples();
849   const double *w=getConstPointer();
850   const double *end2=w+nbOfTuples;
851   const double vmin=val-eps;
852   const double vmax=val+eps;
853   for(;w!=end2;w++)
854     if(*w<vmin || *w>vmax)
855       return false;
856   return true;
857 }
858
859 /*!
860  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
861  * with at least absolute difference value of |\a eps| at each step.
862  * If not an exception is thrown.
863  *  \param [in] increasing - if \a true, the array values should be increasing.
864  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
865  *                    the values are considered different.
866  *  \throw If sequence of values is not strictly monotonic in agreement with \a
867  *         increasing arg.
868  *  \throw If \a this->getNumberOfComponents() != 1.
869  *  \throw If \a this is not allocated.
870  */
871 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
872 {
873   if(!isMonotonic(increasing,eps))
874     {
875       if (increasing)
876         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
877       else
878         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
879     }
880 }
881
882 /*!
883  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
884  * with at least absolute difference value of |\a eps| at each step.
885  *  \param [in] increasing - if \a true, array values should be increasing.
886  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
887  *                    the values are considered different.
888  *  \return bool - \a true if values change in accordance with \a increasing arg.
889  *  \throw If \a this->getNumberOfComponents() != 1.
890  *  \throw If \a this is not allocated.
891  */
892 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
893 {
894   checkAllocated();
895   if(getNumberOfComponents()!=1)
896     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
897   int nbOfElements=getNumberOfTuples();
898   const double *ptr=getConstPointer();
899   if(nbOfElements==0)
900     return true;
901   double ref=ptr[0];
902   double absEps=fabs(eps);
903   if(increasing)
904     {
905       for(int i=1;i<nbOfElements;i++)
906         {
907           if(ptr[i]<(ref+absEps))
908             return false;
909           ref=ptr[i];
910         }
911       return true;
912     }
913   else
914     {
915       for(int i=1;i<nbOfElements;i++)
916         {
917           if(ptr[i]>(ref-absEps))
918             return false;
919           ref=ptr[i];
920         }
921       return true;
922     }
923 }
924
925 /*!
926  * Returns a textual and human readable representation of \a this instance of
927  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
928  * \return std::string - text describing \a this DataArrayDouble.
929  *
930  * \sa reprNotTooLong, reprZip
931  */
932 std::string DataArrayDouble::repr() const
933 {
934   std::ostringstream ret;
935   reprStream(ret);
936   return ret.str();
937 }
938
939 std::string DataArrayDouble::reprZip() const
940 {
941   std::ostringstream ret;
942   reprZipStream(ret);
943   return ret.str();
944 }
945
946 /*!
947  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
948  * printed out to avoid to consume too much space in interpretor.
949  * \sa repr
950  */
951 std::string DataArrayDouble::reprNotTooLong() const
952 {
953   std::ostringstream ret;
954   reprNotTooLongStream(ret);
955   return ret.str();
956 }
957
958 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
959 {
960   static const char SPACE[4]={' ',' ',' ',' '};
961   checkAllocated();
962   std::string idt(indent,' ');
963   ofs.precision(17);
964   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
965   //
966   bool areAllEmpty(true);
967   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
968     if(!(*it).empty())
969       areAllEmpty=false;
970   if(!areAllEmpty)
971     for(std::size_t i=0;i<_info_on_compo.size();i++)
972       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
973   //
974   if(byteArr)
975     {
976       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
977       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
978       float *pt(tmp);
979       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
980       for(const double *src=begin();src!=end();src++,pt++)
981         *pt=float(*src);
982       const char *data(reinterpret_cast<const char *>((float *)tmp));
983       std::size_t sz(getNbOfElems()*sizeof(float));
984       byteArr->insertAtTheEnd(data,data+sz);
985       byteArr->insertAtTheEnd(SPACE,SPACE+4);
986     }
987   else
988     {
989       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
990       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
991     }
992   ofs << std::endl << idt << "</DataArray>\n";
993 }
994
995 void DataArrayDouble::reprStream(std::ostream& stream) const
996 {
997   stream << "Name of double array : \"" << _name << "\"\n";
998   reprWithoutNameStream(stream);
999 }
1000
1001 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1002 {
1003   stream << "Name of double array : \"" << _name << "\"\n";
1004   reprZipWithoutNameStream(stream);
1005 }
1006
1007 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1008 {
1009   stream << "Name of double array : \"" << _name << "\"\n";
1010   reprNotTooLongWithoutNameStream(stream);
1011 }
1012
1013 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1014 {
1015   DataArray::reprWithoutNameStream(stream);
1016   stream.precision(17);
1017   _mem.repr(getNumberOfComponents(),stream);
1018 }
1019
1020 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1021 {
1022   DataArray::reprWithoutNameStream(stream);
1023   stream.precision(17);
1024   _mem.reprZip(getNumberOfComponents(),stream);
1025 }
1026
1027 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1028 {
1029   DataArray::reprWithoutNameStream(stream);
1030   stream.precision(17);
1031   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1032 }
1033
1034 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1035 {
1036   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1037   const double *data=getConstPointer();
1038   stream.precision(17);
1039   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1040   if(nbTuples*nbComp>=1)
1041     {
1042       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1043       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1044       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1045       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1046     }
1047   else
1048     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1049   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1050 }
1051
1052 /*!
1053  * Method that gives a quick overvien of \a this for python.
1054  */
1055 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1056 {
1057   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1058   stream << "DataArrayDouble C++ instance at " << this << ". ";
1059   if(isAllocated())
1060     {
1061       int nbOfCompo=(int)_info_on_compo.size();
1062       if(nbOfCompo>=1)
1063         {
1064           int nbOfTuples=getNumberOfTuples();
1065           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1066           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1067         }
1068       else
1069         stream << "Number of components : 0.";
1070     }
1071   else
1072     stream << "*** No data allocated ****";
1073 }
1074
1075 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1076 {
1077   const double *data=begin();
1078   int nbOfTuples=getNumberOfTuples();
1079   int nbOfCompo=(int)_info_on_compo.size();
1080   std::ostringstream oss2; oss2 << "[";
1081   oss2.precision(17);
1082   std::string oss2Str(oss2.str());
1083   bool isFinished=true;
1084   for(int i=0;i<nbOfTuples && isFinished;i++)
1085     {
1086       if(nbOfCompo>1)
1087         {
1088           oss2 << "(";
1089           for(int j=0;j<nbOfCompo;j++,data++)
1090             {
1091               oss2 << *data;
1092               if(j!=nbOfCompo-1) oss2 << ", ";
1093             }
1094           oss2 << ")";
1095         }
1096       else
1097         oss2 << *data++;
1098       if(i!=nbOfTuples-1) oss2 << ", ";
1099       std::string oss3Str(oss2.str());
1100       if(oss3Str.length()<maxNbOfByteInRepr)
1101         oss2Str=oss3Str;
1102       else
1103         isFinished=false;
1104     }
1105   stream << oss2Str;
1106   if(!isFinished)
1107     stream << "... ";
1108   stream << "]";
1109 }
1110
1111 /*!
1112  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1113  * mismatch is given.
1114  * 
1115  * \param [in] other the instance to be compared with \a this
1116  * \param [in] prec the precision to compare numeric data of the arrays.
1117  * \param [out] reason In case of inequality returns the reason.
1118  * \sa DataArrayDouble::isEqual
1119  */
1120 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1121 {
1122   if(!areInfoEqualsIfNotWhy(other,reason))
1123     return false;
1124   return _mem.isEqual(other._mem,prec,reason);
1125 }
1126
1127 /*!
1128  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1129  * \ref MEDCouplingArrayBasicsCompare.
1130  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1131  *  \param [in] prec - precision value to compare numeric data of the arrays.
1132  *  \return bool - \a true if the two arrays are equal, \a false else.
1133  */
1134 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1135 {
1136   std::string tmp;
1137   return isEqualIfNotWhy(other,prec,tmp);
1138 }
1139
1140 /*!
1141  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1142  * \ref MEDCouplingArrayBasicsCompare.
1143  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1144  *  \param [in] prec - precision value to compare numeric data of the arrays.
1145  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1146  */
1147 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1148 {
1149   std::string tmp;
1150   return _mem.isEqual(other._mem,prec,tmp);
1151 }
1152
1153 /*!
1154  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1155  * array to the new one.
1156  *  \return DataArrayInt * - the new instance of DataArrayInt.
1157  */
1158 DataArrayInt *DataArrayDouble::convertToIntArr() const
1159 {
1160   DataArrayInt *ret=DataArrayInt::New();
1161   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1162   int *dest=ret->getPointer();
1163   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1164   for(const double *src=begin();src!=end();src++,dest++)
1165     *dest=(int)*src;
1166   ret->copyStringInfoFrom(*this);
1167   return ret;
1168 }
1169
1170 /*!
1171  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1172  * arranged in memory. If \a this array holds 2 components of 3 values:
1173  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1174  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1175  *  \warning Do not confuse this method with transpose()!
1176  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1177  *          is to delete using decrRef() as it is no more needed.
1178  *  \throw If \a this is not allocated.
1179  */
1180 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1181 {
1182   if(_mem.isNull())
1183     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1184   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1185   DataArrayDouble *ret=DataArrayDouble::New();
1186   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1187   return ret;
1188 }
1189
1190 /*!
1191  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1192  * arranged in memory. If \a this array holds 2 components of 3 values:
1193  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1194  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1195  *  \warning Do not confuse this method with transpose()!
1196  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1197  *          is to delete using decrRef() as it is no more needed.
1198  *  \throw If \a this is not allocated.
1199  */
1200 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1201 {
1202   if(_mem.isNull())
1203     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1204   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1205   DataArrayDouble *ret=DataArrayDouble::New();
1206   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1207   return ret;
1208 }
1209
1210 /*!
1211  * Appends components of another array to components of \a this one, tuple by tuple.
1212  * So that the number of tuples of \a this array remains the same and the number of 
1213  * components increases.
1214  *  \param [in] other - the DataArrayDouble to append to \a this one.
1215  *  \throw If \a this is not allocated.
1216  *  \throw If \a this and \a other arrays have different number of tuples.
1217  *
1218  *  \if ENABLE_EXAMPLES
1219  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1220  *
1221  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1222  *  \endif
1223  */
1224 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1225 {
1226   checkAllocated();
1227   other->checkAllocated();
1228   int nbOfTuples=getNumberOfTuples();
1229   if(nbOfTuples!=other->getNumberOfTuples())
1230     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1231   int nbOfComp1=getNumberOfComponents();
1232   int nbOfComp2=other->getNumberOfComponents();
1233   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1234   double *w=newArr;
1235   const double *inp1=getConstPointer();
1236   const double *inp2=other->getConstPointer();
1237   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1238     {
1239       w=std::copy(inp1,inp1+nbOfComp1,w);
1240       w=std::copy(inp2,inp2+nbOfComp2,w);
1241     }
1242   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1243   std::vector<int> compIds(nbOfComp2);
1244   for(int i=0;i<nbOfComp2;i++)
1245     compIds[i]=nbOfComp1+i;
1246   copyPartOfStringInfoFrom2(compIds,*other);
1247 }
1248
1249 /*!
1250  * This method checks that all tuples in \a other are in \a this.
1251  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1252  * 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.
1253  *
1254  * \param [in] other - the array having the same number of components than \a this.
1255  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1256  * \sa DataArrayDouble::findCommonTuples
1257  */
1258 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1259 {
1260   if(!other)
1261     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1262   checkAllocated(); other->checkAllocated();
1263   if(getNumberOfComponents()!=other->getNumberOfComponents())
1264     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1265   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1266   DataArrayInt *c=0,*ci=0;
1267   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1268   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1269   int newNbOfTuples=-1;
1270   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1271   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1272   tupleIds=ret1.retn();
1273   return newNbOfTuples==getNumberOfTuples();
1274 }
1275
1276 /*!
1277  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1278  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1279  * distance separating two points is computed with the infinite norm.
1280  *
1281  * Indices of coincident tuples are stored in output arrays.
1282  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1283  *
1284  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1285  * MEDCouplingUMesh::mergeNodes().
1286  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1287  *              considered not coincident.
1288  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1289  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1290  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1291  *               \a comm->getNumberOfComponents() == 1. 
1292  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1293  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1294  *               groups of (indices of) coincident tuples. Its every value is a tuple
1295  *               index where a next group of tuples begins. For example the second
1296  *               group of tuples in \a comm is described by following range of indices:
1297  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1298  *               gives the number of groups of coincident tuples.
1299  *  \throw If \a this is not allocated.
1300  *  \throw If the number of components is not in [1,2,3,4].
1301  *
1302  *  \if ENABLE_EXAMPLES
1303  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1304  *
1305  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1306  *  \endif
1307  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1308  */
1309 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1310 {
1311   checkAllocated();
1312   int nbOfCompo=getNumberOfComponents();
1313   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1314     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1315
1316   int nbOfTuples=getNumberOfTuples();
1317   //
1318   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1319   switch(nbOfCompo)
1320   {
1321     case 4:
1322       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1323       break;
1324     case 3:
1325       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1326       break;
1327     case 2:
1328       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1329       break;
1330     case 1:
1331       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1332       break;
1333     default:
1334       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1335   }
1336   comm=c.retn();
1337   commIndex=cI.retn();
1338 }
1339
1340 /*!
1341  * 
1342  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1343  *             \a nbTimes  should be at least equal to 1.
1344  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1345  * \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.
1346  */
1347 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1348 {
1349   checkAllocated();
1350   if(getNumberOfComponents()!=1)
1351     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1352   if(nbTimes<1)
1353     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1354   int nbTuples=getNumberOfTuples();
1355   const double *inPtr=getConstPointer();
1356   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1357   double *retPtr=ret->getPointer();
1358   for(int i=0;i<nbTuples;i++,inPtr++)
1359     {
1360       double val=*inPtr;
1361       for(int j=0;j<nbTimes;j++,retPtr++)
1362         *retPtr=val;
1363     }
1364   ret->copyStringInfoFrom(*this);
1365   return ret.retn();
1366 }
1367
1368 /*!
1369  * This methods returns the minimal distance between the two set of points \a this and \a other.
1370  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1371  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1372  *
1373  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1374  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1375  * \return the minimal distance between the two set of points \a this and \a other.
1376  * \sa DataArrayDouble::findClosestTupleId
1377  */
1378 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1379 {
1380   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1381   int nbOfCompo(getNumberOfComponents());
1382   int otherNbTuples(other->getNumberOfTuples());
1383   const double *thisPt(begin()),*otherPt(other->begin());
1384   const int *part1Pt(part1->begin());
1385   double ret=std::numeric_limits<double>::max();
1386   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1387     {
1388       double tmp(0.);
1389       for(int j=0;j<nbOfCompo;j++)
1390         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1391       if(tmp<ret)
1392         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1393     }
1394   return sqrt(ret);
1395 }
1396
1397 /*!
1398  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1399  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1400  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1401  *
1402  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1403  * \sa DataArrayDouble::minimalDistanceTo
1404  */
1405 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1406 {
1407   if(!other)
1408     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1409   checkAllocated(); other->checkAllocated();
1410   int nbOfCompo=getNumberOfComponents();
1411   if(nbOfCompo!=other->getNumberOfComponents())
1412     {
1413       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1414       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1415       throw INTERP_KERNEL::Exception(oss.str().c_str());
1416     }
1417   int nbOfTuples=other->getNumberOfTuples();
1418   int thisNbOfTuples=getNumberOfTuples();
1419   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1420   double bounds[6];
1421   getMinMaxPerComponent(bounds);
1422   switch(nbOfCompo)
1423   {
1424     case 3:
1425       {
1426         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1427         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1428         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1429         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1430         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1431         break;
1432       }
1433     case 2:
1434       {
1435         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1436         double delta=std::max(xDelta,yDelta);
1437         double characSize=sqrt(delta/(double)thisNbOfTuples);
1438         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1439         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1440         break;
1441       }
1442     case 1:
1443       {
1444         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1445         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1446         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1447         break;
1448       }
1449     default:
1450       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1451   }
1452   return ret.retn();
1453 }
1454
1455 /*!
1456  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1457  * 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
1458  * how many bounding boxes in \a otherBBoxFrmt.
1459  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1460  *
1461  * \param [in] otherBBoxFrmt - It is an array .
1462  * \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.
1463  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1464  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1465  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1466  */
1467 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1468 {
1469   if(!otherBBoxFrmt)
1470     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1471   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1472     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1473   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1474   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1475     {
1476       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1477       throw INTERP_KERNEL::Exception(oss.str().c_str());
1478     }
1479   if(nbOfComp%2!=0)
1480     {
1481       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1482       throw INTERP_KERNEL::Exception(oss.str().c_str());
1483     }
1484   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1485   const double *thisBBPtr(begin());
1486   int *retPtr(ret->getPointer());
1487   switch(nbOfComp/2)
1488   {
1489     case 3:
1490       {
1491         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1492         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1493           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1494         break;
1495       }
1496     case 2:
1497       {
1498         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1499         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1500           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1501         break;
1502       }
1503     case 1:
1504       {
1505         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1506         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1507           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1508         break;
1509       }
1510     default:
1511       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1512   }
1513
1514   return ret.retn();
1515 }
1516
1517 /*!
1518  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1519  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1520  * space. The distance between tuples is computed using norm2. If several tuples are
1521  * not far each from other than \a prec, only one of them remains in the result
1522  * array. The order of tuples in the result array is same as in \a this one except
1523  * that coincident tuples are excluded.
1524  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1525  *              considered not coincident.
1526  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1527  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1528  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1529  *          is to delete using decrRef() as it is no more needed.
1530  *  \throw If \a this is not allocated.
1531  *  \throw If the number of components is not in [1,2,3,4].
1532  *
1533  *  \if ENABLE_EXAMPLES
1534  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1535  *  \endif
1536  */
1537 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1538 {
1539   checkAllocated();
1540   DataArrayInt *c0=0,*cI0=0;
1541   findCommonTuples(prec,limitTupleId,c0,cI0);
1542   MCAuto<DataArrayInt> c(c0),cI(cI0);
1543   int newNbOfTuples=-1;
1544   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1545   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1546 }
1547
1548 /*!
1549  * Copy all components in a specified order from another DataArrayDouble.
1550  * Both numerical and textual data is copied. The number of tuples in \a this and
1551  * the other array can be different.
1552  *  \param [in] a - the array to copy data from.
1553  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1554  *              to be copied.
1555  *  \throw If \a a is NULL.
1556  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1557  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1558  *
1559  *  \if ENABLE_EXAMPLES
1560  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1561  *  \endif
1562  */
1563 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1564 {
1565   if(!a)
1566     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1567   checkAllocated();
1568   copyPartOfStringInfoFrom2(compoIds,*a);
1569   std::size_t partOfCompoSz=compoIds.size();
1570   int nbOfCompo=getNumberOfComponents();
1571   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1572   const double *ac=a->getConstPointer();
1573   double *nc=getPointer();
1574   for(int i=0;i<nbOfTuples;i++)
1575     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1576       nc[nbOfCompo*i+compoIds[j]]=*ac;
1577 }
1578
1579 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1580 {
1581   if(newArray!=arrayToSet)
1582     {
1583       if(arrayToSet)
1584         arrayToSet->decrRef();
1585       arrayToSet=newArray;
1586       if(arrayToSet)
1587         arrayToSet->incrRef();
1588     }
1589 }
1590
1591 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1592 {
1593   if(!other)
1594     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1595   if(getNumberOfComponents()!=other->getNumberOfComponents())
1596     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1597   _mem.insertAtTheEnd(other->begin(),other->end());
1598 }
1599
1600 /*!
1601  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1602  * is thrown.
1603  * \throw If zero is found in \a this array.
1604  */
1605 void DataArrayDouble::checkNoNullValues() const
1606 {
1607   const double *tmp=getConstPointer();
1608   std::size_t nbOfElems=getNbOfElems();
1609   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1610   if(where!=tmp+nbOfElems)
1611     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1612 }
1613
1614 /*!
1615  * Computes minimal and maximal value in each component. An output array is filled
1616  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1617  * enough memory before calling this method.
1618  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1619  *               It is filled as follows:<br>
1620  *               \a bounds[0] = \c min_of_component_0 <br>
1621  *               \a bounds[1] = \c max_of_component_0 <br>
1622  *               \a bounds[2] = \c min_of_component_1 <br>
1623  *               \a bounds[3] = \c max_of_component_1 <br>
1624  *               ...
1625  */
1626 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1627 {
1628   checkAllocated();
1629   int dim=getNumberOfComponents();
1630   for (int idim=0; idim<dim; idim++)
1631     {
1632       bounds[idim*2]=std::numeric_limits<double>::max();
1633       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1634     } 
1635   const double *ptr=getConstPointer();
1636   int nbOfTuples=getNumberOfTuples();
1637   for(int i=0;i<nbOfTuples;i++)
1638     {
1639       for(int idim=0;idim<dim;idim++)
1640         {
1641           if(bounds[idim*2]>ptr[i*dim+idim])
1642             {
1643               bounds[idim*2]=ptr[i*dim+idim];
1644             }
1645           if(bounds[idim*2+1]<ptr[i*dim+idim])
1646             {
1647               bounds[idim*2+1]=ptr[i*dim+idim];
1648             }
1649         }
1650     }
1651 }
1652
1653 /*!
1654  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1655  * to store both the min and max per component of each tuples. 
1656  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1657  *
1658  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1659  *
1660  * \throw If \a this is not allocated yet.
1661  */
1662 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1663 {
1664   checkAllocated();
1665   const double *dataPtr=getConstPointer();
1666   int nbOfCompo=getNumberOfComponents();
1667   int nbTuples=getNumberOfTuples();
1668   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1669   bbox->alloc(nbTuples,2*nbOfCompo);
1670   double *bboxPtr=bbox->getPointer();
1671   for(int i=0;i<nbTuples;i++)
1672     {
1673       for(int j=0;j<nbOfCompo;j++)
1674         {
1675           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1676           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1677         }
1678     }
1679   return bbox.retn();
1680 }
1681
1682 /*!
1683  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1684  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1685  * 
1686  * \param [in] other a DataArrayDouble having same number of components than \a this.
1687  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1688  * \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.
1689  *             \a cI allows to extract information in \a c.
1690  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1691  *
1692  * \throw In case of:
1693  *  - \a this is not allocated
1694  *  - \a other is not allocated or null
1695  *  - \a this and \a other do not have the same number of components
1696  *  - if number of components of \a this is not in [1,2,3]
1697  *
1698  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1699  */
1700 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1701 {
1702   if(!other)
1703     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1704   checkAllocated();
1705   other->checkAllocated();
1706   int nbOfCompo=getNumberOfComponents();
1707   int otherNbOfCompo=other->getNumberOfComponents();
1708   if(nbOfCompo!=otherNbOfCompo)
1709     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1710   int nbOfTuplesOther=other->getNumberOfTuples();
1711   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1712   switch(nbOfCompo)
1713   {
1714     case 3:
1715       {
1716         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1717         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1718         break;
1719       }
1720     case 2:
1721       {
1722         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1723         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1724         break;
1725       }
1726     case 1:
1727       {
1728         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1729         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1730         break;
1731       }
1732     default:
1733       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1734   }
1735   c=cArr.retn(); cI=cIArr.retn();
1736 }
1737
1738 /*!
1739  * 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
1740  * around origin of 'radius' 1.
1741  * 
1742  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1743  */
1744 void DataArrayDouble::recenterForMaxPrecision(double eps)
1745 {
1746   checkAllocated();
1747   int dim=getNumberOfComponents();
1748   std::vector<double> bounds(2*dim);
1749   getMinMaxPerComponent(&bounds[0]);
1750   for(int i=0;i<dim;i++)
1751     {
1752       double delta=bounds[2*i+1]-bounds[2*i];
1753       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1754       if(delta>eps)
1755         applyLin(1./delta,-offset/delta,i);
1756       else
1757         applyLin(1.,-offset,i);
1758     }
1759 }
1760
1761 /*!
1762  * Returns the maximal value and all its locations within \a this one-dimensional array.
1763  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1764  *               tuples holding the maximal value. The caller is to delete it using
1765  *               decrRef() as it is no more needed.
1766  *  \return double - the maximal value among all values of \a this array.
1767  *  \throw If \a this->getNumberOfComponents() != 1
1768  *  \throw If \a this->getNumberOfTuples() < 1
1769  */
1770 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1771 {
1772   int tmp;
1773   tupleIds=0;
1774   double ret=getMaxValue(tmp);
1775   tupleIds=findIdsInRange(ret,ret);
1776   return ret;
1777 }
1778
1779 /*!
1780  * Returns the minimal value and all its locations within \a this one-dimensional array.
1781  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1782  *               tuples holding the minimal value. The caller is to delete it using
1783  *               decrRef() as it is no more needed.
1784  *  \return double - the minimal value among all values of \a this array.
1785  *  \throw If \a this->getNumberOfComponents() != 1
1786  *  \throw If \a this->getNumberOfTuples() < 1
1787  */
1788 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1789 {
1790   int tmp;
1791   tupleIds=0;
1792   double ret=getMinValue(tmp);
1793   tupleIds=findIdsInRange(ret,ret);
1794   return ret;
1795 }
1796
1797 /*!
1798  * 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.
1799  * This method only works for single component array.
1800  *
1801  * \return a value in [ 0, \c this->getNumberOfTuples() )
1802  *
1803  * \throw If \a this is not allocated
1804  *
1805  */
1806 int DataArrayDouble::count(double value, double eps) const
1807 {
1808   int ret=0;
1809   checkAllocated();
1810   if(getNumberOfComponents()!=1)
1811     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1812   const double *vals=begin();
1813   int nbOfTuples=getNumberOfTuples();
1814   for(int i=0;i<nbOfTuples;i++,vals++)
1815     if(fabs(*vals-value)<=eps)
1816       ret++;
1817   return ret;
1818 }
1819
1820 /*!
1821  * Returns the average value of \a this one-dimensional array.
1822  *  \return double - the average value over all values of \a this array.
1823  *  \throw If \a this->getNumberOfComponents() != 1
1824  *  \throw If \a this->getNumberOfTuples() < 1
1825  */
1826 double DataArrayDouble::getAverageValue() const
1827 {
1828   if(getNumberOfComponents()!=1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1830   int nbOfTuples=getNumberOfTuples();
1831   if(nbOfTuples<=0)
1832     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1833   const double *vals=getConstPointer();
1834   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1835   return ret/nbOfTuples;
1836 }
1837
1838 /*!
1839  * Returns the Euclidean norm of the vector defined by \a this array.
1840  *  \return double - the value of the Euclidean norm, i.e.
1841  *          the square root of the inner product of vector.
1842  *  \throw If \a this is not allocated.
1843  */
1844 double DataArrayDouble::norm2() const
1845 {
1846   checkAllocated();
1847   double ret=0.;
1848   std::size_t nbOfElems=getNbOfElems();
1849   const double *pt=getConstPointer();
1850   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1851     ret+=(*pt)*(*pt);
1852   return sqrt(ret);
1853 }
1854
1855 /*!
1856  * Returns the maximum norm of the vector defined by \a this array.
1857  * This method works even if the number of components is diferent from one.
1858  * If the number of elements in \a this is 0, -1. is returned.
1859  *  \return double - the value of the maximum norm, i.e.
1860  *          the maximal absolute value among values of \a this array (whatever its number of components).
1861  *  \throw If \a this is not allocated.
1862  */
1863 double DataArrayDouble::normMax() const
1864 {
1865   checkAllocated();
1866   double ret(-1.);
1867   std::size_t nbOfElems(getNbOfElems());
1868   const double *pt(getConstPointer());
1869   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1870     {
1871       double val(std::abs(*pt));
1872       if(val>ret)
1873         ret=val;
1874     }
1875   return ret;
1876 }
1877
1878 /*!
1879  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1880  * This method works even if the number of components is diferent from one.
1881  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1882  *  \return double - the value of the minimum norm, i.e.
1883  *          the minimal absolute value among values of \a this array (whatever its number of components).
1884  *  \throw If \a this is not allocated.
1885  */
1886 double DataArrayDouble::normMin() const
1887 {
1888   checkAllocated();
1889   double ret(std::numeric_limits<double>::max());
1890   std::size_t nbOfElems(getNbOfElems());
1891   const double *pt(getConstPointer());
1892   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1893     {
1894       double val(std::abs(*pt));
1895       if(val<ret)
1896         ret=val;
1897     }
1898   return ret;
1899 }
1900
1901 /*!
1902  * Accumulates values of each component of \a this array.
1903  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1904  *         by the caller, that is filled by this method with sum value for each
1905  *         component.
1906  *  \throw If \a this is not allocated.
1907  */
1908 void DataArrayDouble::accumulate(double *res) const
1909 {
1910   checkAllocated();
1911   const double *ptr=getConstPointer();
1912   int nbTuple=getNumberOfTuples();
1913   int nbComps=getNumberOfComponents();
1914   std::fill(res,res+nbComps,0.);
1915   for(int i=0;i<nbTuple;i++)
1916     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1917 }
1918
1919 /*!
1920  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1921  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1922  *
1923  *
1924  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1925  * \a tupleEnd. If not an exception will be thrown.
1926  *
1927  * \param [in] tupleBg start pointer (included) of input external tuple
1928  * \param [in] tupleEnd end pointer (not included) of input external tuple
1929  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1930  * \return the min distance.
1931  * \sa MEDCouplingUMesh::distanceToPoint
1932  */
1933 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1934 {
1935   checkAllocated();
1936   int nbTuple=getNumberOfTuples();
1937   int nbComps=getNumberOfComponents();
1938   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1939     { 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()); }
1940   if(nbTuple==0)
1941     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1942   double ret0=std::numeric_limits<double>::max();
1943   tupleId=-1;
1944   const double *work=getConstPointer();
1945   for(int i=0;i<nbTuple;i++)
1946     {
1947       double val=0.;
1948       for(int j=0;j<nbComps;j++,work++) 
1949         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1950       if(val>=ret0)
1951         continue;
1952       else
1953         { ret0=val; tupleId=i; }
1954     }
1955   return sqrt(ret0);
1956 }
1957
1958 /*!
1959  * Accumulate values of the given component of \a this array.
1960  *  \param [in] compId - the index of the component of interest.
1961  *  \return double - a sum value of \a compId-th component.
1962  *  \throw If \a this is not allocated.
1963  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1964  *         not respected.
1965  */
1966 double DataArrayDouble::accumulate(int compId) const
1967 {
1968   checkAllocated();
1969   const double *ptr=getConstPointer();
1970   int nbTuple=getNumberOfTuples();
1971   int nbComps=getNumberOfComponents();
1972   if(compId<0 || compId>=nbComps)
1973     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1974   double ret=0.;
1975   for(int i=0;i<nbTuple;i++)
1976     ret+=ptr[i*nbComps+compId];
1977   return ret;
1978 }
1979
1980 /*!
1981  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1982  * The returned array will have same number of components than \a this and number of tuples equal to
1983  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1984  *
1985  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1986  * 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.
1987  *
1988  * \param [in] bgOfIndex - begin (included) of the input index array.
1989  * \param [in] endOfIndex - end (excluded) of the input index array.
1990  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1991  * 
1992  * \throw If bgOfIndex or end is NULL.
1993  * \throw If input index array is not ascendingly sorted.
1994  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1995  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1996  */
1997 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1998 {
1999   if(!bgOfIndex || !endOfIndex)
2000     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
2001   checkAllocated();
2002   int nbCompo=getNumberOfComponents();
2003   int nbOfTuples=getNumberOfTuples();
2004   int sz=(int)std::distance(bgOfIndex,endOfIndex);
2005   if(sz<1)
2006     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
2007   sz--;
2008   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
2009   const int *w=bgOfIndex;
2010   if(*w<0 || *w>=nbOfTuples)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
2012   const double *srcPt=begin()+(*w)*nbCompo;
2013   double *tmp=ret->getPointer();
2014   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
2015     {
2016       std::fill(tmp,tmp+nbCompo,0.);
2017       if(w[1]>=w[0])
2018         {
2019           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
2020             {
2021               if(j>=0 && j<nbOfTuples)
2022                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
2023               else
2024                 {
2025                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2026                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2027                 }
2028             }
2029         }
2030       else
2031         {
2032           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2033           throw INTERP_KERNEL::Exception(oss.str().c_str());
2034         }
2035     }
2036   ret->copyStringInfoFrom(*this);
2037   return ret.retn();
2038 }
2039
2040 /*!
2041  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2042  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2043  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2044  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2045  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2046  *          is to delete this array using decrRef() as it is no more needed. The array
2047  *          does not contain any textual info on components.
2048  *  \throw If \a this->getNumberOfComponents() != 2.
2049  */
2050 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2051 {
2052   checkAllocated();
2053   int nbOfComp(getNumberOfComponents());
2054   if(nbOfComp!=2)
2055     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2056   int nbOfTuple(getNumberOfTuples());
2057   DataArrayDouble *ret(DataArrayDouble::New());
2058   ret->alloc(nbOfTuple,2);
2059   double *w(ret->getPointer());
2060   const double *wIn(getConstPointer());
2061   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2062     {
2063       w[0]=wIn[0]*cos(wIn[1]);
2064       w[1]=wIn[0]*sin(wIn[1]);
2065     }
2066   return ret;
2067 }
2068
2069 /*!
2070  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2071  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2072  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2073  * the Cylindrical CS.
2074  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2075  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2076  *          on the third component is copied from \a this array. The caller
2077  *          is to delete this array using decrRef() as it is no more needed. 
2078  *  \throw If \a this->getNumberOfComponents() != 3.
2079  */
2080 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2081 {
2082   checkAllocated();
2083   int nbOfComp(getNumberOfComponents());
2084   if(nbOfComp!=3)
2085     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2086   int nbOfTuple(getNumberOfTuples());
2087   DataArrayDouble *ret(DataArrayDouble::New());
2088   ret->alloc(getNumberOfTuples(),3);
2089   double *w(ret->getPointer());
2090   const double *wIn(getConstPointer());
2091   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2092     {
2093       w[0]=wIn[0]*cos(wIn[1]);
2094       w[1]=wIn[0]*sin(wIn[1]);
2095       w[2]=wIn[2];
2096     }
2097   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2098   return ret;
2099 }
2100
2101 /*!
2102  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2103  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2104  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2105  * point in the Cylindrical CS.
2106  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2107  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2108  *          on the third component is copied from \a this array. The caller
2109  *          is to delete this array using decrRef() as it is no more needed.
2110  *  \throw If \a this->getNumberOfComponents() != 3.
2111  */
2112 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2113 {
2114   checkAllocated();
2115   int nbOfComp(getNumberOfComponents());
2116   if(nbOfComp!=3)
2117     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2118   int nbOfTuple(getNumberOfTuples());
2119   DataArrayDouble *ret(DataArrayDouble::New());
2120   ret->alloc(getNumberOfTuples(),3);
2121   double *w(ret->getPointer());
2122   const double *wIn(getConstPointer());
2123   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2124     {
2125       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2126       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2127       w[2]=wIn[0]*cos(wIn[1]);
2128     }
2129   return ret;
2130 }
2131
2132 /*!
2133  * 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.
2134  * 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.
2135  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2136  *
2137  * \param [in] atOfThis - The axis type of \a this.
2138  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2139  */
2140 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2141 {
2142   checkAllocated();
2143   int nbOfComp(getNumberOfComponents());
2144   MCAuto<DataArrayDouble> ret;
2145   switch(atOfThis)
2146     {
2147     case AX_CART:
2148       ret=deepCopy();
2149     case AX_CYL:
2150       if(nbOfComp==3)
2151         {
2152           ret=fromCylToCart();
2153           break;
2154         }
2155       if(nbOfComp==2)
2156         {
2157           ret=fromPolarToCart();
2158           break;
2159         }
2160       else
2161         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2162     case AX_SPHER:
2163       if(nbOfComp==3)
2164         {
2165           ret=fromSpherToCart();
2166           break;
2167         }
2168       if(nbOfComp==2)
2169         {
2170           ret=fromPolarToCart();
2171           break;
2172         }
2173       else
2174         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2175     default:
2176       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2177     }
2178   ret->copyStringInfoFrom(*this);
2179   return ret.retn();
2180 }
2181
2182 /*!
2183  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2184  * array contating 6 components.
2185  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2186  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2187  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2188  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2189  *  \throw If \a this->getNumberOfComponents() != 6.
2190  */
2191 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2192 {
2193   checkAllocated();
2194   int nbOfComp(getNumberOfComponents());
2195   if(nbOfComp!=6)
2196     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2197   DataArrayDouble *ret=DataArrayDouble::New();
2198   int nbOfTuple=getNumberOfTuples();
2199   ret->alloc(nbOfTuple,1);
2200   const double *src=getConstPointer();
2201   double *dest=ret->getPointer();
2202   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2203     *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];
2204   return ret;
2205 }
2206
2207 /*!
2208  * Computes the determinant of every square matrix defined by the tuple of \a this
2209  * array, which contains either 4, 6 or 9 components. The case of 6 components
2210  * corresponds to that of the upper triangular matrix.
2211  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2212  *          is the determinant of matrix of the corresponding tuple of \a this array.
2213  *          The caller is to delete this result array using decrRef() as it is no more
2214  *          needed. 
2215  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2216  */
2217 DataArrayDouble *DataArrayDouble::determinant() const
2218 {
2219   checkAllocated();
2220   DataArrayDouble *ret=DataArrayDouble::New();
2221   int nbOfTuple=getNumberOfTuples();
2222   ret->alloc(nbOfTuple,1);
2223   const double *src=getConstPointer();
2224   double *dest=ret->getPointer();
2225   switch(getNumberOfComponents())
2226   {
2227     case 6:
2228       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2229         *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];
2230       return ret;
2231     case 4:
2232       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2233         *dest=src[0]*src[3]-src[1]*src[2];
2234       return ret;
2235     case 9:
2236       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2237         *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];
2238       return ret;
2239     default:
2240       ret->decrRef();
2241       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2242   }
2243 }
2244
2245 /*!
2246  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2247  * \a this array, which contains 6 components.
2248  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2249  *          components, whose each tuple contains the eigenvalues of the matrix of
2250  *          corresponding tuple of \a this array. 
2251  *          The caller is to delete this result array using decrRef() as it is no more
2252  *          needed. 
2253  *  \throw If \a this->getNumberOfComponents() != 6.
2254  */
2255 DataArrayDouble *DataArrayDouble::eigenValues() const
2256 {
2257   checkAllocated();
2258   int nbOfComp=getNumberOfComponents();
2259   if(nbOfComp!=6)
2260     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2261   DataArrayDouble *ret=DataArrayDouble::New();
2262   int nbOfTuple=getNumberOfTuples();
2263   ret->alloc(nbOfTuple,3);
2264   const double *src=getConstPointer();
2265   double *dest=ret->getPointer();
2266   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2267     INTERP_KERNEL::computeEigenValues6(src,dest);
2268   return ret;
2269 }
2270
2271 /*!
2272  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2273  * \a this array, which contains 6 components.
2274  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2275  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2276  *          corresponding tuple of \a this array.
2277  *          The caller is to delete this result array using decrRef() as it is no more
2278  *          needed.
2279  *  \throw If \a this->getNumberOfComponents() != 6.
2280  */
2281 DataArrayDouble *DataArrayDouble::eigenVectors() const
2282 {
2283   checkAllocated();
2284   int nbOfComp=getNumberOfComponents();
2285   if(nbOfComp!=6)
2286     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2287   DataArrayDouble *ret=DataArrayDouble::New();
2288   int nbOfTuple=getNumberOfTuples();
2289   ret->alloc(nbOfTuple,9);
2290   const double *src=getConstPointer();
2291   double *dest=ret->getPointer();
2292   for(int i=0;i<nbOfTuple;i++,src+=6)
2293     {
2294       double tmp[3];
2295       INTERP_KERNEL::computeEigenValues6(src,tmp);
2296       for(int j=0;j<3;j++,dest+=3)
2297         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2298     }
2299   return ret;
2300 }
2301
2302 /*!
2303  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2304  * array, which contains either 4, 6 or 9 components. The case of 6 components
2305  * corresponds to that of the upper triangular matrix.
2306  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2307  *          same number of components as \a this one, whose each tuple is the inverse
2308  *          matrix of the matrix of corresponding tuple of \a this array. 
2309  *          The caller is to delete this result array using decrRef() as it is no more
2310  *          needed. 
2311  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2312  */
2313 DataArrayDouble *DataArrayDouble::inverse() const
2314 {
2315   checkAllocated();
2316   int nbOfComp=getNumberOfComponents();
2317   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2318     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2319   DataArrayDouble *ret=DataArrayDouble::New();
2320   int nbOfTuple=getNumberOfTuples();
2321   ret->alloc(nbOfTuple,nbOfComp);
2322   const double *src=getConstPointer();
2323   double *dest=ret->getPointer();
2324   if(nbOfComp==6)
2325     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2326       {
2327         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];
2328         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2329         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2330         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2331         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2332         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2333         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2334       }
2335   else if(nbOfComp==4)
2336     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2337       {
2338         double det=src[0]*src[3]-src[1]*src[2];
2339         dest[0]=src[3]/det;
2340         dest[1]=-src[1]/det;
2341         dest[2]=-src[2]/det;
2342         dest[3]=src[0]/det;
2343       }
2344   else
2345     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2346       {
2347         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];
2348         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2349         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2350         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2351         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2352         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2353         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2354         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2355         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2356         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2357       }
2358   return ret;
2359 }
2360
2361 /*!
2362  * Computes the trace of every matrix defined by the tuple of \a this
2363  * array, which contains either 4, 6 or 9 components. The case of 6 components
2364  * corresponds to that of the upper triangular matrix.
2365  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2366  *          1 component, whose each tuple is the trace of
2367  *          the matrix of corresponding tuple of \a this array. 
2368  *          The caller is to delete this result array using decrRef() as it is no more
2369  *          needed. 
2370  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2371  */
2372 DataArrayDouble *DataArrayDouble::trace() const
2373 {
2374   checkAllocated();
2375   int nbOfComp=getNumberOfComponents();
2376   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2377     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2378   DataArrayDouble *ret=DataArrayDouble::New();
2379   int nbOfTuple=getNumberOfTuples();
2380   ret->alloc(nbOfTuple,1);
2381   const double *src=getConstPointer();
2382   double *dest=ret->getPointer();
2383   if(nbOfComp==6)
2384     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2385       *dest=src[0]+src[1]+src[2];
2386   else if(nbOfComp==4)
2387     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2388       *dest=src[0]+src[3];
2389   else
2390     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2391       *dest=src[0]+src[4]+src[8];
2392   return ret;
2393 }
2394
2395 /*!
2396  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2397  * \a this array, which contains 6 components.
2398  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2399  *          same number of components and tuples as \a this array.
2400  *          The caller is to delete this result array using decrRef() as it is no more
2401  *          needed.
2402  *  \throw If \a this->getNumberOfComponents() != 6.
2403  */
2404 DataArrayDouble *DataArrayDouble::deviator() const
2405 {
2406   checkAllocated();
2407   int nbOfComp=getNumberOfComponents();
2408   if(nbOfComp!=6)
2409     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2410   DataArrayDouble *ret=DataArrayDouble::New();
2411   int nbOfTuple=getNumberOfTuples();
2412   ret->alloc(nbOfTuple,6);
2413   const double *src=getConstPointer();
2414   double *dest=ret->getPointer();
2415   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2416     {
2417       double tr=(src[0]+src[1]+src[2])/3.;
2418       dest[0]=src[0]-tr;
2419       dest[1]=src[1]-tr;
2420       dest[2]=src[2]-tr;
2421       dest[3]=src[3];
2422       dest[4]=src[4];
2423       dest[5]=src[5];
2424     }
2425   return ret;
2426 }
2427
2428 /*!
2429  * Computes the magnitude of every vector defined by the tuple of
2430  * \a this array.
2431  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2432  *          same number of tuples as \a this array and one component.
2433  *          The caller is to delete this result array using decrRef() as it is no more
2434  *          needed.
2435  *  \throw If \a this is not allocated.
2436  */
2437 DataArrayDouble *DataArrayDouble::magnitude() const
2438 {
2439   checkAllocated();
2440   int nbOfComp=getNumberOfComponents();
2441   DataArrayDouble *ret=DataArrayDouble::New();
2442   int nbOfTuple=getNumberOfTuples();
2443   ret->alloc(nbOfTuple,1);
2444   const double *src=getConstPointer();
2445   double *dest=ret->getPointer();
2446   for(int i=0;i<nbOfTuple;i++,dest++)
2447     {
2448       double sum=0.;
2449       for(int j=0;j<nbOfComp;j++,src++)
2450         sum+=(*src)*(*src);
2451       *dest=sqrt(sum);
2452     }
2453   return ret;
2454 }
2455
2456 /*!
2457  * Computes for each tuple the sum of number of components values in the tuple and return it.
2458  * 
2459  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2460  *          same number of tuples as \a this array and one component.
2461  *          The caller is to delete this result array using decrRef() as it is no more
2462  *          needed.
2463  *  \throw If \a this is not allocated.
2464  */
2465 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2466 {
2467   checkAllocated();
2468   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2469   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2470   ret->alloc(nbOfTuple,1);
2471   const double *src(getConstPointer());
2472   double *dest(ret->getPointer());
2473   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2474     *dest=std::accumulate(src,src+nbOfComp,0.);
2475   return ret.retn();
2476 }
2477
2478 /*!
2479  * Computes the maximal value within every tuple of \a this array.
2480  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2481  *          same number of tuples as \a this array and one component.
2482  *          The caller is to delete this result array using decrRef() as it is no more
2483  *          needed.
2484  *  \throw If \a this is not allocated.
2485  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2486  */
2487 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2488 {
2489   checkAllocated();
2490   int nbOfComp=getNumberOfComponents();
2491   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2492   int nbOfTuple=getNumberOfTuples();
2493   ret->alloc(nbOfTuple,1);
2494   const double *src=getConstPointer();
2495   double *dest=ret->getPointer();
2496   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2497     *dest=*std::max_element(src,src+nbOfComp);
2498   return ret.retn();
2499 }
2500
2501 /*!
2502  * Computes the maximal value within every tuple of \a this array and it returns the first component
2503  * id for each tuple that corresponds to the maximal value within the tuple.
2504  * 
2505  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2506  *          same number of tuples and only one component.
2507  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2508  *          same number of tuples as \a this array and one component.
2509  *          The caller is to delete this result array using decrRef() as it is no more
2510  *          needed.
2511  *  \throw If \a this is not allocated.
2512  *  \sa DataArrayDouble::maxPerTuple
2513  */
2514 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2515 {
2516   checkAllocated();
2517   int nbOfComp=getNumberOfComponents();
2518   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2519   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2520   int nbOfTuple=getNumberOfTuples();
2521   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2522   const double *src=getConstPointer();
2523   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2524   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2525     {
2526       const double *loc=std::max_element(src,src+nbOfComp);
2527       *dest=*loc;
2528       *dest1=(int)std::distance(src,loc);
2529     }
2530   compoIdOfMaxPerTuple=ret1.retn();
2531   return ret0.retn();
2532 }
2533
2534 /*!
2535  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2536  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2537  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2538  * \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)
2539  *
2540  * \warning use this method with care because it can leads to big amount of consumed memory !
2541  * 
2542  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2543  *
2544  * \throw If \a this is not allocated.
2545  *
2546  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2547  */
2548 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2549 {
2550   checkAllocated();
2551   int nbOfComp=getNumberOfComponents();
2552   int nbOfTuples=getNumberOfTuples();
2553   const double *inData=getConstPointer();
2554   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2555   ret->alloc(nbOfTuples*nbOfTuples,1);
2556   double *outData=ret->getPointer();
2557   for(int i=0;i<nbOfTuples;i++)
2558     {
2559       outData[i*nbOfTuples+i]=0.;
2560       for(int j=i+1;j<nbOfTuples;j++)
2561         {
2562           double dist=0.;
2563           for(int k=0;k<nbOfComp;k++)
2564             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2565           dist=sqrt(dist);
2566           outData[i*nbOfTuples+j]=dist;
2567           outData[j*nbOfTuples+i]=dist;
2568         }
2569     }
2570   return ret.retn();
2571 }
2572
2573 /*!
2574  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2575  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2576  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2577  * \n Output rectangular matrix is sorted along rows.
2578  * \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)
2579  *
2580  * \warning use this method with care because it can leads to big amount of consumed memory !
2581  * 
2582  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2583  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2584  *
2585  * \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.
2586  *
2587  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2588  */
2589 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2590 {
2591   if(!other)
2592     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2593   checkAllocated();
2594   other->checkAllocated();
2595   int nbOfComp=getNumberOfComponents();
2596   int otherNbOfComp=other->getNumberOfComponents();
2597   if(nbOfComp!=otherNbOfComp)
2598     {
2599       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2600       throw INTERP_KERNEL::Exception(oss.str().c_str());
2601     }
2602   int nbOfTuples=getNumberOfTuples();
2603   int otherNbOfTuples=other->getNumberOfTuples();
2604   const double *inData=getConstPointer();
2605   const double *inDataOther=other->getConstPointer();
2606   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2607   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2608   double *outData=ret->getPointer();
2609   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2610     {
2611       for(int j=0;j<nbOfTuples;j++)
2612         {
2613           double dist=0.;
2614           for(int k=0;k<nbOfComp;k++)
2615             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2616           dist=sqrt(dist);
2617           outData[i*nbOfTuples+j]=dist;
2618         }
2619     }
2620   return ret.retn();
2621 }
2622
2623 /*!
2624  * Sorts value within every tuple of \a this array.
2625  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2626  *              in descending order.
2627  *  \throw If \a this is not allocated.
2628  */
2629 void DataArrayDouble::sortPerTuple(bool asc)
2630 {
2631   checkAllocated();
2632   double *pt=getPointer();
2633   int nbOfTuple=getNumberOfTuples();
2634   int nbOfComp=getNumberOfComponents();
2635   if(asc)
2636     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2637       std::sort(pt,pt+nbOfComp);
2638   else
2639     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2640       std::sort(pt,pt+nbOfComp,std::greater<double>());
2641   declareAsNew();
2642 }
2643
2644 /*!
2645  * Converts every value of \a this array to its absolute value.
2646  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2647  * should be called instead.
2648  *
2649  * \throw If \a this is not allocated.
2650  * \sa DataArrayDouble::computeAbs
2651  */
2652 void DataArrayDouble::abs()
2653 {
2654   checkAllocated();
2655   double *ptr(getPointer());
2656   std::size_t nbOfElems(getNbOfElems());
2657   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2658   declareAsNew();
2659 }
2660
2661 /*!
2662  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2663  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2664  *
2665  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2666  *         same number of tuples and component as \a this array.
2667  *         The caller is to delete this result array using decrRef() as it is no more
2668  *         needed.
2669  * \throw If \a this is not allocated.
2670  * \sa DataArrayDouble::abs
2671  */
2672 DataArrayDouble *DataArrayDouble::computeAbs() const
2673 {
2674   checkAllocated();
2675   DataArrayDouble *newArr(DataArrayDouble::New());
2676   int nbOfTuples(getNumberOfTuples());
2677   int nbOfComp(getNumberOfComponents());
2678   newArr->alloc(nbOfTuples,nbOfComp);
2679   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2680   newArr->copyStringInfoFrom(*this);
2681   return newArr;
2682 }
2683
2684 /*!
2685  * Apply a linear function to a given component of \a this array, so that
2686  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2687  *  \param [in] a - the first coefficient of the function.
2688  *  \param [in] b - the second coefficient of the function.
2689  *  \param [in] compoId - the index of component to modify.
2690  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2691  */
2692 void DataArrayDouble::applyLin(double a, double b, int compoId)
2693 {
2694   checkAllocated();
2695   double *ptr(getPointer()+compoId);
2696   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2697   if(compoId<0 || compoId>=nbOfComp)
2698     {
2699       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2700       throw INTERP_KERNEL::Exception(oss.str().c_str());
2701     }
2702   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2703     *ptr=a*(*ptr)+b;
2704   declareAsNew();
2705 }
2706
2707 /*!
2708  * Apply a linear function to all elements of \a this array, so that
2709  * an element _x_ becomes \f$ a * x + b \f$.
2710  *  \param [in] a - the first coefficient of the function.
2711  *  \param [in] b - the second coefficient of the function.
2712  *  \throw If \a this is not allocated.
2713  */
2714 void DataArrayDouble::applyLin(double a, double b)
2715 {
2716   checkAllocated();
2717   double *ptr=getPointer();
2718   std::size_t nbOfElems=getNbOfElems();
2719   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2720     *ptr=a*(*ptr)+b;
2721   declareAsNew();
2722 }
2723
2724 /*!
2725  * Modify all elements of \a this array, so that
2726  * an element _x_ becomes \f$ numerator / x \f$.
2727  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2728  *           array, all elements processed before detection of the zero element remain
2729  *           modified.
2730  *  \param [in] numerator - the numerator used to modify array elements.
2731  *  \throw If \a this is not allocated.
2732  *  \throw If there is an element equal to 0.0 in \a this array.
2733  */
2734 void DataArrayDouble::applyInv(double numerator)
2735 {
2736   checkAllocated();
2737   double *ptr=getPointer();
2738   std::size_t nbOfElems=getNbOfElems();
2739   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2740     {
2741       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2742         {
2743           *ptr=numerator/(*ptr);
2744         }
2745       else
2746         {
2747           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2748           oss << " !";
2749           throw INTERP_KERNEL::Exception(oss.str().c_str());
2750         }
2751     }
2752   declareAsNew();
2753 }
2754
2755 /*!
2756  * Returns a full copy of \a this array except that sign of all elements is reversed.
2757  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2758  *          same number of tuples and component as \a this array.
2759  *          The caller is to delete this result array using decrRef() as it is no more
2760  *          needed.
2761  *  \throw If \a this is not allocated.
2762  */
2763 DataArrayDouble *DataArrayDouble::negate() const
2764 {
2765   checkAllocated();
2766   DataArrayDouble *newArr=DataArrayDouble::New();
2767   int nbOfTuples=getNumberOfTuples();
2768   int nbOfComp=getNumberOfComponents();
2769   newArr->alloc(nbOfTuples,nbOfComp);
2770   const double *cptr=getConstPointer();
2771   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2772   newArr->copyStringInfoFrom(*this);
2773   return newArr;
2774 }
2775
2776 /*!
2777  * Modify all elements of \a this array, so that
2778  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2779  * all values in \a this have to be >= 0 if val is \b not integer.
2780  *  \param [in] val - the value used to apply pow on all array elements.
2781  *  \throw If \a this is not allocated.
2782  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2783  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2784  *           modified.
2785  */
2786 void DataArrayDouble::applyPow(double val)
2787 {
2788   checkAllocated();
2789   double *ptr=getPointer();
2790   std::size_t nbOfElems=getNbOfElems();
2791   int val2=(int)val;
2792   bool isInt=((double)val2)==val;
2793   if(!isInt)
2794     {
2795       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2796         {
2797           if(*ptr>=0)
2798             *ptr=pow(*ptr,val);
2799           else
2800             {
2801               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2802               throw INTERP_KERNEL::Exception(oss.str().c_str());
2803             }
2804         }
2805     }
2806   else
2807     {
2808       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2809         *ptr=pow(*ptr,val2);
2810     }
2811   declareAsNew();
2812 }
2813
2814 /*!
2815  * Modify all elements of \a this array, so that
2816  * an element _x_ becomes \f$ val ^ x \f$.
2817  *  \param [in] val - the value used to apply pow on all array elements.
2818  *  \throw If \a this is not allocated.
2819  *  \throw If \a val < 0.
2820  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2821  *           array, all elements processed before detection of the zero element remain
2822  *           modified.
2823  */
2824 void DataArrayDouble::applyRPow(double val)
2825 {
2826   checkAllocated();
2827   if(val<0.)
2828     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2829   double *ptr=getPointer();
2830   std::size_t nbOfElems=getNbOfElems();
2831   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2832     *ptr=pow(val,*ptr);
2833   declareAsNew();
2834 }
2835
2836 /*!
2837  * Returns a new DataArrayDouble created from \a this one by applying \a
2838  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2839  * For more info see \ref MEDCouplingArrayApplyFunc
2840  *  \param [in] nbOfComp - number of components in the result array.
2841  *  \param [in] func - the \a FunctionToEvaluate declared as 
2842  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2843  *              where \a pos points to the first component of a tuple of \a this array
2844  *              and \a res points to the first component of a tuple of the result array.
2845  *              Note that length (number of components) of \a pos can differ from
2846  *              that of \a res.
2847  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2848  *          same number of tuples as \a this array.
2849  *          The caller is to delete this result array using decrRef() as it is no more
2850  *          needed.
2851  *  \throw If \a this is not allocated.
2852  *  \throw If \a func returns \a false.
2853  */
2854 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2855 {
2856   checkAllocated();
2857   DataArrayDouble *newArr=DataArrayDouble::New();
2858   int nbOfTuples=getNumberOfTuples();
2859   int oldNbOfComp=getNumberOfComponents();
2860   newArr->alloc(nbOfTuples,nbOfComp);
2861   const double *ptr=getConstPointer();
2862   double *ptrToFill=newArr->getPointer();
2863   for(int i=0;i<nbOfTuples;i++)
2864     {
2865       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2866         {
2867           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2868           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2869           oss << ") : Evaluation of function failed !";
2870           newArr->decrRef();
2871           throw INTERP_KERNEL::Exception(oss.str().c_str());
2872         }
2873     }
2874   return newArr;
2875 }
2876
2877 /*!
2878  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2879  * tuple of \a this array. Textual data is not copied.
2880  * For more info see \ref MEDCouplingArrayApplyFunc1.
2881  *  \param [in] nbOfComp - number of components in the result array.
2882  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2883  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2884  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2885  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2886  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2887  *          same number of tuples as \a this array and \a nbOfComp components.
2888  *          The caller is to delete this result array using decrRef() as it is no more
2889  *          needed.
2890  *  \throw If \a this is not allocated.
2891  *  \throw If computing \a func fails.
2892  */
2893 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2894 {
2895   INTERP_KERNEL::ExprParser expr(func);
2896   expr.parse();
2897   std::set<std::string> vars;
2898   expr.getTrueSetOfVars(vars);
2899   std::vector<std::string> varsV(vars.begin(),vars.end());
2900   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2901 }
2902
2903 /*!
2904  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2905  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2906  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2907  *
2908  * For more info see \ref MEDCouplingArrayApplyFunc0.
2909  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2910  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2911  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2912  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
2913  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2914  *          same number of tuples and components as \a this array.
2915  *          The caller is to delete this result array using decrRef() as it is no more
2916  *          needed.
2917  *  \sa applyFuncOnThis
2918  *  \throw If \a this is not allocated.
2919  *  \throw If computing \a func fails.
2920  */
2921 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2922 {
2923   int nbOfComp(getNumberOfComponents());
2924   if(nbOfComp<=0)
2925     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2926   checkAllocated();
2927   int nbOfTuples(getNumberOfTuples());
2928   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2929   newArr->alloc(nbOfTuples,nbOfComp);
2930   INTERP_KERNEL::ExprParser expr(func);
2931   expr.parse();
2932   std::set<std::string> vars;
2933   expr.getTrueSetOfVars(vars);
2934   if((int)vars.size()>1)
2935     {
2936       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 : ";
2937       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2938       throw INTERP_KERNEL::Exception(oss.str().c_str());
2939     }
2940   if(vars.empty())
2941     {
2942       expr.prepareFastEvaluator();
2943       newArr->rearrange(1);
2944       newArr->fillWithValue(expr.evaluateDouble());
2945       newArr->rearrange(nbOfComp);
2946       return newArr.retn();
2947     }
2948   std::vector<std::string> vars2(vars.begin(),vars.end());
2949   double buff,*ptrToFill(newArr->getPointer());
2950   const double *ptr(begin());
2951   std::vector<double> stck;
2952   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2953   expr.prepareFastEvaluator();
2954   if(!isSafe)
2955     {
2956       for(int i=0;i<nbOfTuples;i++)
2957         {
2958           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2959             {
2960               buff=*ptr;
2961               expr.evaluateDoubleInternal(stck);
2962               *ptrToFill=stck.back();
2963               stck.pop_back();
2964             }
2965         }
2966     }
2967   else
2968     {
2969       for(int i=0;i<nbOfTuples;i++)
2970         {
2971           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2972             {
2973               buff=*ptr;
2974               try
2975               {
2976                   expr.evaluateDoubleInternalSafe(stck);
2977               }
2978               catch(INTERP_KERNEL::Exception& e)
2979               {
2980                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2981                   oss << buff;
2982                   oss << ") : Evaluation of function failed !" << e.what();
2983                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2984               }
2985               *ptrToFill=stck.back();
2986               stck.pop_back();
2987             }
2988         }
2989     }
2990   return newArr.retn();
2991 }
2992
2993 /*!
2994  * This method is a non const method that modify the array in \a this.
2995  * This method only works on one component array. It means that function \a func must
2996  * contain at most one variable.
2997  * This method is a specialization of applyFunc method with one parameter on one component array.
2998  *
2999  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3000  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3001  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3002  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3003  *
3004  * \sa applyFunc
3005  */
3006 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3007 {
3008   int nbOfComp(getNumberOfComponents());
3009   if(nbOfComp<=0)
3010     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3011   checkAllocated();
3012   int nbOfTuples(getNumberOfTuples());
3013   INTERP_KERNEL::ExprParser expr(func);
3014   expr.parse();
3015   std::set<std::string> vars;
3016   expr.getTrueSetOfVars(vars);
3017   if((int)vars.size()>1)
3018     {
3019       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 : ";
3020       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3021       throw INTERP_KERNEL::Exception(oss.str().c_str());
3022     }
3023   if(vars.empty())
3024     {
3025       expr.prepareFastEvaluator();
3026       std::vector<std::string> compInfo(getInfoOnComponents());
3027       rearrange(1);
3028       fillWithValue(expr.evaluateDouble());
3029       rearrange(nbOfComp);
3030       setInfoOnComponents(compInfo);
3031       return ;
3032     }
3033   std::vector<std::string> vars2(vars.begin(),vars.end());
3034   double buff,*ptrToFill(getPointer());
3035   const double *ptr(begin());
3036   std::vector<double> stck;
3037   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3038   expr.prepareFastEvaluator();
3039   if(!isSafe)
3040     {
3041       for(int i=0;i<nbOfTuples;i++)
3042         {
3043           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3044             {
3045               buff=*ptr;
3046               expr.evaluateDoubleInternal(stck);
3047               *ptrToFill=stck.back();
3048               stck.pop_back();
3049             }
3050         }
3051     }
3052   else
3053     {
3054       for(int i=0;i<nbOfTuples;i++)
3055         {
3056           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3057             {
3058               buff=*ptr;
3059               try
3060               {
3061                   expr.evaluateDoubleInternalSafe(stck);
3062               }
3063               catch(INTERP_KERNEL::Exception& e)
3064               {
3065                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3066                   oss << buff;
3067                   oss << ") : Evaluation of function failed !" << e.what();
3068                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3069               }
3070               *ptrToFill=stck.back();
3071               stck.pop_back();
3072             }
3073         }
3074     }
3075 }
3076
3077 /*!
3078  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3079  * tuple of \a this array. Textual data is not copied.
3080  * For more info see \ref MEDCouplingArrayApplyFunc2.
3081  *  \param [in] nbOfComp - number of components in the result array.
3082  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3083  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3084  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3085  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3086  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3087  *          same number of tuples as \a this array.
3088  *          The caller is to delete this result array using decrRef() as it is no more
3089  *          needed.
3090  *  \throw If \a this is not allocated.
3091  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3092  *  \throw If computing \a func fails.
3093  */
3094 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3095 {
3096   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3097 }
3098
3099 /*!
3100  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3101  * tuple of \a this array. Textual data is not copied.
3102  * For more info see \ref MEDCouplingArrayApplyFunc3.
3103  *  \param [in] nbOfComp - number of components in the result array.
3104  *  \param [in] varsOrder - sequence of vars defining their order.
3105  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3106  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3107  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3108  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3109  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3110  *          same number of tuples as \a this array.
3111  *          The caller is to delete this result array using decrRef() as it is no more
3112  *          needed.
3113  *  \throw If \a this is not allocated.
3114  *  \throw If \a func contains vars not in \a varsOrder.
3115  *  \throw If computing \a func fails.
3116  */
3117 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3118 {
3119   if(nbOfComp<=0)
3120     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3121   std::vector<std::string> varsOrder2(varsOrder);
3122   int oldNbOfComp(getNumberOfComponents());
3123   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3124     varsOrder2.push_back(std::string());
3125   checkAllocated();
3126   int nbOfTuples(getNumberOfTuples());
3127   INTERP_KERNEL::ExprParser expr(func);
3128   expr.parse();
3129   std::set<std::string> vars;
3130   expr.getTrueSetOfVars(vars);
3131   if((int)vars.size()>oldNbOfComp)
3132     {
3133       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3134       oss << vars.size() << " variables : ";
3135       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3136       throw INTERP_KERNEL::Exception(oss.str().c_str());
3137     }
3138   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3139   newArr->alloc(nbOfTuples,nbOfComp);
3140   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3141   double *buffPtr(buff),*ptrToFill;
3142   std::vector<double> stck;
3143   for(int iComp=0;iComp<nbOfComp;iComp++)
3144     {
3145       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3146       expr.prepareFastEvaluator();
3147       const double *ptr(getConstPointer());
3148       ptrToFill=newArr->getPointer()+iComp;
3149       if(!isSafe)
3150         {
3151           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3152             {
3153               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3154               expr.evaluateDoubleInternal(stck);
3155               *ptrToFill=stck.back();
3156               stck.pop_back();
3157             }
3158         }
3159       else
3160         {
3161           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3162             {
3163               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3164               try
3165               {
3166                   expr.evaluateDoubleInternalSafe(stck);
3167                   *ptrToFill=stck.back();
3168                   stck.pop_back();
3169               }
3170               catch(INTERP_KERNEL::Exception& e)
3171               {
3172                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3173                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3174                   oss << ") : Evaluation of function failed !" << e.what();
3175                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3176               }
3177             }
3178         }
3179     }
3180   return newArr.retn();
3181 }
3182
3183 void DataArrayDouble::applyFuncFast32(const std::string& func)
3184 {
3185   checkAllocated();
3186   INTERP_KERNEL::ExprParser expr(func);
3187   expr.parse();
3188   char *funcStr=expr.compileX86();
3189   MYFUNCPTR funcPtr;
3190   *((void **)&funcPtr)=funcStr;//he he...
3191   //
3192   double *ptr=getPointer();
3193   int nbOfComp=getNumberOfComponents();
3194   int nbOfTuples=getNumberOfTuples();
3195   int nbOfElems=nbOfTuples*nbOfComp;
3196   for(int i=0;i<nbOfElems;i++,ptr++)
3197     *ptr=funcPtr(*ptr);
3198   declareAsNew();
3199 }
3200
3201 void DataArrayDouble::applyFuncFast64(const std::string& func)
3202 {
3203   checkAllocated();
3204   INTERP_KERNEL::ExprParser expr(func);
3205   expr.parse();
3206   char *funcStr=expr.compileX86_64();
3207   MYFUNCPTR funcPtr;
3208   *((void **)&funcPtr)=funcStr;//he he...
3209   //
3210   double *ptr=getPointer();
3211   int nbOfComp=getNumberOfComponents();
3212   int nbOfTuples=getNumberOfTuples();
3213   int nbOfElems=nbOfTuples*nbOfComp;
3214   for(int i=0;i<nbOfElems;i++,ptr++)
3215     *ptr=funcPtr(*ptr);
3216   declareAsNew();
3217 }
3218
3219 /*!
3220  * \return a new object that is the result of the symmetry along 3D plane defined by its normal vector \a normalVector and a point \a point.
3221  */
3222 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3223 {
3224   checkAllocated();
3225   if(getNumberOfComponents()!=3)
3226     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3227   int nbTuples(getNumberOfTuples());
3228   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3229   ret->alloc(nbTuples,3);
3230   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3231   return ret;
3232 }
3233
3234 DataArrayDoubleIterator *DataArrayDouble::iterator()
3235 {
3236   return new DataArrayDoubleIterator(this);
3237 }
3238
3239 /*!
3240  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3241  * array whose values are within a given range. Textual data is not copied.
3242  *  \param [in] vmin - a lowest acceptable value (included).
3243  *  \param [in] vmax - a greatest acceptable value (included).
3244  *  \return DataArrayInt * - the new instance of DataArrayInt.
3245  *          The caller is to delete this result array using decrRef() as it is no more
3246  *          needed.
3247  *  \throw If \a this->getNumberOfComponents() != 1.
3248  *
3249  *  \sa DataArrayDouble::findIdsNotInRange
3250  *
3251  *  \if ENABLE_EXAMPLES
3252  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3253  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3254  *  \endif
3255  */
3256 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3257 {
3258   checkAllocated();
3259   if(getNumberOfComponents()!=1)
3260     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3261   const double *cptr(begin());
3262   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3263   int nbOfTuples(getNumberOfTuples());
3264   for(int i=0;i<nbOfTuples;i++,cptr++)
3265     if(*cptr>=vmin && *cptr<=vmax)
3266       ret->pushBackSilent(i);
3267   return ret.retn();
3268 }
3269
3270 /*!
3271  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3272  * array whose values are not within a given range. Textual data is not copied.
3273  *  \param [in] vmin - a lowest not acceptable value (excluded).
3274  *  \param [in] vmax - a greatest not acceptable value (excluded).
3275  *  \return DataArrayInt * - the new instance of DataArrayInt.
3276  *          The caller is to delete this result array using decrRef() as it is no more
3277  *          needed.
3278  *  \throw If \a this->getNumberOfComponents() != 1.
3279  *
3280  *  \sa DataArrayDouble::findIdsInRange
3281  */
3282 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3283 {
3284   checkAllocated();
3285   if(getNumberOfComponents()!=1)
3286     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3287   const double *cptr(begin());
3288   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3289   int nbOfTuples(getNumberOfTuples());
3290   for(int i=0;i<nbOfTuples;i++,cptr++)
3291     if(*cptr<vmin || *cptr>vmax)
3292       ret->pushBackSilent(i);
3293   return ret.retn();
3294 }
3295
3296 /*!
3297  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3298  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3299  * the number of component in the result array is same as that of each of given arrays.
3300  * Info on components is copied from the first of the given arrays. Number of components
3301  * in the given arrays must be  the same.
3302  *  \param [in] a1 - an array to include in the result array.
3303  *  \param [in] a2 - another array to include in the result array.
3304  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3305  *          The caller is to delete this result array using decrRef() as it is no more
3306  *          needed.
3307  *  \throw If both \a a1 and \a a2 are NULL.
3308  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3309  */
3310 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3311 {
3312   std::vector<const DataArrayDouble *> tmp(2);
3313   tmp[0]=a1; tmp[1]=a2;
3314   return Aggregate(tmp);
3315 }
3316
3317 /*!
3318  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3319  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3320  * the number of component in the result array is same as that of each of given arrays.
3321  * Info on components is copied from the first of the given arrays. Number of components
3322  * in the given arrays must be  the same.
3323  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3324  * not the object itself.
3325  *  \param [in] arr - a sequence of arrays to include in the result array.
3326  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3327  *          The caller is to delete this result array using decrRef() as it is no more
3328  *          needed.
3329  *  \throw If all arrays within \a arr are NULL.
3330  *  \throw If getNumberOfComponents() of arrays within \a arr.
3331  */
3332 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3333 {
3334   std::vector<const DataArrayDouble *> a;
3335   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3336     if(*it4)
3337       a.push_back(*it4);
3338   if(a.empty())
3339     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3340   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3341   int nbOfComp=(*it)->getNumberOfComponents();
3342   int nbt=(*it++)->getNumberOfTuples();
3343   for(int i=1;it!=a.end();it++,i++)
3344     {
3345       if((*it)->getNumberOfComponents()!=nbOfComp)
3346         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3347       nbt+=(*it)->getNumberOfTuples();
3348     }
3349   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3350   ret->alloc(nbt,nbOfComp);
3351   double *pt=ret->getPointer();
3352   for(it=a.begin();it!=a.end();it++)
3353     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3354   ret->copyStringInfoFrom(*(a[0]));
3355   return ret.retn();
3356 }
3357
3358 /*!
3359  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3360  * of components in the result array is a sum of the number of components of given arrays
3361  * and (2) the number of tuples in the result array is same as that of each of given
3362  * arrays. In other words the i-th tuple of result array includes all components of
3363  * i-th tuples of all given arrays.
3364  * Number of tuples in the given arrays must be  the same.
3365  *  \param [in] a1 - an array to include in the result array.
3366  *  \param [in] a2 - another array to include in the result array.
3367  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3368  *          The caller is to delete this result array using decrRef() as it is no more
3369  *          needed.
3370  *  \throw If both \a a1 and \a a2 are NULL.
3371  *  \throw If any given array is not allocated.
3372  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3373  */
3374 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3375 {
3376   std::vector<const DataArrayDouble *> arr(2);
3377   arr[0]=a1; arr[1]=a2;
3378   return Meld(arr);
3379 }
3380
3381 /*!
3382  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3383  * of components in the result array is a sum of the number of components of given arrays
3384  * and (2) the number of tuples in the result array is same as that of each of given
3385  * arrays. In other words the i-th tuple of result array includes all components of
3386  * i-th tuples of all given arrays.
3387  * Number of tuples in the given arrays must be  the same.
3388  *  \param [in] arr - a sequence of arrays to include in the result array.
3389  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3390  *          The caller is to delete this result array using decrRef() as it is no more
3391  *          needed.
3392  *  \throw If all arrays within \a arr are NULL.
3393  *  \throw If any given array is not allocated.
3394  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3395  */
3396 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3397 {
3398   std::vector<const DataArrayDouble *> a;
3399   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3400     if(*it4)
3401       a.push_back(*it4);
3402   if(a.empty())
3403     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3404   std::vector<const DataArrayDouble *>::const_iterator it;
3405   for(it=a.begin();it!=a.end();it++)
3406     (*it)->checkAllocated();
3407   it=a.begin();
3408   int nbOfTuples=(*it)->getNumberOfTuples();
3409   std::vector<int> nbc(a.size());
3410   std::vector<const double *> pts(a.size());
3411   nbc[0]=(*it)->getNumberOfComponents();
3412   pts[0]=(*it++)->getConstPointer();
3413   for(int i=1;it!=a.end();it++,i++)
3414     {
3415       if(nbOfTuples!=(*it)->getNumberOfTuples())
3416         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3417       nbc[i]=(*it)->getNumberOfComponents();
3418       pts[i]=(*it)->getConstPointer();
3419     }
3420   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3421   DataArrayDouble *ret=DataArrayDouble::New();
3422   ret->alloc(nbOfTuples,totalNbOfComp);
3423   double *retPtr=ret->getPointer();
3424   for(int i=0;i<nbOfTuples;i++)
3425     for(int j=0;j<(int)a.size();j++)
3426       {
3427         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3428         pts[j]+=nbc[j];
3429       }
3430   int k=0;
3431   for(int i=0;i<(int)a.size();i++)
3432     for(int j=0;j<nbc[i];j++,k++)
3433       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3434   return ret;
3435 }
3436
3437 /*!
3438  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3439  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3440  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3441  * Info on components and name is copied from the first of the given arrays.
3442  * Number of tuples and components in the given arrays must be the same.
3443  *  \param [in] a1 - a given array.
3444  *  \param [in] a2 - another given array.
3445  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3446  *          The caller is to delete this result array using decrRef() as it is no more
3447  *          needed.
3448  *  \throw If either \a a1 or \a a2 is NULL.
3449  *  \throw If any given array is not allocated.
3450  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3451  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3452  */
3453 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3454 {
3455   if(!a1 || !a2)
3456     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3457   a1->checkAllocated();
3458   a2->checkAllocated();
3459   int nbOfComp=a1->getNumberOfComponents();
3460   if(nbOfComp!=a2->getNumberOfComponents())
3461     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3462   int nbOfTuple=a1->getNumberOfTuples();
3463   if(nbOfTuple!=a2->getNumberOfTuples())
3464     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3465   DataArrayDouble *ret=DataArrayDouble::New();
3466   ret->alloc(nbOfTuple,1);
3467   double *retPtr=ret->getPointer();
3468   const double *a1Ptr=a1->getConstPointer();
3469   const double *a2Ptr=a2->getConstPointer();
3470   for(int i=0;i<nbOfTuple;i++)
3471     {
3472       double sum=0.;
3473       for(int j=0;j<nbOfComp;j++)
3474         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3475       retPtr[i]=sum;
3476     }
3477   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3478   ret->setName(a1->getName());
3479   return ret;
3480 }
3481
3482 /*!
3483  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3484  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3485  * product of two vectors defined by the i-th tuples of given arrays.
3486  * Info on components is copied from the first of the given arrays.
3487  * Number of tuples in the given arrays must be the same.
3488  * Number of components in the given arrays must be 3.
3489  *  \param [in] a1 - a given array.
3490  *  \param [in] a2 - another given array.
3491  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3492  *          The caller is to delete this result array using decrRef() as it is no more
3493  *          needed.
3494  *  \throw If either \a a1 or \a a2 is NULL.
3495  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3496  *  \throw If \a a1->getNumberOfComponents() != 3
3497  *  \throw If \a a2->getNumberOfComponents() != 3
3498  */
3499 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3500 {
3501   if(!a1 || !a2)
3502     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3503   int nbOfComp=a1->getNumberOfComponents();
3504   if(nbOfComp!=a2->getNumberOfComponents())
3505     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3506   if(nbOfComp!=3)
3507     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3508   int nbOfTuple=a1->getNumberOfTuples();
3509   if(nbOfTuple!=a2->getNumberOfTuples())
3510     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3511   DataArrayDouble *ret=DataArrayDouble::New();
3512   ret->alloc(nbOfTuple,3);
3513   double *retPtr=ret->getPointer();
3514   const double *a1Ptr=a1->getConstPointer();
3515   const double *a2Ptr=a2->getConstPointer();
3516   for(int i=0;i<nbOfTuple;i++)
3517     {
3518       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3519       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3520       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3521     }
3522   ret->copyStringInfoFrom(*a1);
3523   return ret;
3524 }
3525
3526 /*!
3527  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3528  * Info on components is copied from the first of the given arrays.
3529  * Number of tuples and components in the given arrays must be the same.
3530  *  \param [in] a1 - an array to compare values with another one.
3531  *  \param [in] a2 - another array to compare values with the first one.
3532  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3533  *          The caller is to delete this result array using decrRef() as it is no more
3534  *          needed.
3535  *  \throw If either \a a1 or \a a2 is NULL.
3536  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3537  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3538  */
3539 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3540 {
3541   if(!a1 || !a2)
3542     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3543   int nbOfComp=a1->getNumberOfComponents();
3544   if(nbOfComp!=a2->getNumberOfComponents())
3545     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3546   int nbOfTuple=a1->getNumberOfTuples();
3547   if(nbOfTuple!=a2->getNumberOfTuples())
3548     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3549   DataArrayDouble *ret=DataArrayDouble::New();
3550   ret->alloc(nbOfTuple,nbOfComp);
3551   double *retPtr=ret->getPointer();
3552   const double *a1Ptr=a1->getConstPointer();
3553   const double *a2Ptr=a2->getConstPointer();
3554   int nbElem=nbOfTuple*nbOfComp;
3555   for(int i=0;i<nbElem;i++)
3556     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3557   ret->copyStringInfoFrom(*a1);
3558   return ret;
3559 }
3560
3561 /*!
3562  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3563  * Info on components is copied from the first of the given arrays.
3564  * Number of tuples and components in the given arrays must be the same.
3565  *  \param [in] a1 - an array to compare values with another one.
3566  *  \param [in] a2 - another array to compare values with the first one.
3567  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3568  *          The caller is to delete this result array using decrRef() as it is no more
3569  *          needed.
3570  *  \throw If either \a a1 or \a a2 is NULL.
3571  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3572  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3573  */
3574 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3575 {
3576   if(!a1 || !a2)
3577     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3578   int nbOfComp=a1->getNumberOfComponents();
3579   if(nbOfComp!=a2->getNumberOfComponents())
3580     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3581   int nbOfTuple=a1->getNumberOfTuples();
3582   if(nbOfTuple!=a2->getNumberOfTuples())
3583     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3584   DataArrayDouble *ret=DataArrayDouble::New();
3585   ret->alloc(nbOfTuple,nbOfComp);
3586   double *retPtr=ret->getPointer();
3587   const double *a1Ptr=a1->getConstPointer();
3588   const double *a2Ptr=a2->getConstPointer();
3589   int nbElem=nbOfTuple*nbOfComp;
3590   for(int i=0;i<nbElem;i++)
3591     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3592   ret->copyStringInfoFrom(*a1);
3593   return ret;
3594 }
3595
3596 /*!
3597  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3598  * valid cases.
3599  * 1.  The arrays have same number of tuples and components. Then each value of
3600  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3601  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3602  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3603  *   component. Then
3604  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3605  * 3.  The arrays have same number of components and one array, say _a2_, has one
3606  *   tuple. Then
3607  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3608  *
3609  * Info on components is copied either from the first array (in the first case) or from
3610  * the array with maximal number of elements (getNbOfElems()).
3611  *  \param [in] a1 - an array to sum up.
3612  *  \param [in] a2 - another array to sum up.
3613  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3614  *          The caller is to delete this result array using decrRef() as it is no more
3615  *          needed.
3616  *  \throw If either \a a1 or \a a2 is NULL.
3617  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3618  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3619  *         none of them has number of tuples or components equal to 1.
3620  */
3621 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3622 {
3623   if(!a1 || !a2)
3624     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3625   int nbOfTuple=a1->getNumberOfTuples();
3626   int nbOfTuple2=a2->getNumberOfTuples();
3627   int nbOfComp=a1->getNumberOfComponents();
3628   int nbOfComp2=a2->getNumberOfComponents();
3629   MCAuto<DataArrayDouble> ret=0;
3630   if(nbOfTuple==nbOfTuple2)
3631     {
3632       if(nbOfComp==nbOfComp2)
3633         {
3634           ret=DataArrayDouble::New();
3635           ret->alloc(nbOfTuple,nbOfComp);
3636           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3637           ret->copyStringInfoFrom(*a1);
3638         }
3639       else
3640         {
3641           int nbOfCompMin,nbOfCompMax;
3642           const DataArrayDouble *aMin, *aMax;
3643           if(nbOfComp>nbOfComp2)
3644             {
3645               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3646               aMin=a2; aMax=a1;
3647             }
3648           else
3649             {
3650               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3651               aMin=a1; aMax=a2;
3652             }
3653           if(nbOfCompMin==1)
3654             {
3655               ret=DataArrayDouble::New();
3656               ret->alloc(nbOfTuple,nbOfCompMax);
3657               const double *aMinPtr=aMin->getConstPointer();
3658               const double *aMaxPtr=aMax->getConstPointer();
3659               double *res=ret->getPointer();
3660               for(int i=0;i<nbOfTuple;i++)
3661                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3662               ret->copyStringInfoFrom(*aMax);
3663             }
3664           else
3665             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3666         }
3667     }
3668   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3669     {
3670       if(nbOfComp==nbOfComp2)
3671         {
3672           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3673           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3674           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3675           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3676           ret=DataArrayDouble::New();
3677           ret->alloc(nbOfTupleMax,nbOfComp);
3678           double *res=ret->getPointer();
3679           for(int i=0;i<nbOfTupleMax;i++)
3680             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3681           ret->copyStringInfoFrom(*aMax);
3682         }
3683       else
3684         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3685     }
3686   else
3687     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3688   return ret.retn();
3689 }
3690
3691 /*!
3692  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3693  * valid cases.
3694  * 1.  The arrays have same number of tuples and components. Then each value of
3695  *   \a other array is added to the corresponding value of \a this array, i.e.:
3696  *   _a_ [ i, j ] += _other_ [ i, j ].
3697  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3698  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3699  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3700  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3701  *
3702  *  \param [in] other - an array to add to \a this one.
3703  *  \throw If \a other is NULL.
3704  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3705  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3706  *         \a other has number of both tuples and components not equal to 1.
3707  */
3708 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3709 {
3710   if(!other)
3711     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3712   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3713   checkAllocated();
3714   other->checkAllocated();
3715   int nbOfTuple=getNumberOfTuples();
3716   int nbOfTuple2=other->getNumberOfTuples();
3717   int nbOfComp=getNumberOfComponents();
3718   int nbOfComp2=other->getNumberOfComponents();
3719   if(nbOfTuple==nbOfTuple2)
3720     {
3721       if(nbOfComp==nbOfComp2)
3722         {
3723           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3724         }
3725       else if(nbOfComp2==1)
3726         {
3727           double *ptr=getPointer();
3728           const double *ptrc=other->getConstPointer();
3729           for(int i=0;i<nbOfTuple;i++)
3730             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3731         }
3732       else
3733         throw INTERP_KERNEL::Exception(msg);
3734     }
3735   else if(nbOfTuple2==1)
3736     {
3737       if(nbOfComp2==nbOfComp)
3738         {
3739           double *ptr=getPointer();
3740           const double *ptrc=other->getConstPointer();
3741           for(int i=0;i<nbOfTuple;i++)
3742             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3743         }
3744       else
3745         throw INTERP_KERNEL::Exception(msg);
3746     }
3747   else
3748     throw INTERP_KERNEL::Exception(msg);
3749   declareAsNew();
3750 }
3751
3752 /*!
3753  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3754  * valid cases.
3755  * 1.  The arrays have same number of tuples and components. Then each value of
3756  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3757  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3758  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3759  *   component. Then
3760  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3761  * 3.  The arrays have same number of components and one array, say _a2_, has one
3762  *   tuple. Then
3763  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3764  *
3765  * Info on components is copied either from the first array (in the first case) or from
3766  * the array with maximal number of elements (getNbOfElems()).
3767  *  \param [in] a1 - an array to subtract from.
3768  *  \param [in] a2 - an array to subtract.
3769  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3770  *          The caller is to delete this result array using decrRef() as it is no more
3771  *          needed.
3772  *  \throw If either \a a1 or \a a2 is NULL.
3773  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3774  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3775  *         none of them has number of tuples or components equal to 1.
3776  */
3777 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3778 {
3779   if(!a1 || !a2)
3780     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3781   int nbOfTuple1=a1->getNumberOfTuples();
3782   int nbOfTuple2=a2->getNumberOfTuples();
3783   int nbOfComp1=a1->getNumberOfComponents();
3784   int nbOfComp2=a2->getNumberOfComponents();
3785   if(nbOfTuple2==nbOfTuple1)
3786     {
3787       if(nbOfComp1==nbOfComp2)
3788         {
3789           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3790           ret->alloc(nbOfTuple2,nbOfComp1);
3791           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3792           ret->copyStringInfoFrom(*a1);
3793           return ret.retn();
3794         }
3795       else if(nbOfComp2==1)
3796         {
3797           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3798           ret->alloc(nbOfTuple1,nbOfComp1);
3799           const double *a2Ptr=a2->getConstPointer();
3800           const double *a1Ptr=a1->getConstPointer();
3801           double *res=ret->getPointer();
3802           for(int i=0;i<nbOfTuple1;i++)
3803             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3804           ret->copyStringInfoFrom(*a1);
3805           return ret.retn();
3806         }
3807       else
3808         {
3809           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3810           return 0;
3811         }
3812     }
3813   else if(nbOfTuple2==1)
3814     {
3815       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3816       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3817       ret->alloc(nbOfTuple1,nbOfComp1);
3818       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3819       double *pt=ret->getPointer();
3820       for(int i=0;i<nbOfTuple1;i++)
3821         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3822       ret->copyStringInfoFrom(*a1);
3823       return ret.retn();
3824     }
3825   else
3826     {
3827       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3828       return 0;
3829     }
3830 }
3831
3832 /*!
3833  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3834  * valid cases.
3835  * 1.  The arrays have same number of tuples and components. Then each value of
3836  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3837  *   _a_ [ i, j ] -= _other_ [ i, j ].
3838  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3839  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3840  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3841  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3842  *
3843  *  \param [in] other - an array to subtract from \a this one.
3844  *  \throw If \a other is NULL.
3845  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3846  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3847  *         \a other has number of both tuples and components not equal to 1.
3848  */
3849 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3850 {
3851   if(!other)
3852     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3853   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3854   checkAllocated();
3855   other->checkAllocated();
3856   int nbOfTuple=getNumberOfTuples();
3857   int nbOfTuple2=other->getNumberOfTuples();
3858   int nbOfComp=getNumberOfComponents();
3859   int nbOfComp2=other->getNumberOfComponents();
3860   if(nbOfTuple==nbOfTuple2)
3861     {
3862       if(nbOfComp==nbOfComp2)
3863         {
3864           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3865         }
3866       else if(nbOfComp2==1)
3867         {
3868           double *ptr=getPointer();
3869           const double *ptrc=other->getConstPointer();
3870           for(int i=0;i<nbOfTuple;i++)
3871             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3872         }
3873       else
3874         throw INTERP_KERNEL::Exception(msg);
3875     }
3876   else if(nbOfTuple2==1)
3877     {
3878       if(nbOfComp2==nbOfComp)
3879         {
3880           double *ptr=getPointer();
3881           const double *ptrc=other->getConstPointer();
3882           for(int i=0;i<nbOfTuple;i++)
3883             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3884         }
3885       else
3886         throw INTERP_KERNEL::Exception(msg);
3887     }
3888   else
3889     throw INTERP_KERNEL::Exception(msg);
3890   declareAsNew();
3891 }
3892
3893 /*!
3894  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3895  * valid cases.
3896  * 1.  The arrays have same number of tuples and components. Then each value of
3897  *   the result array (_a_) is a product of the corresponding values of \a a1 and
3898  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3899  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3900  *   component. Then
3901  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3902  * 3.  The arrays have same number of components and one array, say _a2_, has one
3903  *   tuple. Then
3904  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3905  *
3906  * Info on components is copied either from the first array (in the first case) or from
3907  * the array with maximal number of elements (getNbOfElems()).
3908  *  \param [in] a1 - a factor array.
3909  *  \param [in] a2 - another factor array.
3910  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3911  *          The caller is to delete this result array using decrRef() as it is no more
3912  *          needed.
3913  *  \throw If either \a a1 or \a a2 is NULL.
3914  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3915  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3916  *         none of them has number of tuples or components equal to 1.
3917  */
3918 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
3919 {
3920   if(!a1 || !a2)
3921     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
3922   int nbOfTuple=a1->getNumberOfTuples();
3923   int nbOfTuple2=a2->getNumberOfTuples();
3924   int nbOfComp=a1->getNumberOfComponents();
3925   int nbOfComp2=a2->getNumberOfComponents();
3926   MCAuto<DataArrayDouble> ret=0;
3927   if(nbOfTuple==nbOfTuple2)
3928     {
3929       if(nbOfComp==nbOfComp2)
3930         {
3931           ret=DataArrayDouble::New();
3932           ret->alloc(nbOfTuple,nbOfComp);
3933           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
3934           ret->copyStringInfoFrom(*a1);
3935         }
3936       else
3937         {
3938           int nbOfCompMin,nbOfCompMax;
3939           const DataArrayDouble *aMin, *aMax;
3940           if(nbOfComp>nbOfComp2)
3941             {
3942               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3943               aMin=a2; aMax=a1;
3944             }
3945           else
3946             {
3947               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3948               aMin=a1; aMax=a2;
3949             }
3950           if(nbOfCompMin==1)
3951             {
3952               ret=DataArrayDouble::New();
3953               ret->alloc(nbOfTuple,nbOfCompMax);
3954               const double *aMinPtr=aMin->getConstPointer();
3955               const double *aMaxPtr=aMax->getConstPointer();
3956               double *res=ret->getPointer();
3957               for(int i=0;i<nbOfTuple;i++)
3958                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
3959               ret->copyStringInfoFrom(*aMax);
3960             }
3961           else
3962             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
3963         }
3964     }
3965   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3966     {
3967       if(nbOfComp==nbOfComp2)
3968         {
3969           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3970           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3971           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3972           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3973           ret=DataArrayDouble::New();
3974           ret->alloc(nbOfTupleMax,nbOfComp);
3975           double *res=ret->getPointer();
3976           for(int i=0;i<nbOfTupleMax;i++)
3977             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
3978           ret->copyStringInfoFrom(*aMax);
3979         }
3980       else
3981         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
3982     }
3983   else
3984     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
3985   return ret.retn();
3986 }
3987
3988 /*!
3989  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
3990  * valid cases.
3991  * 1.  The arrays have same number of tuples and components. Then each value of
3992  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
3993  *   _this_ [ i, j ] *= _other_ [ i, j ].
3994  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3995  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
3996  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3997  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
3998  *
3999  *  \param [in] other - an array to multiply to \a this one.
4000  *  \throw If \a other is NULL.
4001  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4002  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4003  *         \a other has number of both tuples and components not equal to 1.
4004  */
4005 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4006 {
4007   if(!other)
4008     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4009   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4010   checkAllocated();
4011   other->checkAllocated();
4012   int nbOfTuple=getNumberOfTuples();
4013   int nbOfTuple2=other->getNumberOfTuples();
4014   int nbOfComp=getNumberOfComponents();
4015   int nbOfComp2=other->getNumberOfComponents();
4016   if(nbOfTuple==nbOfTuple2)
4017     {
4018       if(nbOfComp==nbOfComp2)
4019         {
4020           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4021         }
4022       else if(nbOfComp2==1)
4023         {
4024           double *ptr=getPointer();
4025           const double *ptrc=other->getConstPointer();
4026           for(int i=0;i<nbOfTuple;i++)
4027             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4028         }
4029       else
4030         throw INTERP_KERNEL::Exception(msg);
4031     }
4032   else if(nbOfTuple2==1)
4033     {
4034       if(nbOfComp2==nbOfComp)
4035         {
4036           double *ptr=getPointer();
4037           const double *ptrc=other->getConstPointer();
4038           for(int i=0;i<nbOfTuple;i++)
4039             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4040         }
4041       else
4042         throw INTERP_KERNEL::Exception(msg);
4043     }
4044   else
4045     throw INTERP_KERNEL::Exception(msg);
4046   declareAsNew();
4047 }
4048
4049 /*!
4050  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4051  * valid cases.
4052  * 1.  The arrays have same number of tuples and components. Then each value of
4053  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4054  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4055  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4056  *   component. Then
4057  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4058  * 3.  The arrays have same number of components and one array, say _a2_, has one
4059  *   tuple. Then
4060  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4061  *
4062  * Info on components is copied either from the first array (in the first case) or from
4063  * the array with maximal number of elements (getNbOfElems()).
4064  *  \warning No check of division by zero is performed!
4065  *  \param [in] a1 - a numerator array.
4066  *  \param [in] a2 - a denominator array.
4067  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4068  *          The caller is to delete this result array using decrRef() as it is no more
4069  *          needed.
4070  *  \throw If either \a a1 or \a a2 is NULL.
4071  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4072  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4073  *         none of them has number of tuples or components equal to 1.
4074  */
4075 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4076 {
4077   if(!a1 || !a2)
4078     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4079   int nbOfTuple1=a1->getNumberOfTuples();
4080   int nbOfTuple2=a2->getNumberOfTuples();
4081   int nbOfComp1=a1->getNumberOfComponents();
4082   int nbOfComp2=a2->getNumberOfComponents();
4083   if(nbOfTuple2==nbOfTuple1)
4084     {
4085       if(nbOfComp1==nbOfComp2)
4086         {
4087           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4088           ret->alloc(nbOfTuple2,nbOfComp1);
4089           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4090           ret->copyStringInfoFrom(*a1);
4091           return ret.retn();
4092         }
4093       else if(nbOfComp2==1)
4094         {
4095           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4096           ret->alloc(nbOfTuple1,nbOfComp1);
4097           const double *a2Ptr=a2->getConstPointer();
4098           const double *a1Ptr=a1->getConstPointer();
4099           double *res=ret->getPointer();
4100           for(int i=0;i<nbOfTuple1;i++)
4101             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4102           ret->copyStringInfoFrom(*a1);
4103           return ret.retn();
4104         }
4105       else
4106         {
4107           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4108           return 0;
4109         }
4110     }
4111   else if(nbOfTuple2==1)
4112     {
4113       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4114       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4115       ret->alloc(nbOfTuple1,nbOfComp1);
4116       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4117       double *pt=ret->getPointer();
4118       for(int i=0;i<nbOfTuple1;i++)
4119         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4120       ret->copyStringInfoFrom(*a1);
4121       return ret.retn();
4122     }
4123   else
4124     {
4125       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4126       return 0;
4127     }
4128 }
4129
4130 /*!
4131  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4132  * valid cases.
4133  * 1.  The arrays have same number of tuples and components. Then each value of
4134  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4135  *   _a_ [ i, j ] /= _other_ [ i, j ].
4136  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4137  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4138  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4139  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4140  *
4141  *  \warning No check of division by zero is performed!
4142  *  \param [in] other - an array to divide \a this one by.
4143  *  \throw If \a other is NULL.
4144  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4145  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4146  *         \a other has number of both tuples and components not equal to 1.
4147  */
4148 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4149 {
4150   if(!other)
4151     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4152   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4153   checkAllocated();
4154   other->checkAllocated();
4155   int nbOfTuple=getNumberOfTuples();
4156   int nbOfTuple2=other->getNumberOfTuples();
4157   int nbOfComp=getNumberOfComponents();
4158   int nbOfComp2=other->getNumberOfComponents();
4159   if(nbOfTuple==nbOfTuple2)
4160     {
4161       if(nbOfComp==nbOfComp2)
4162         {
4163           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4164         }
4165       else if(nbOfComp2==1)
4166         {
4167           double *ptr=getPointer();
4168           const double *ptrc=other->getConstPointer();
4169           for(int i=0;i<nbOfTuple;i++)
4170             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4171         }
4172       else
4173         throw INTERP_KERNEL::Exception(msg);
4174     }
4175   else if(nbOfTuple2==1)
4176     {
4177       if(nbOfComp2==nbOfComp)
4178         {
4179           double *ptr=getPointer();
4180           const double *ptrc=other->getConstPointer();
4181           for(int i=0;i<nbOfTuple;i++)
4182             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4183         }
4184       else
4185         throw INTERP_KERNEL::Exception(msg);
4186     }
4187   else
4188     throw INTERP_KERNEL::Exception(msg);
4189   declareAsNew();
4190 }
4191
4192 /*!
4193  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4194  * valid cases.
4195  *
4196  *  \param [in] a1 - an array to pow up.
4197  *  \param [in] a2 - another array to sum up.
4198  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4199  *          The caller is to delete this result array using decrRef() as it is no more
4200  *          needed.
4201  *  \throw If either \a a1 or \a a2 is NULL.
4202  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4203  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4204  *  \throw If there is a negative value in \a a1.
4205  */
4206 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4207 {
4208   if(!a1 || !a2)
4209     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4210   int nbOfTuple=a1->getNumberOfTuples();
4211   int nbOfTuple2=a2->getNumberOfTuples();
4212   int nbOfComp=a1->getNumberOfComponents();
4213   int nbOfComp2=a2->getNumberOfComponents();
4214   if(nbOfTuple!=nbOfTuple2)
4215     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4216   if(nbOfComp!=1 || nbOfComp2!=1)
4217     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4218   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4219   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4220   double *ptr=ret->getPointer();
4221   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4222     {
4223       if(*ptr1>=0)
4224         {
4225           *ptr=pow(*ptr1,*ptr2);
4226         }
4227       else
4228         {
4229           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4230           throw INTERP_KERNEL::Exception(oss.str().c_str());
4231         }
4232     }
4233   return ret.retn();
4234 }
4235
4236 /*!
4237  * Apply pow on values of another DataArrayDouble to values of \a this one.
4238  *
4239  *  \param [in] other - an array to pow to \a this one.
4240  *  \throw If \a other is NULL.
4241  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4242  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4243  *  \throw If there is a negative value in \a this.
4244  */
4245 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4246 {
4247   if(!other)
4248     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4249   int nbOfTuple=getNumberOfTuples();
4250   int nbOfTuple2=other->getNumberOfTuples();
4251   int nbOfComp=getNumberOfComponents();
4252   int nbOfComp2=other->getNumberOfComponents();
4253   if(nbOfTuple!=nbOfTuple2)
4254     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4255   if(nbOfComp!=1 || nbOfComp2!=1)
4256     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4257   double *ptr=getPointer();
4258   const double *ptrc=other->begin();
4259   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4260     {
4261       if(*ptr>=0)
4262         *ptr=pow(*ptr,*ptrc);
4263       else
4264         {
4265           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4266           throw INTERP_KERNEL::Exception(oss.str().c_str());
4267         }
4268     }
4269   declareAsNew();
4270 }
4271
4272 /*!
4273  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4274  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4275  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4276  *
4277  * \throw if \a this is not allocated.
4278  * \throw if \a this has not exactly one component.
4279  */
4280 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4281 {
4282   checkAllocated();
4283   if(getNumberOfComponents()!=1)
4284     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4285   int nbt(getNumberOfTuples());
4286   std::vector<bool> ret(nbt);
4287   const double *pt(begin());
4288   for(int i=0;i<nbt;i++)
4289     {
4290       if(fabs(pt[i])<eps)
4291         ret[i]=false;
4292       else if(fabs(pt[i]-1.)<eps)
4293         ret[i]=true;
4294       else
4295         {
4296           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4297           throw INTERP_KERNEL::Exception(oss.str().c_str());
4298         }
4299     }
4300   return ret;
4301 }
4302
4303 /*!
4304  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4305  * Server side.
4306  */
4307 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4308 {
4309   tinyInfo.resize(2);
4310   if(isAllocated())
4311     {
4312       tinyInfo[0]=getNumberOfTuples();
4313       tinyInfo[1]=getNumberOfComponents();
4314     }
4315   else
4316     {
4317       tinyInfo[0]=-1;
4318       tinyInfo[1]=-1;
4319     }
4320 }
4321
4322 /*!
4323  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4324  * Server side.
4325  */
4326 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4327 {
4328   if(isAllocated())
4329     {
4330       int nbOfCompo=getNumberOfComponents();
4331       tinyInfo.resize(nbOfCompo+1);
4332       tinyInfo[0]=getName();
4333       for(int i=0;i<nbOfCompo;i++)
4334         tinyInfo[i+1]=getInfoOnComponent(i);
4335     }
4336   else
4337     {
4338       tinyInfo.resize(1);
4339       tinyInfo[0]=getName();
4340     }
4341 }
4342
4343 /*!
4344  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4345  * This method returns if a feeding is needed.
4346  */
4347 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4348 {
4349   int nbOfTuple=tinyInfoI[0];
4350   int nbOfComp=tinyInfoI[1];
4351   if(nbOfTuple!=-1 || nbOfComp!=-1)
4352     {
4353       alloc(nbOfTuple,nbOfComp);
4354       return true;
4355     }
4356   return false;
4357 }
4358
4359 /*!
4360  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4361  */
4362 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4363 {
4364   setName(tinyInfoS[0]);
4365   if(isAllocated())
4366     {
4367       int nbOfCompo=getNumberOfComponents();
4368       for(int i=0;i<nbOfCompo;i++)
4369         setInfoOnComponent(i,tinyInfoS[i+1]);
4370     }
4371 }
4372
4373 /*!
4374  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4375  * around an axe ( \a center, \a vect) and with angle \a angle.
4376  */
4377 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4378 {
4379   if(!center || !vect)
4380     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4381   double sina(sin(angle));
4382   double cosa(cos(angle));
4383   double vectorNorm[3];
4384   double matrix[9];
4385   double matrixTmp[9];
4386   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4387   if(norm<std::numeric_limits<double>::min())
4388     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4389   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4390   //rotation matrix computation
4391   matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa;
4392   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4393   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4394   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4395   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4396   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4397   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4398   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4399   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4400   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4401   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4402   //rotation matrix computed.
4403   double tmp[3];
4404   for(int i=0; i<nbNodes; i++)
4405     {
4406       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4407       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4408       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4409       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4410     }
4411 }
4412
4413 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4414 {
4415   double matrix[9],matrix2[9],matrix3[9];
4416   double vect[3],crossVect[3];
4417   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4418   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4419   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4420   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4421   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4422   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4423   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4424   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4425   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4426   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4427   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4428   for(int i=0;i<3;i++)
4429     for(int j=0;j<3;j++)
4430       {
4431         double val(0.);
4432         for(int k=0;k<3;k++)
4433           val+=matrix[3*i+k]*matrix2[3*k+j];
4434         matrix3[3*i+j]=val;
4435       }
4436   //rotation matrix computed.
4437   double tmp[3];
4438   for(int i=0; i<nbNodes; i++)
4439     {
4440       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4441       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4442       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4443       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4444     }
4445 }
4446
4447 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4448 {
4449   double vect[3],crossVect[3];
4450   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4451   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4452   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4453   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4454   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4455   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4456   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4457   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4458 }
4459
4460 /*!
4461  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4462  * around the center point \a center and with angle \a angle.
4463  */
4464 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4465 {
4466   double cosa=cos(angle);
4467   double sina=sin(angle);
4468   double matrix[4];
4469   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4470   double tmp[2];
4471   for(int i=0; i<nbNodes; i++)
4472     {
4473       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4474       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4475       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4476     }
4477 }
4478
4479 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4480 {
4481   if(_da)
4482     {
4483       _da->incrRef();
4484       if(_da->isAllocated())
4485         {
4486           _nb_comp=da->getNumberOfComponents();
4487           _nb_tuple=da->getNumberOfTuples();
4488           _pt=da->getPointer();
4489         }
4490     }
4491 }
4492
4493 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4494 {
4495   if(_da)
4496     _da->decrRef();
4497 }
4498
4499 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4500 {
4501   if(_tuple_id<_nb_tuple)
4502     {
4503       _tuple_id++;
4504       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4505       _pt+=_nb_comp;
4506       return ret;
4507     }
4508   else
4509     return 0;
4510 }
4511
4512 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4513 {
4514 }
4515
4516
4517 std::string DataArrayDoubleTuple::repr() const
4518 {
4519   std::ostringstream oss; oss.precision(17); oss << "(";
4520   for(int i=0;i<_nb_of_compo-1;i++)
4521     oss << _pt[i] << ", ";
4522   oss << _pt[_nb_of_compo-1] << ")";
4523   return oss.str();
4524 }
4525
4526 double DataArrayDoubleTuple::doubleValue() const
4527 {
4528   if(_nb_of_compo==1)
4529     return *_pt;
4530   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4531 }
4532
4533 /*!
4534  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4535  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4536  * 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
4537  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4538  */
4539 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4540 {
4541   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4542     {
4543       DataArrayDouble *ret=DataArrayDouble::New();
4544       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4545       return ret;
4546     }
4547   else
4548     {
4549       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4550       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4551       throw INTERP_KERNEL::Exception(oss.str().c_str());
4552     }
4553 }
4554
4555 /*!
4556  * Returns a new instance of DataArrayInt. The caller is to delete this array
4557  * using decrRef() as it is no more needed. 
4558  */
4559 DataArrayInt *DataArrayInt::New()
4560 {
4561   return new DataArrayInt;
4562 }
4563
4564 /*!
4565  * Returns the only one value in \a this, if and only if number of elements
4566  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4567  *  \return double - the sole value stored in \a this array.
4568  *  \throw If at least one of conditions stated above is not fulfilled.
4569  */
4570 int DataArrayInt::intValue() const
4571 {
4572   if(isAllocated())
4573     {
4574       if(getNbOfElems()==1)
4575         {
4576           return *getConstPointer();
4577         }
4578       else
4579         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4580     }
4581   else
4582     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4583 }
4584
4585 /*!
4586  * Returns an integer value characterizing \a this array, which is useful for a quick
4587  * comparison of many instances of DataArrayInt.
4588  *  \return int - the hash value.
4589  *  \throw If \a this is not allocated.
4590  */
4591 int DataArrayInt::getHashCode() const
4592 {
4593   checkAllocated();
4594   std::size_t nbOfElems=getNbOfElems();
4595   int ret=nbOfElems*65536;
4596   int delta=3;
4597   if(nbOfElems>48)
4598     delta=nbOfElems/8;
4599   int ret0=0;
4600   const int *pt=begin();
4601   for(std::size_t i=0;i<nbOfElems;i+=delta)
4602     ret0+=pt[i] & 0x1FFF;
4603   return ret+ret0;
4604 }
4605
4606 /*!
4607  * Returns a full copy of \a this. For more info on copying data arrays see
4608  * \ref MEDCouplingArrayBasicsCopyDeep.
4609  *  \return DataArrayInt * - a new instance of DataArrayInt.
4610  */
4611 DataArrayInt *DataArrayInt::deepCopy() const
4612 {
4613   return new DataArrayInt(*this);
4614 }
4615
4616 /*!
4617  * Returns either a \a deep or \a shallow copy of this array. For more info see
4618  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4619  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4620  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4621  *          == \a true) or \a this instance (if \a dCpy == \a false).
4622  */
4623 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4624 {
4625   if(dCpy)
4626     return deepCopy();
4627   else
4628     {
4629       incrRef();
4630       return const_cast<DataArrayInt *>(this);
4631     }
4632 }
4633
4634 /*!
4635  * Assign zero to all values in \a this array. To know more on filling arrays see
4636  * \ref MEDCouplingArrayFill.
4637  * \throw If \a this is not allocated.
4638  */
4639 void DataArrayInt::fillWithZero()
4640 {
4641   fillWithValue(0);
4642 }
4643
4644 /*!
4645  * Set all values in \a this array so that the i-th element equals to \a init + i
4646  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4647  *  \param [in] init - value to assign to the first element of array.
4648  *  \throw If \a this->getNumberOfComponents() != 1
4649  *  \throw If \a this is not allocated.
4650  */
4651 void DataArrayInt::iota(int init)
4652 {
4653   checkAllocated();
4654   if(getNumberOfComponents()!=1)
4655     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4656   int *ptr=getPointer();
4657   int ntuples=getNumberOfTuples();
4658   for(int i=0;i<ntuples;i++)
4659     ptr[i]=init+i;
4660   declareAsNew();
4661 }
4662
4663 /*!
4664  * Returns a textual and human readable representation of \a this instance of
4665  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4666  * \return std::string - text describing \a this DataArrayInt.
4667  * 
4668  * \sa reprNotTooLong, reprZip
4669  */
4670 std::string DataArrayInt::repr() const
4671 {
4672   std::ostringstream ret;
4673   reprStream(ret);
4674   return ret.str();
4675 }
4676
4677 std::string DataArrayInt::reprZip() const
4678 {
4679   std::ostringstream ret;
4680   reprZipStream(ret);
4681   return ret.str();
4682 }
4683
4684 /*!
4685  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4686  * printed out to avoid to consume too much space in interpretor.
4687  * \sa repr
4688  */
4689 std::string DataArrayInt::reprNotTooLong() const
4690 {
4691   std::ostringstream ret;
4692   reprNotTooLongStream(ret);
4693   return ret.str();
4694 }
4695
4696 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4697 {
4698   static const char SPACE[4]={' ',' ',' ',' '};
4699   checkAllocated();
4700   std::string idt(indent,' ');
4701   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4702   if(byteArr)
4703     {
4704       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4705       if(std::string(type)=="Int32")
4706         {
4707           const char *data(reinterpret_cast<const char *>(begin()));
4708           std::size_t sz(getNbOfElems()*sizeof(int));
4709           byteArr->insertAtTheEnd(data,data+sz);
4710           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4711         }
4712       else if(std::string(type)=="Int8")
4713         {
4714           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4715           std::copy(begin(),end(),(char *)tmp);
4716           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4717           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4718         }
4719       else if(std::string(type)=="UInt8")
4720         {
4721           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4722           std::copy(begin(),end(),(unsigned char *)tmp);
4723           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4724           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4725         }
4726       else
4727         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4728     }
4729   else
4730     {
4731       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4732       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4733     }
4734   ofs << std::endl << idt << "</DataArray>\n";
4735 }
4736
4737 void DataArrayInt::reprStream(std::ostream& stream) const
4738 {
4739   stream << "Name of int array : \"" << _name << "\"\n";
4740   reprWithoutNameStream(stream);
4741 }
4742
4743 void DataArrayInt::reprZipStream(std::ostream& stream) const
4744 {
4745   stream << "Name of int array : \"" << _name << "\"\n";
4746   reprZipWithoutNameStream(stream);
4747 }
4748
4749 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4750 {
4751   stream << "Name of int array : \"" << _name << "\"\n";
4752   reprNotTooLongWithoutNameStream(stream);
4753 }
4754
4755 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4756 {
4757   DataArray::reprWithoutNameStream(stream);
4758   _mem.repr(getNumberOfComponents(),stream);
4759 }
4760
4761 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4762 {
4763   DataArray::reprWithoutNameStream(stream);
4764   _mem.reprZip(getNumberOfComponents(),stream);
4765 }
4766
4767 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4768 {
4769   DataArray::reprWithoutNameStream(stream);
4770   stream.precision(17);
4771   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4772 }
4773
4774 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4775 {
4776   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4777   const int *data=getConstPointer();
4778   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4779   if(nbTuples*nbComp>=1)
4780     {
4781       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4782       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4783       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4784       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4785     }
4786   else
4787     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4788   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4789 }
4790
4791 /*!
4792  * Method that gives a quick overvien of \a this for python.
4793  */
4794 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4795 {
4796   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4797   stream << "DataArrayInt C++ instance at " << this << ". ";
4798   if(isAllocated())
4799     {
4800       int nbOfCompo=(int)_info_on_compo.size();
4801       if(nbOfCompo>=1)
4802         {
4803           int nbOfTuples=getNumberOfTuples();
4804           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4805           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4806         }
4807       else
4808         stream << "Number of components : 0.";
4809     }
4810   else
4811     stream << "*** No data allocated ****";
4812 }
4813
4814 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4815 {
4816   const int *data=begin();
4817   int nbOfTuples=getNumberOfTuples();
4818   int nbOfCompo=(int)_info_on_compo.size();
4819   std::ostringstream oss2; oss2 << "[";
4820   std::string oss2Str(oss2.str());
4821   bool isFinished=true;
4822   for(int i=0;i<nbOfTuples && isFinished;i++)
4823     {
4824       if(nbOfCompo>1)
4825         {
4826           oss2 << "(";
4827           for(int j=0;j<nbOfCompo;j++,data++)
4828             {
4829               oss2 << *data;
4830               if(j!=nbOfCompo-1) oss2 << ", ";
4831             }
4832           oss2 << ")";
4833         }
4834       else
4835         oss2 << *data++;
4836       if(i!=nbOfTuples-1) oss2 << ", ";
4837       std::string oss3Str(oss2.str());
4838       if(oss3Str.length()<maxNbOfByteInRepr)
4839         oss2Str=oss3Str;
4840       else
4841         isFinished=false;
4842     }
4843   stream << oss2Str;
4844   if(!isFinished)
4845     stream << "... ";
4846   stream << "]";
4847 }
4848
4849 /*!
4850  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4851  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4852  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4853  *         to \a this array.
4854  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4855  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4856  *  \throw If \a this->getNumberOfComponents() != 1
4857  *  \throw If any value of \a this can't be used as a valid index for 
4858  *         [\a indArrBg, \a indArrEnd).
4859  *
4860  *  \sa changeValue
4861  */
4862 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4863 {
4864   checkAllocated();
4865   if(getNumberOfComponents()!=1)
4866     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4867   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4868   for(int i=0;i<nbOfTuples;i++,pt++)
4869     {
4870       if(*pt>=0 && *pt<nbElemsIn)
4871         *pt=indArrBg[*pt];
4872       else
4873         {
4874           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4875           throw INTERP_KERNEL::Exception(oss.str().c_str());
4876         }
4877     }
4878   declareAsNew();
4879 }
4880
4881 /*!
4882  * Computes distribution of values of \a this one-dimensional array between given value
4883  * ranges (casts). This method is typically useful for entity number spliting by types,
4884  * for example. 
4885  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4886  *           check of this is be done. If not, the result is not warranted. 
4887  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4888  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4889  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4890  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4891  *         should be more than every value in \a this array.
4892  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4893  *              the last value of \a arrBg is \a arrEnd[ -1 ].
4894  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4895  *         (same number of tuples and components), the caller is to delete 
4896  *         using decrRef() as it is no more needed.
4897  *         This array contains indices of ranges for every value of \a this array. I.e.
4898  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
4899  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
4900  *         this in which cast it holds.
4901  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4902  *         array, the caller is to delete using decrRef() as it is no more needed.
4903  *         This array contains ranks of values of \a this array within ranges
4904  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4905  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4906  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
4907  *         for each tuple its rank inside its cast. The rank is computed as difference
4908  *         between the value and the lowest value of range.
4909  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4910  *         ranges (casts) to which at least one value of \a this array belongs.
4911  *         Or, in other words, this param contains the casts that \a this contains.
4912  *         The caller is to delete this array using decrRef() as it is no more needed.
4913  *
4914  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4915  *            the output of this method will be : 
4916  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4917  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4918  * - \a castsPresent  : [0,1]
4919  *
4920  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4921  * range #1 and its rank within this range is 2; etc.
4922  *
4923  *  \throw If \a this->getNumberOfComponents() != 1.
4924  *  \throw If \a arrEnd - arrBg < 2.
4925  *  \throw If any value of \a this is not less than \a arrEnd[-1].
4926  */
4927 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4928                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4929 {
4930   checkAllocated();
4931   if(getNumberOfComponents()!=1)
4932     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4933   int nbOfTuples=getNumberOfTuples();
4934   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4935   if(nbOfCast<2)
4936     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4937   nbOfCast--;
4938   const int *work=getConstPointer();
4939   typedef std::reverse_iterator<const int *> rintstart;
4940   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4941   rintstart end2(arrBg);
4942   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4943   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4944   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4945   ret1->alloc(nbOfTuples,1);
4946   ret2->alloc(nbOfTuples,1);
4947   int *ret1Ptr=ret1->getPointer();
4948   int *ret2Ptr=ret2->getPointer();
4949   std::set<std::size_t> castsDetected;
4950   for(int i=0;i<nbOfTuples;i++)
4951     {
4952       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4953       std::size_t pos=std::distance(bg,res);
4954       std::size_t pos2=nbOfCast-pos;
4955       if(pos2<nbOfCast)
4956         {
4957           ret1Ptr[i]=(int)pos2;
4958           ret2Ptr[i]=work[i]-arrBg[pos2];
4959           castsDetected.insert(pos2);
4960         }
4961       else
4962         {
4963           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4964           throw INTERP_KERNEL::Exception(oss.str().c_str());
4965         }
4966     }
4967   ret3->alloc((int)castsDetected.size(),1);
4968   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4969   castArr=ret1.retn();
4970   rankInsideCast=ret2.retn();
4971   castsPresent=ret3.retn();
4972 }
4973
4974 /*!
4975  * 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 ).
4976  * 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 ).
4977  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4978  *
4979  * \param [out] strt - the start of the range (included) if true is returned.
4980  * \param [out] sttoopp - the end of the range (not included) if true is returned.
4981  * \param [out] stteepp - the step of the range if true is returned.
4982  * \return the verdict of the check.
4983  *
4984  * \sa DataArray::GetNumberOfItemGivenBES
4985  */
4986 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4987 {
4988   checkAllocated();
4989   if(getNumberOfComponents()!=1)
4990     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4991   int nbTuples(getNumberOfTuples());
4992   if(nbTuples==0)
4993     { strt=0; sttoopp=0; stteepp=1; return true; }
4994   const int *pt(begin());
4995   strt=*pt; 
4996   if(nbTuples==1)
4997     { sttoopp=strt+1; stteepp=1; return true; }
4998   strt=*pt; sttoopp=pt[nbTuples-1];
4999   if(strt==sttoopp)
5000     return false;
5001   if(sttoopp>strt)
5002     {
5003       sttoopp++;
5004       int a(sttoopp-1-strt),tmp(strt);
5005       if(a%(nbTuples-1)!=0)
5006         return false;
5007       stteepp=a/(nbTuples-1);
5008       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5009         if(pt[i]!=tmp)
5010           return false;
5011       return true;
5012     }
5013   else
5014     {
5015       sttoopp--;
5016       int a(strt-sttoopp-1),tmp(strt);
5017       if(a%(nbTuples-1)!=0)
5018         return false;
5019       stteepp=-(a/(nbTuples-1));
5020       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5021         if(pt[i]!=tmp)
5022           return false;
5023       return true;
5024     }
5025 }
5026
5027 /*!
5028  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5029  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5030  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5031  * new value in place \a indArr[ \a v ] is i.
5032  *  \param [in] indArrBg - the array holding indices within the result array to assign
5033  *         indices of values of \a this array pointing to values of \a indArrBg.
5034  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5035  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5036  *  \return DataArrayInt * - the new instance of DataArrayInt.
5037  *          The caller is to delete this result array using decrRef() as it is no more
5038  *          needed.
5039  *  \throw If \a this->getNumberOfComponents() != 1.
5040  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5041  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5042  */
5043 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5044 {
5045   checkAllocated();
5046   if(getNumberOfComponents()!=1)
5047     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5048   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5049   int nbOfTuples=getNumberOfTuples();
5050   const int *pt=getConstPointer();
5051   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5052   ret->alloc(nbOfTuples,1);
5053   ret->fillWithValue(-1);
5054   int *tmp=ret->getPointer();
5055   for(int i=0;i<nbOfTuples;i++,pt++)
5056     {
5057       if(*pt>=0 && *pt<nbElemsIn)
5058         {
5059           int pos=indArrBg[*pt];
5060           if(pos>=0 && pos<nbOfTuples)
5061             tmp[pos]=i;
5062           else
5063             {
5064               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5065               throw INTERP_KERNEL::Exception(oss.str().c_str());
5066             }
5067         }
5068       else
5069         {
5070           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5071           throw INTERP_KERNEL::Exception(oss.str().c_str());
5072         }
5073     }
5074   return ret.retn();
5075 }
5076
5077 /*!
5078  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5079  * from values of \a this array, which is supposed to contain a renumbering map in 
5080  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5081  * To know how to use the renumbering maps see \ref numbering.
5082  *  \param [in] newNbOfElem - the number of tuples in the result array.
5083  *  \return DataArrayInt * - the new instance of DataArrayInt.
5084  *          The caller is to delete this result array using decrRef() as it is no more
5085  *          needed.
5086  * 
5087  *  \if ENABLE_EXAMPLES
5088  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5089  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5090  *  \endif
5091  */
5092 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5093 {
5094   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5095   ret->alloc(newNbOfElem,1);
5096   int nbOfOldNodes=getNumberOfTuples();
5097   const int *old2New=getConstPointer();
5098   int *pt=ret->getPointer();
5099   for(int i=0;i!=nbOfOldNodes;i++)
5100     {
5101       int newp(old2New[i]);
5102       if(newp!=-1)
5103         {
5104           if(newp>=0 && newp<newNbOfElem)
5105             pt[newp]=i;
5106           else
5107             {
5108               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5109               throw INTERP_KERNEL::Exception(oss.str().c_str());
5110             }
5111         }
5112     }
5113   return ret.retn();
5114 }
5115
5116 /*!
5117  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5118  * 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]
5119  */
5120 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5121 {
5122   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5123   ret->alloc(newNbOfElem,1);
5124   int nbOfOldNodes=getNumberOfTuples();
5125   const int *old2New=getConstPointer();
5126   int *pt=ret->getPointer();
5127   for(int i=nbOfOldNodes-1;i>=0;i--)
5128     {
5129       int newp(old2New[i]);
5130       if(newp!=-1)
5131         {
5132           if(newp>=0 && newp<newNbOfElem)
5133             pt[newp]=i;
5134           else
5135             {
5136               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5137               throw INTERP_KERNEL::Exception(oss.str().c_str());
5138             }
5139         }
5140     }
5141   return ret.retn();
5142 }
5143
5144 /*!
5145  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5146  * from values of \a this array, which is supposed to contain a renumbering map in 
5147  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5148  * To know how to use the renumbering maps see \ref numbering.
5149  *  \param [in] newNbOfElem - the number of tuples in the result array.
5150  *  \return DataArrayInt * - the new instance of DataArrayInt.
5151  *          The caller is to delete this result array using decrRef() as it is no more
5152  *          needed.
5153  * 
5154  *  \if ENABLE_EXAMPLES
5155  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5156  *
5157  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5158  *  \endif
5159  */
5160 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5161 {
5162   checkAllocated();
5163   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5164   ret->alloc(oldNbOfElem,1);
5165   const int *new2Old=getConstPointer();
5166   int *pt=ret->getPointer();
5167   std::fill(pt,pt+oldNbOfElem,-1);
5168   int nbOfNewElems=getNumberOfTuples();
5169   for(int i=0;i<nbOfNewElems;i++)
5170     {
5171       int v(new2Old[i]);
5172       if(v>=0 && v<oldNbOfElem)
5173         pt[v]=i;
5174       else
5175         {
5176           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5177           throw INTERP_KERNEL::Exception(oss.str().c_str());
5178         }
5179     }
5180   return ret.retn();
5181 }
5182
5183 /*!
5184  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5185  * mismatch is given.
5186  * 
5187  * \param [in] other the instance to be compared with \a this
5188  * \param [out] reason In case of inequality returns the reason.
5189  * \sa DataArrayInt::isEqual
5190  */
5191 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5192 {
5193   if(!areInfoEqualsIfNotWhy(other,reason))
5194     return false;
5195   return _mem.isEqual(other._mem,0,reason);
5196 }
5197
5198 /*!
5199  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5200  * \ref MEDCouplingArrayBasicsCompare.
5201  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5202  *  \return bool - \a true if the two arrays are equal, \a false else.
5203  */
5204 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5205 {
5206   std::string tmp;
5207   return isEqualIfNotWhy(other,tmp);
5208 }
5209
5210 /*!
5211  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5212  * \ref MEDCouplingArrayBasicsCompare.
5213  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5214  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5215  */
5216 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5217 {
5218   std::string tmp;
5219   return _mem.isEqual(other._mem,0,tmp);
5220 }
5221
5222 /*!
5223  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5224  * performed on sorted value sequences.
5225  * For more info see\ref MEDCouplingArrayBasicsCompare.
5226  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5227  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5228  */
5229 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5230 {
5231   MCAuto<DataArrayInt> a=deepCopy();
5232   MCAuto<DataArrayInt> b=other.deepCopy();
5233   a->sort();
5234   b->sort();
5235   return a->isEqualWithoutConsideringStr(*b);
5236 }
5237
5238 /*!
5239  * This method compares content of input vector \a v and \a this.
5240  * 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.
5241  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5242  *
5243  * \param [in] v - the vector of 'flags' to be compared with \a this.
5244  *
5245  * \throw If \a this is not sorted ascendingly.
5246  * \throw If \a this has not exactly one component.
5247  * \throw If \a this is not allocated.
5248  */
5249 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5250 {
5251   checkAllocated();
5252   if(getNumberOfComponents()!=1)
5253     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5254   const int *w(begin()),*end2(end());
5255   int refVal=-std::numeric_limits<int>::max();
5256   int i=0;
5257   std::vector<bool>::const_iterator it(v.begin());
5258   for(;it!=v.end();it++,i++)
5259     {
5260       if(*it)
5261         {
5262           if(w!=end2)
5263             {
5264               if(*w++==i)
5265                 {
5266                   if(i>refVal)
5267                     refVal=i;
5268                   else
5269                     {
5270                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5271                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5272                     }
5273                 }
5274               else
5275                 return false;
5276             }
5277           else
5278             return false;
5279         }
5280     }
5281   return w==end2;
5282 }
5283
5284 /*!
5285  * 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
5286  * put True to the corresponding entry in \a vec.
5287  * \a vec is expected to be with the same size than the number of tuples of \a this.
5288  *
5289  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5290  */
5291 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5292 {
5293   checkAllocated();
5294   if(getNumberOfComponents()!=1)
5295     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5296   int nbOfTuples(getNumberOfTuples());
5297   if(nbOfTuples!=(int)vec.size())
5298     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5299   const int *pt(begin());
5300   for(int i=0;i<nbOfTuples;i++)
5301     if(pt[i]==val)
5302       vec[i]=true;
5303 }
5304
5305 /*!
5306  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
5307  * put True to the corresponding entry in \a vec.
5308  * \a vec is expected to be with the same size than the number of tuples of \a this.
5309  * 
5310  *  \sa DataArrayInt::switchOnTupleEqualTo.
5311  */
5312 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5313 {
5314   checkAllocated();
5315   if(getNumberOfComponents()!=1)
5316     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5317   int nbOfTuples(getNumberOfTuples());
5318   if(nbOfTuples!=(int)vec.size())
5319     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5320   const int *pt(begin());
5321   for(int i=0;i<nbOfTuples;i++)
5322     if(pt[i]!=val)
5323       vec[i]=true;
5324 }
5325
5326 /*!
5327  * Computes for each tuple the sum of number of components values in the tuple and return it.
5328  * 
5329  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5330  *          same number of tuples as \a this array and one component.
5331  *          The caller is to delete this result array using decrRef() as it is no more
5332  *          needed.
5333  *  \throw If \a this is not allocated.
5334  */
5335 DataArrayInt *DataArrayInt::sumPerTuple() const
5336 {
5337   checkAllocated();
5338   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5339   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5340   ret->alloc(nbOfTuple,1);
5341   const int *src(getConstPointer());
5342   int *dest(ret->getPointer());
5343   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5344     *dest=std::accumulate(src,src+nbOfComp,0);
5345   return ret.retn();
5346 }
5347
5348 /*!
5349  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5350  * If not an exception is thrown.
5351  *  \param [in] increasing - if \a true, the array values should be increasing.
5352  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5353  *         increasing arg.
5354  *  \throw If \a this->getNumberOfComponents() != 1.
5355  *  \throw If \a this is not allocated.
5356  */
5357 void DataArrayInt::checkMonotonic(bool increasing) const
5358 {
5359   if(!isMonotonic(increasing))
5360     {
5361       if (increasing)
5362         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5363       else
5364         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5365     }
5366 }
5367
5368 /*!
5369  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5370  *  \param [in] increasing - if \a true, array values should be increasing.
5371  *  \return bool - \a true if values change in accordance with \a increasing arg.
5372  *  \throw If \a this->getNumberOfComponents() != 1.
5373  *  \throw If \a this is not allocated.
5374  */
5375 bool DataArrayInt::isMonotonic(bool increasing) const
5376 {
5377   checkAllocated();
5378   if(getNumberOfComponents()!=1)
5379     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5380   int nbOfElements=getNumberOfTuples();
5381   const int *ptr=getConstPointer();
5382   if(nbOfElements==0)
5383     return true;
5384   int ref=ptr[0];
5385   if(increasing)
5386     {
5387       for(int i=1;i<nbOfElements;i++)
5388         {
5389           if(ptr[i]>=ref)
5390             ref=ptr[i];
5391           else
5392             return false;
5393         }
5394     }
5395   else
5396     {
5397       for(int i=1;i<nbOfElements;i++)
5398         {
5399           if(ptr[i]<=ref)
5400             ref=ptr[i];
5401           else
5402             return false;
5403         }
5404     }
5405   return true;
5406 }
5407
5408 /*!
5409  * This method check that array consistently INCREASING or DECREASING in value.
5410  */
5411 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5412 {
5413   checkAllocated();
5414   if(getNumberOfComponents()!=1)
5415     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5416   int nbOfElements=getNumberOfTuples();
5417   const int *ptr=getConstPointer();
5418   if(nbOfElements==0)
5419     return true;
5420   int ref=ptr[0];
5421   if(increasing)
5422     {
5423       for(int i=1;i<nbOfElements;i++)
5424         {
5425           if(ptr[i]>ref)
5426             ref=ptr[i];
5427           else
5428             return false;
5429         }
5430     }
5431   else
5432     {
5433       for(int i=1;i<nbOfElements;i++)
5434         {
5435           if(ptr[i]<ref)
5436             ref=ptr[i];
5437           else
5438             return false;
5439         }
5440     }
5441   return true;
5442 }
5443
5444 /*!
5445  * This method check that array consistently INCREASING or DECREASING in value.
5446  */
5447 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5448 {
5449   if(!isStrictlyMonotonic(increasing))
5450     {
5451       if (increasing)
5452         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5453       else
5454         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5455     }
5456 }
5457
5458 /*!
5459  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5460  * one-dimensional arrays that must be of the same length. The result array describes
5461  * correspondence between \a this and \a other arrays, so that 
5462  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5463  * not possible because some element in \a other is not in \a this, an exception is thrown.
5464  *  \param [in] other - an array to compute permutation to.
5465  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5466  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5467  * no more needed.
5468  *  \throw If \a this->getNumberOfComponents() != 1.
5469  *  \throw If \a other->getNumberOfComponents() != 1.
5470  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5471  *  \throw If \a other includes a value which is not in \a this array.
5472  * 
5473  *  \if ENABLE_EXAMPLES
5474  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5475  *
5476  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5477  *  \endif
5478  */
5479 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5480 {
5481   checkAllocated();
5482   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5483     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5484   int nbTuple=getNumberOfTuples();
5485   other.checkAllocated();
5486   if(nbTuple!=other.getNumberOfTuples())
5487     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5488   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5489   ret->alloc(nbTuple,1);
5490   ret->fillWithValue(-1);
5491   const int *pt=getConstPointer();
5492   std::map<int,int> mm;
5493   for(int i=0;i<nbTuple;i++)
5494     mm[pt[i]]=i;
5495   pt=other.getConstPointer();
5496   int *retToFill=ret->getPointer();
5497   for(int i=0;i<nbTuple;i++)
5498     {
5499       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5500       if(it==mm.end())
5501         {
5502           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5503           throw INTERP_KERNEL::Exception(oss.str().c_str());
5504         }
5505       retToFill[i]=(*it).second;
5506     }
5507   return ret.retn();
5508 }
5509
5510 void DataArrayInt::aggregate(const DataArrayInt *other)
5511 {
5512   if(!other)
5513     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5514   if(getNumberOfComponents()!=other->getNumberOfComponents())
5515     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5516   _mem.insertAtTheEnd(other->begin(),other->end());
5517 }
5518
5519 /*!
5520  * Returns a new DataArrayInt holding the same values as \a this array but differently
5521  * arranged in memory. If \a this array holds 2 components of 3 values:
5522  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5523  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5524  *  \warning Do not confuse this method with transpose()!
5525  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5526  *          is to delete using decrRef() as it is no more needed.
5527  *  \throw If \a this is not allocated.
5528  */
5529 DataArrayInt *DataArrayInt::fromNoInterlace() const
5530 {
5531   checkAllocated();
5532   if(_mem.isNull())
5533     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5534   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5535   DataArrayInt *ret=DataArrayInt::New();
5536   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5537   return ret;
5538 }
5539
5540 /*!
5541  * Returns a new DataArrayInt holding the same values as \a this array but differently
5542  * arranged in memory. If \a this array holds 2 components of 3 values:
5543  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5544  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5545  *  \warning Do not confuse this method with transpose()!
5546  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5547  *          is to delete using decrRef() as it is no more needed.
5548  *  \throw If \a this is not allocated.
5549  */
5550 DataArrayInt *DataArrayInt::toNoInterlace() const
5551 {
5552   checkAllocated();
5553   if(_mem.isNull())
5554     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5555   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5556   DataArrayInt *ret=DataArrayInt::New();
5557   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5558   return ret;
5559 }
5560
5561 /*!
5562  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5563  * This map, if applied to \a this array, would make it sorted. For example, if
5564  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5565  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5566  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5567  * This method is useful for renumbering (in MED file for example). For more info
5568  * on renumbering see \ref numbering.
5569  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5570  *          array using decrRef() as it is no more needed.
5571  *  \throw If \a this is not allocated.
5572  *  \throw If \a this->getNumberOfComponents() != 1.
5573  *  \throw If there are equal values in \a this array.
5574  */
5575 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5576 {
5577   checkAllocated();
5578   if(getNumberOfComponents()!=1)
5579     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5580   int nbTuples=getNumberOfTuples();
5581   const int *pt=getConstPointer();
5582   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5583   DataArrayInt *ret=DataArrayInt::New();
5584   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5585   return ret;
5586 }
5587
5588 /*!
5589  * 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
5590  * input array \a ids2.
5591  * \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.
5592  * 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
5593  * inversely.
5594  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5595  *
5596  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5597  *          array using decrRef() as it is no more needed.
5598  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5599  * 
5600  */
5601 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5602 {
5603   if(!ids1 || !ids2)
5604     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5605   if(!ids1->isAllocated() || !ids2->isAllocated())
5606     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5607   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5608     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5609   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5610     {
5611       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 !";
5612       throw INTERP_KERNEL::Exception(oss.str().c_str());
5613     }
5614   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5615   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5616   p1->sort(true); p2->sort(true);
5617   if(!p1->isEqualWithoutConsideringStr(*p2))
5618     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5619   p1=ids1->checkAndPreparePermutation();
5620   p2=ids2->checkAndPreparePermutation();
5621   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5622   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5623   return p2.retn();
5624 }
5625
5626 /*!
5627  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5628  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5629  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5630  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5631  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5632  * The first of out arrays returns indices of elements of \a this array, grouped by their
5633  * place in the set \a B. The second out array is the index of the first one; it shows how
5634  * many elements of \a A are mapped into each element of \a B. <br>
5635  * For more info on
5636  * mapping and its usage in renumbering see \ref numbering. <br>
5637  * \b Example:
5638  * - \a this: [0,3,2,3,2,2,1,2]
5639  * - \a targetNb: 4
5640  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5641  * - \a arrI: [0,1,2,6,8]
5642  *
5643  * This result means: <br>
5644  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5645  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5646  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5647  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5648  * \a arrI[ 2+1 ]]); <br> etc.
5649  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5650  *         than the maximal value of \a A.
5651  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5652  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5653  *         this array using decrRef() as it is no more needed.
5654  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5655  *         elements of \a this. The caller is to delete this array using decrRef() as it
5656  *         is no more needed.
5657  *  \throw If \a this is not allocated.
5658  *  \throw If \a this->getNumberOfComponents() != 1.
5659  *  \throw If any value in \a this is more or equal to \a targetNb.
5660  */
5661 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5662 {
5663   checkAllocated();
5664   if(getNumberOfComponents()!=1)
5665     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5666   int nbOfTuples=getNumberOfTuples();
5667   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5668   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5669   retI->alloc(targetNb+1,1);
5670   const int *input=getConstPointer();
5671   std::vector< std::vector<int> > tmp(targetNb);
5672   for(int i=0;i<nbOfTuples;i++)
5673     {
5674       int tmp2=input[i];
5675       if(tmp2>=0 && tmp2<targetNb)
5676         tmp[tmp2].push_back(i);
5677       else
5678         {
5679           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5680           throw INTERP_KERNEL::Exception(oss.str().c_str());
5681         }
5682     }
5683   int *retIPtr=retI->getPointer();
5684   *retIPtr=0;
5685   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5686     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5687   if(nbOfTuples!=retI->getIJ(targetNb,0))
5688     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5689   ret->alloc(nbOfTuples,1);
5690   int *retPtr=ret->getPointer();
5691   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5692     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5693   arr=ret.retn();
5694   arrI=retI.retn();
5695 }
5696
5697
5698 /*!
5699  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5700  * from a zip representation of a surjective format (returned e.g. by
5701  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5702  * for example). The result array minimizes the permutation. <br>
5703  * For more info on renumbering see \ref numbering. <br>
5704  * \b Example: <br>
5705  * - \a nbOfOldTuples: 10 
5706  * - \a arr          : [0,3, 5,7,9]
5707  * - \a arrIBg       : [0,2,5]
5708  * - \a newNbOfTuples: 7
5709  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5710  *
5711  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5712  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5713  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5714  *         (indices of) equal values. Its every element (except the last one) points to
5715  *         the first element of a group of equal values.
5716  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5717  *          arrIBg is \a arrIEnd[ -1 ].
5718  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5719  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5720  *          array using decrRef() as it is no more needed.
5721  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5722  */
5723 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5724 {
5725   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5726   ret->alloc(nbOfOldTuples,1);
5727   int *pt=ret->getPointer();
5728   std::fill(pt,pt+nbOfOldTuples,-1);
5729   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5730   const int *cIPtr=arrIBg;
5731   for(int i=0;i<nbOfGrps;i++)
5732     pt[arr[cIPtr[i]]]=-(i+2);
5733   int newNb=0;
5734   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5735     {
5736       if(pt[iNode]<0)
5737         {
5738           if(pt[iNode]==-1)
5739             pt[iNode]=newNb++;
5740           else
5741             {
5742               int grpId=-(pt[iNode]+2);
5743               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5744                 {
5745                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5746                     pt[arr[j]]=newNb;
5747                   else
5748                     {
5749                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5750                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5751                     }
5752                 }
5753               newNb++;
5754             }
5755         }
5756     }
5757   newNbOfTuples=newNb;
5758   return ret.retn();
5759 }
5760
5761 /*!
5762  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5763  * which if applied to \a this array would make it sorted ascendingly.
5764  * For more info on renumbering see \ref numbering. <br>
5765  * \b Example: <br>
5766  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5767  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5768  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5769  *
5770  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5771  *          array using decrRef() as it is no more needed.
5772  *  \throw If \a this is not allocated.
5773  *  \throw If \a this->getNumberOfComponents() != 1.
5774  */
5775 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5776 {
5777   checkAllocated();
5778   if(getNumberOfComponents()!=1)
5779     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5780   int nbOfTuples=getNumberOfTuples();
5781   const int *pt=getConstPointer();
5782   std::map<int,int> m;
5783   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5784   ret->alloc(nbOfTuples,1);
5785   int *opt=ret->getPointer();
5786   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5787     {
5788       int val=*pt;
5789       std::map<int,int>::iterator it=m.find(val);
5790       if(it!=m.end())
5791         {
5792           *opt=(*it).second;
5793           (*it).second++;
5794         }
5795       else
5796         {
5797           *opt=0;
5798           m.insert(std::pair<int,int>(val,1));
5799         }
5800     }
5801   int sum=0;
5802   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5803     {
5804       int vt=(*it).second;
5805       (*it).second=sum;
5806       sum+=vt;
5807     }
5808   pt=getConstPointer();
5809   opt=ret->getPointer();
5810   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5811     *opt+=m[*pt];
5812   //
5813   return ret.retn();
5814 }
5815
5816 /*!
5817  * Checks if contents of \a this array are equal to that of an array filled with
5818  * iota(). This method is particularly useful for DataArrayInt instances that represent
5819  * a renumbering array to check the real need in renumbering. This method checks than \a this can be considered as an identity function
5820  * of a set having \a sizeExpected elements into itself.
5821  *
5822  *  \param [in] sizeExpected - The number of elements expected.
5823  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5824  *  \throw If \a this is not allocated.
5825  *  \throw If \a this->getNumberOfComponents() != 1.
5826  */
5827 bool DataArrayInt::isIota(int sizeExpected) const
5828 {
5829   checkAllocated();
5830   if(getNumberOfComponents()!=1)
5831     return false;
5832   int nbOfTuples(getNumberOfTuples());
5833   if(nbOfTuples!=sizeExpected)
5834     return false;
5835   const int *pt=getConstPointer();
5836   for(int i=0;i<nbOfTuples;i++,pt++)
5837     if(*pt!=i)
5838       return false;
5839   return true;
5840 }
5841
5842 /*!
5843  * Checks if all values in \a this array are equal to \a val.
5844  *  \param [in] val - value to check equality of array values to.
5845  *  \return bool - \a true if all values are \a val.
5846  *  \throw If \a this is not allocated.
5847  *  \throw If \a this->getNumberOfComponents() != 1
5848  */
5849 bool DataArrayInt::isUniform(int val) const
5850 {
5851   checkAllocated();
5852   if(getNumberOfComponents()!=1)
5853     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5854   int nbOfTuples=getNumberOfTuples();
5855   const int *w=getConstPointer();
5856   const int *end2=w+nbOfTuples;
5857   for(;w!=end2;w++)
5858     if(*w!=val)
5859       return false;
5860   return true;
5861 }
5862
5863 /*!
5864  * Checks if all values in \a this array are unique.
5865  *  \return bool - \a true if condition above is true
5866  *  \throw If \a this is not allocated.
5867  *  \throw If \a this->getNumberOfComponents() != 1
5868  */
5869 bool DataArrayInt::hasUniqueValues() const
5870 {
5871   checkAllocated();
5872   if(getNumberOfComponents()!=1)
5873     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5874   int nbOfTuples(getNumberOfTuples());
5875   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
5876   if (s.size() != nbOfTuples)
5877     return false;
5878   return true;
5879 }
5880
5881 /*!
5882  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
5883  * array to the new one.
5884  *  \return DataArrayDouble * - the new instance of DataArrayInt.
5885  */
5886 DataArrayDouble *DataArrayInt::convertToDblArr() const
5887 {
5888   checkAllocated();
5889   DataArrayDouble *ret=DataArrayDouble::New();
5890   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
5891   std::size_t nbOfVals=getNbOfElems();
5892   const int *src=getConstPointer();
5893   double *dest=ret->getPointer();
5894   std::copy(src,src+nbOfVals,dest);
5895   ret->copyStringInfoFrom(*this);
5896   return ret;
5897 }
5898
5899 /*!
5900  * Appends components of another array to components of \a this one, tuple by tuple.
5901  * So that the number of tuples of \a this array remains the same and the number of 
5902  * components increases.
5903  *  \param [in] other - the DataArrayInt to append to \a this one.
5904  *  \throw If \a this is not allocated.
5905  *  \throw If \a this and \a other arrays have different number of tuples.
5906  *
5907  *  \if ENABLE_EXAMPLES
5908  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
5909  *
5910  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
5911  *  \endif
5912  */
5913 void DataArrayInt::meldWith(const DataArrayInt *other)
5914 {
5915   if(!other)
5916     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
5917   checkAllocated();
5918   other->checkAllocated();
5919   int nbOfTuples=getNumberOfTuples();
5920   if(nbOfTuples!=other->getNumberOfTuples())
5921     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
5922   int nbOfComp1=getNumberOfComponents();
5923   int nbOfComp2=other->getNumberOfComponents();
5924   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
5925   int *w=newArr;
5926   const int *inp1=getConstPointer();
5927   const int *inp2=other->getConstPointer();
5928   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
5929     {
5930       w=std::copy(inp1,inp1+nbOfComp1,w);
5931       w=std::copy(inp2,inp2+nbOfComp2,w);
5932     }
5933   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
5934   std::vector<int> compIds(nbOfComp2);
5935   for(int i=0;i<nbOfComp2;i++)
5936     compIds[i]=nbOfComp1+i;
5937   copyPartOfStringInfoFrom2(compIds,*other);
5938 }
5939
5940 /*!
5941  * Copy all components in a specified order from another DataArrayInt.
5942  * The specified components become the first ones in \a this array.
5943  * Both numerical and textual data is copied. The number of tuples in \a this and
5944  * the other array can be different.
5945  *  \param [in] a - the array to copy data from.
5946  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
5947  *              to be copied.
5948  *  \throw If \a a is NULL.
5949  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
5950  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
5951  *
5952  *  \if ENABLE_EXAMPLES
5953  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
5954  *  \endif
5955  */
5956 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
5957 {
5958   if(!a)
5959     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
5960   checkAllocated();
5961   a->checkAllocated();
5962   copyPartOfStringInfoFrom2(compoIds,*a);
5963   std::size_t partOfCompoSz=compoIds.size();
5964   int nbOfCompo=getNumberOfComponents();
5965   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
5966   const int *ac=a->getConstPointer();
5967   int *nc=getPointer();
5968   for(int i=0;i<nbOfTuples;i++)
5969     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
5970       nc[nbOfCompo*i+compoIds[j]]=*ac;
5971 }
5972
5973 /*!
5974  * Assign pointer to one array to a pointer to another appay. Reference counter of
5975  * \a arrayToSet is incremented / decremented.
5976  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
5977  *  \param [in,out] arrayToSet - the pointer to array to assign to.
5978  */
5979 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
5980 {
5981   if(newArray!=arrayToSet)
5982     {
5983       if(arrayToSet)
5984         arrayToSet->decrRef();
5985       arrayToSet=newArray;
5986       if(arrayToSet)
5987         arrayToSet->incrRef();
5988     }
5989 }
5990
5991 DataArrayIntIterator *DataArrayInt::iterator()
5992 {
5993   return new DataArrayIntIterator(this);
5994 }
5995
5996 /*!
5997  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
5998  * given one. The ids are sorted in the ascending order.
5999  *  \param [in] val - the value to find within \a this.
6000  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6001  *          array using decrRef() as it is no more needed.
6002  *  \throw If \a this is not allocated.
6003  *  \throw If \a this->getNumberOfComponents() != 1.
6004  *  \sa DataArrayInt::findIdsEqualTuple
6005  */
6006 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6007 {
6008   checkAllocated();
6009   if(getNumberOfComponents()!=1)
6010     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6011   const int *cptr(getConstPointer());
6012   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6013   int nbOfTuples=getNumberOfTuples();
6014   for(int i=0;i<nbOfTuples;i++,cptr++)
6015     if(*cptr==val)
6016       ret->pushBackSilent(i);
6017   return ret.retn();
6018 }
6019
6020 /*!
6021  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6022  * equal to a given one. 
6023  *  \param [in] val - the value to ignore within \a this.
6024  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6025  *          array using decrRef() as it is no more needed.
6026  *  \throw If \a this is not allocated.
6027  *  \throw If \a this->getNumberOfComponents() != 1.
6028  */
6029 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6030 {
6031   checkAllocated();
6032   if(getNumberOfComponents()!=1)
6033     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6034   const int *cptr(getConstPointer());
6035   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6036   int nbOfTuples=getNumberOfTuples();
6037   for(int i=0;i<nbOfTuples;i++,cptr++)
6038     if(*cptr!=val)
6039       ret->pushBackSilent(i);
6040   return ret.retn();
6041 }
6042
6043 /*!
6044  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6045  * This method is an extension of  DataArrayInt::findIdsEqual method.
6046  *
6047  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6048  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6049  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6050  *          array using decrRef() as it is no more needed.
6051  *  \throw If \a this is not allocated.
6052  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6053  * \throw If \a this->getNumberOfComponents() is equal to 0.
6054  * \sa DataArrayInt::findIdsEqual
6055  */
6056 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6057 {
6058   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6059   checkAllocated();
6060   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6061     {
6062       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6063       throw INTERP_KERNEL::Exception(oss.str().c_str());
6064     }
6065   if(nbOfCompoExp==0)
6066     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6067   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6068   const int *bg(begin()),*end2(end()),*work(begin());
6069   while(work!=end2)
6070     {
6071       work=std::search(work,end2,tupleBg,tupleEnd);
6072       if(work!=end2)
6073         {
6074           std::size_t pos(std::distance(bg,work));
6075           if(pos%nbOfCompoExp==0)
6076             ret->pushBackSilent(pos/nbOfCompoExp);
6077           work++;
6078         }
6079     }
6080   return ret.retn();
6081 }
6082
6083 /*!
6084  * Assigns \a newValue to all elements holding \a oldValue within \a this
6085  * one-dimensional array.
6086  *  \param [in] oldValue - the value to replace.
6087  *  \param [in] newValue - the value to assign.
6088  *  \return int - number of replacements performed.
6089  *  \throw If \a this is not allocated.
6090  *  \throw If \a this->getNumberOfComponents() != 1.
6091  */
6092 int DataArrayInt::changeValue(int oldValue, int newValue)
6093 {
6094   checkAllocated();
6095   if(getNumberOfComponents()!=1)
6096     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6097   if(oldValue==newValue)
6098     return 0;
6099   int *start(getPointer()),*end2(start+getNbOfElems());
6100   int ret(0);
6101   for(int *val=start;val!=end2;val++)
6102     {
6103       if(*val==oldValue)
6104         {
6105           *val=newValue;
6106           ret++;
6107         }
6108     }
6109   if(ret>0)
6110     declareAsNew();
6111   return ret;
6112 }
6113
6114 /*!
6115  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6116  * one of given values.
6117  *  \param [in] valsBg - an array of values to find within \a this array.
6118  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6119  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6120  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6121  *          array using decrRef() as it is no more needed.
6122  *  \throw If \a this->getNumberOfComponents() != 1.
6123  */
6124 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6125 {
6126   if(getNumberOfComponents()!=1)
6127     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6128   std::set<int> vals2(valsBg,valsEnd);
6129   const int *cptr(getConstPointer());
6130   std::vector<int> res;
6131   int nbOfTuples(getNumberOfTuples());
6132   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6133   for(int i=0;i<nbOfTuples;i++,cptr++)
6134     if(vals2.find(*cptr)!=vals2.end())
6135       ret->pushBackSilent(i);
6136   return ret.retn();
6137 }
6138
6139 /*!
6140  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6141  * equal to any of given values.
6142  *  \param [in] valsBg - an array of values to ignore within \a this array.
6143  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6144  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6145  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6146  *          array using decrRef() as it is no more needed.
6147  *  \throw If \a this->getNumberOfComponents() != 1.
6148  */
6149 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6150 {
6151   if(getNumberOfComponents()!=1)
6152     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6153   std::set<int> vals2(valsBg,valsEnd);
6154   const int *cptr=getConstPointer();
6155   std::vector<int> res;
6156   int nbOfTuples=getNumberOfTuples();
6157   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6158   for(int i=0;i<nbOfTuples;i++,cptr++)
6159     if(vals2.find(*cptr)==vals2.end())
6160       ret->pushBackSilent(i);
6161   return ret.retn();
6162 }
6163
6164 /*!
6165  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6166  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6167  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6168  * If any the tuple id is returned. If not -1 is returned.
6169  * 
6170  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6171  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6172  *
6173  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6174  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6175  */
6176 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6177 {
6178   checkAllocated();
6179   int nbOfCompo=getNumberOfComponents();
6180   if(nbOfCompo==0)
6181     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6182   if(nbOfCompo!=(int)tupl.size())
6183     {
6184       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6185       throw INTERP_KERNEL::Exception(oss.str().c_str());
6186     }
6187   const int *cptr=getConstPointer();
6188   std::size_t nbOfVals=getNbOfElems();
6189   for(const int *work=cptr;work!=cptr+nbOfVals;)
6190     {
6191       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6192       if(work!=cptr+nbOfVals)
6193         {
6194           if(std::distance(cptr,work)%nbOfCompo!=0)
6195             work++;
6196           else
6197             return std::distance(cptr,work)/nbOfCompo;
6198         }
6199     }
6200   return -1;
6201 }
6202
6203 /*!
6204  * This method searches the sequence specified in input parameter \b vals in \b this.
6205  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6206  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6207  * \sa DataArrayInt::findIdFirstEqualTuple
6208  */
6209 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6210 {
6211   checkAllocated();
6212   int nbOfCompo=getNumberOfComponents();
6213   if(nbOfCompo!=1)
6214     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6215   const int *cptr=getConstPointer();
6216   std::size_t nbOfVals=getNbOfElems();
6217   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6218   if(loc!=cptr+nbOfVals)
6219     return std::distance(cptr,loc);
6220   return -1;
6221 }
6222
6223 /*!
6224  * This method expects to be called when number of components of this is equal to one.
6225  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6226  * If not any tuple contains \b value -1 is returned.
6227  * \sa DataArrayInt::presenceOfValue
6228  */
6229 int DataArrayInt::findIdFirstEqual(int value) const
6230 {
6231   checkAllocated();
6232   if(getNumberOfComponents()!=1)
6233     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6234   const int *cptr=getConstPointer();
6235   int nbOfTuples=getNumberOfTuples();
6236   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6237   if(ret!=cptr+nbOfTuples)
6238     return std::distance(cptr,ret);
6239   return -1;
6240 }
6241
6242 /*!
6243  * This method expects to be called when number of components of this is equal to one.
6244  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6245  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6246  * \sa DataArrayInt::presenceOfValue
6247  */
6248 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6249 {
6250   checkAllocated();
6251   if(getNumberOfComponents()!=1)
6252     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6253   std::set<int> vals2(vals.begin(),vals.end());
6254   const int *cptr=getConstPointer();
6255   int nbOfTuples=getNumberOfTuples();
6256   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6257     if(vals2.find(*w)!=vals2.end())
6258       return std::distance(cptr,w);
6259   return -1;
6260 }
6261
6262 /*!
6263  * This method returns the number of values in \a this that are equals to input parameter \a value.
6264  * This method only works for single component array.
6265  *
6266  * \return a value in [ 0, \c this->getNumberOfTuples() )
6267  *
6268  * \throw If \a this is not allocated
6269  *
6270  */
6271 int DataArrayInt::count(int value) const
6272 {
6273   int ret=0;
6274   checkAllocated();
6275   if(getNumberOfComponents()!=1)
6276     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6277   const int *vals=begin();
6278   int nbOfTuples=getNumberOfTuples();
6279   for(int i=0;i<nbOfTuples;i++,vals++)
6280     if(*vals==value)
6281       ret++;
6282   return ret;
6283 }
6284
6285 /*!
6286  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6287  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6288  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6289  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6290  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6291  * \sa DataArrayInt::findIdFirstEqualTuple
6292  */
6293 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6294 {
6295   return findIdFirstEqualTuple(tupl)!=-1;
6296 }
6297
6298
6299 /*!
6300  * Returns \a true if a given value is present within \a this one-dimensional array.
6301  *  \param [in] value - the value to find within \a this array.
6302  *  \return bool - \a true in case if \a value is present within \a this array.
6303  *  \throw If \a this is not allocated.
6304  *  \throw If \a this->getNumberOfComponents() != 1.
6305  *  \sa findIdFirstEqual()
6306  */
6307 bool DataArrayInt::presenceOfValue(int value) const
6308 {
6309   return findIdFirstEqual(value)!=-1;
6310 }
6311
6312 /*!
6313  * This method expects to be called when number of components of this is equal to one.
6314  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6315  * If not any tuple contains one of the values contained in 'vals' false is returned.
6316  * \sa DataArrayInt::findIdFirstEqual
6317  */
6318 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6319 {
6320   return findIdFirstEqual(vals)!=-1;
6321 }
6322
6323 /*!
6324  * Accumulates values of each component of \a this array.
6325  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6326  *         by the caller, that is filled by this method with sum value for each
6327  *         component.
6328  *  \throw If \a this is not allocated.
6329  */
6330 void DataArrayInt::accumulate(int *res) const
6331 {
6332   checkAllocated();
6333   const int *ptr=getConstPointer();
6334   int nbTuple=getNumberOfTuples();
6335   int nbComps=getNumberOfComponents();
6336   std::fill(res,res+nbComps,0);
6337   for(int i=0;i<nbTuple;i++)
6338     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6339 }
6340
6341 int DataArrayInt::accumulate(int compId) const
6342 {
6343   checkAllocated();
6344   const int *ptr=getConstPointer();
6345   int nbTuple=getNumberOfTuples();
6346   int nbComps=getNumberOfComponents();
6347   if(compId<0 || compId>=nbComps)
6348     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6349   int ret=0;
6350   for(int i=0;i<nbTuple;i++)
6351     ret+=ptr[i*nbComps+compId];
6352   return ret;
6353 }
6354
6355 /*!
6356  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6357  * The returned array will have same number of components than \a this and number of tuples equal to
6358  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6359  *
6360  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6361  *
6362  * \param [in] bgOfIndex - begin (included) of the input index array.
6363  * \param [in] endOfIndex - end (excluded) of the input index array.
6364  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6365  * 
6366  * \throw If bgOfIndex or end is NULL.
6367  * \throw If input index array is not ascendingly sorted.
6368  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6369  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6370  */
6371 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6372 {
6373   if(!bgOfIndex || !endOfIndex)
6374     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6375   checkAllocated();
6376   int nbCompo=getNumberOfComponents();
6377   int nbOfTuples=getNumberOfTuples();
6378   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6379   if(sz<1)
6380     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6381   sz--;
6382   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6383   const int *w=bgOfIndex;
6384   if(*w<0 || *w>=nbOfTuples)
6385     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6386   const int *srcPt=begin()+(*w)*nbCompo;
6387   int *tmp=ret->getPointer();
6388   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6389     {
6390       std::fill(tmp,tmp+nbCompo,0);
6391       if(w[1]>=w[0])
6392         {
6393           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6394             {
6395               if(j>=0 && j<nbOfTuples)
6396                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6397               else
6398                 {
6399                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6400                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6401                 }
6402             }
6403         }
6404       else
6405         {
6406           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6407           throw INTERP_KERNEL::Exception(oss.str().c_str());
6408         }
6409     }
6410   ret->copyStringInfoFrom(*this);
6411   return ret.retn();
6412 }
6413
6414 /*!
6415  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6416  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6417  * offsetA2</em> and (2)
6418  * the number of component in the result array is same as that of each of given arrays.
6419  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6420  * Info on components is copied from the first of the given arrays. Number of components
6421  * in the given arrays must be the same.
6422  *  \param [in] a1 - an array to include in the result array.
6423  *  \param [in] a2 - another array to include in the result array.
6424  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6425  *  \return DataArrayInt * - the new instance of DataArrayInt.
6426  *          The caller is to delete this result array using decrRef() as it is no more
6427  *          needed.
6428  *  \throw If either \a a1 or \a a2 is NULL.
6429  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6430  */
6431 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6432 {
6433   if(!a1 || !a2)
6434     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6435   int nbOfComp=a1->getNumberOfComponents();
6436   if(nbOfComp!=a2->getNumberOfComponents())
6437     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6438   int nbOfTuple1=a1->getNumberOfTuples();
6439   int nbOfTuple2=a2->getNumberOfTuples();
6440   DataArrayInt *ret=DataArrayInt::New();
6441   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6442   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6443   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6444   ret->copyStringInfoFrom(*a1);
6445   return ret;
6446 }
6447
6448 /*!
6449  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6450  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6451  * the number of component in the result array is same as that of each of given arrays.
6452  * Info on components is copied from the first of the given arrays. Number of components
6453  * in the given arrays must be  the same.
6454  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6455  * not the object itself.
6456  *  \param [in] arr - a sequence of arrays to include in the result array.
6457  *  \return DataArrayInt * - the new instance of DataArrayInt.
6458  *          The caller is to delete this result array using decrRef() as it is no more
6459  *          needed.
6460  *  \throw If all arrays within \a arr are NULL.
6461  *  \throw If getNumberOfComponents() of arrays within \a arr.
6462  */
6463 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6464 {
6465   std::vector<const DataArrayInt *> a;
6466   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6467     if(*it4)
6468       a.push_back(*it4);
6469   if(a.empty())
6470     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6471   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6472   int nbOfComp=(*it)->getNumberOfComponents();
6473   int nbt=(*it++)->getNumberOfTuples();
6474   for(int i=1;it!=a.end();it++,i++)
6475     {
6476       if((*it)->getNumberOfComponents()!=nbOfComp)
6477         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6478       nbt+=(*it)->getNumberOfTuples();
6479     }
6480   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6481   ret->alloc(nbt,nbOfComp);
6482   int *pt=ret->getPointer();
6483   for(it=a.begin();it!=a.end();it++)
6484     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6485   ret->copyStringInfoFrom(*(a[0]));
6486   return ret.retn();
6487 }
6488
6489 /*!
6490  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6491  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6492  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6493  * 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.
6494  * 
6495  * \return DataArrayInt * - a new object to be managed by the caller.
6496  */
6497 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6498 {
6499   int retSz=1;
6500   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6501     {
6502       if(*it4)
6503         {
6504           (*it4)->checkAllocated();
6505           if((*it4)->getNumberOfComponents()!=1)
6506             {
6507               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6508               throw INTERP_KERNEL::Exception(oss.str().c_str());
6509             }
6510           int nbTupl=(*it4)->getNumberOfTuples();
6511           if(nbTupl<1)
6512             {
6513               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6514               throw INTERP_KERNEL::Exception(oss.str().c_str());
6515             }
6516           if((*it4)->front()!=0)
6517             {
6518               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6519               throw INTERP_KERNEL::Exception(oss.str().c_str());
6520             }
6521           retSz+=nbTupl-1;
6522         }
6523       else
6524         {
6525           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6526           throw INTERP_KERNEL::Exception(oss.str().c_str());
6527         }
6528     }
6529   if(arrs.empty())
6530     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6531   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6532   ret->alloc(retSz,1);
6533   int *pt=ret->getPointer(); *pt++=0;
6534   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6535     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6536   ret->copyStringInfoFrom(*(arrs[0]));
6537   return ret.retn();
6538 }
6539
6540 /*!
6541  * Returns in a single walk in \a this the min value and the max value in \a this.
6542  * \a this is expected to be single component array.
6543  *
6544  * \param [out] minValue - the min value in \a this.
6545  * \param [out] maxValue - the max value in \a this.
6546  *
6547  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6548  */
6549 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6550 {
6551   checkAllocated();
6552   if(getNumberOfComponents()!=1)
6553     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6554   int nbTuples(getNumberOfTuples());
6555   const int *pt(begin());
6556   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6557   for(int i=0;i<nbTuples;i++,pt++)
6558     {
6559       if(*pt<minValue)
6560         minValue=*pt;
6561       if(*pt>maxValue)
6562         maxValue=*pt;
6563     }
6564 }
6565
6566 /*!
6567  * Converts every value of \a this array to its absolute value.
6568  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6569  * should be called instead.
6570  *
6571  * \throw If \a this is not allocated.
6572  * \sa DataArrayInt::computeAbs
6573  */
6574 void DataArrayInt::abs()
6575 {
6576   checkAllocated();
6577   int *ptr(getPointer());
6578   std::size_t nbOfElems(getNbOfElems());
6579   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6580   declareAsNew();
6581 }
6582
6583 /*!
6584  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6585  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6586  *
6587  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6588  *         same number of tuples and component as \a this array.
6589  *         The caller is to delete this result array using decrRef() as it is no more
6590  *         needed.
6591  * \throw If \a this is not allocated.
6592  * \sa DataArrayInt::abs
6593  */
6594 DataArrayInt *DataArrayInt::computeAbs() const
6595 {
6596   checkAllocated();
6597   DataArrayInt *newArr(DataArrayInt::New());
6598   int nbOfTuples(getNumberOfTuples());
6599   int nbOfComp(getNumberOfComponents());
6600   newArr->alloc(nbOfTuples,nbOfComp);
6601   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6602   newArr->copyStringInfoFrom(*this);
6603   return newArr;
6604 }
6605
6606 /*!
6607  * Apply a liner function to a given component of \a this array, so that
6608  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6609  *  \param [in] a - the first coefficient of the function.
6610  *  \param [in] b - the second coefficient of the function.
6611  *  \param [in] compoId - the index of component to modify.
6612  *  \throw If \a this is not allocated.
6613  */
6614 void DataArrayInt::applyLin(int a, int b, int compoId)
6615 {
6616   checkAllocated();
6617   int *ptr=getPointer()+compoId;
6618   int nbOfComp=getNumberOfComponents();
6619   int nbOfTuple=getNumberOfTuples();
6620   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6621     *ptr=a*(*ptr)+b;
6622   declareAsNew();
6623 }
6624
6625 /*!
6626  * Apply a liner function to all elements of \a this array, so that
6627  * an element _x_ becomes \f$ a * x + b \f$.
6628  *  \param [in] a - the first coefficient of the function.
6629  *  \param [in] b - the second coefficient of the function.
6630  *  \throw If \a this is not allocated.
6631  */
6632 void DataArrayInt::applyLin(int a, int b)
6633 {
6634   checkAllocated();
6635   int *ptr=getPointer();
6636   std::size_t nbOfElems=getNbOfElems();
6637   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6638     *ptr=a*(*ptr)+b;
6639   declareAsNew();
6640 }
6641
6642 /*!
6643  * Returns a full copy of \a this array except that sign of all elements is reversed.
6644  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6645  *          same number of tuples and component as \a this array.
6646  *          The caller is to delete this result array using decrRef() as it is no more
6647  *          needed.
6648  *  \throw If \a this is not allocated.
6649  */
6650 DataArrayInt *DataArrayInt::negate() const
6651 {
6652   checkAllocated();
6653   DataArrayInt *newArr=DataArrayInt::New();
6654   int nbOfTuples=getNumberOfTuples();
6655   int nbOfComp=getNumberOfComponents();
6656   newArr->alloc(nbOfTuples,nbOfComp);
6657   const int *cptr=getConstPointer();
6658   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6659   newArr->copyStringInfoFrom(*this);
6660   return newArr;
6661 }
6662
6663 /*!
6664  * Modify all elements of \a this array, so that
6665  * an element _x_ becomes \f$ numerator / x \f$.
6666  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6667  *           array, all elements processed before detection of the zero element remain
6668  *           modified.
6669  *  \param [in] numerator - the numerator used to modify array elements.
6670  *  \throw If \a this is not allocated.
6671  *  \throw If there is an element equal to 0 in \a this array.
6672  */
6673 void DataArrayInt::applyInv(int numerator)
6674 {
6675   checkAllocated();
6676   int *ptr=getPointer();
6677   std::size_t nbOfElems=getNbOfElems();
6678   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6679     {
6680       if(*ptr!=0)
6681         {
6682           *ptr=numerator/(*ptr);
6683         }
6684       else
6685         {
6686           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6687           oss << " !";
6688           throw INTERP_KERNEL::Exception(oss.str().c_str());
6689         }
6690     }
6691   declareAsNew();
6692 }
6693
6694 /*!
6695  * Modify all elements of \a this array, so that
6696  * an element _x_ becomes \f$ x / val \f$.
6697  *  \param [in] val - the denominator used to modify array elements.
6698  *  \throw If \a this is not allocated.
6699  *  \throw If \a val == 0.
6700  */
6701 void DataArrayInt::applyDivideBy(int val)
6702 {
6703   if(val==0)
6704     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6705   checkAllocated();
6706   int *ptr=getPointer();
6707   std::size_t nbOfElems=getNbOfElems();
6708   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6709   declareAsNew();
6710 }
6711
6712 /*!
6713  * Modify all elements of \a this array, so that
6714  * an element _x_ becomes  <em> x % val </em>.
6715  *  \param [in] val - the divisor used to modify array elements.
6716  *  \throw If \a this is not allocated.
6717  *  \throw If \a val <= 0.
6718  */
6719 void DataArrayInt::applyModulus(int val)
6720 {
6721   if(val<=0)
6722     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6723   checkAllocated();
6724   int *ptr=getPointer();
6725   std::size_t nbOfElems=getNbOfElems();
6726   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6727   declareAsNew();
6728 }
6729
6730 /*!
6731  * This method works only on data array with one component.
6732  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6733  * this[*id] in [\b vmin,\b vmax)
6734  * 
6735  * \param [in] vmin begin of range. This value is included in range (included).
6736  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6737  * \return a newly allocated data array that the caller should deal with.
6738  *
6739  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6740  */
6741 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6742 {
6743   checkAllocated();
6744   if(getNumberOfComponents()!=1)
6745     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
6746   const int *cptr(begin());
6747   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6748   int nbOfTuples(getNumberOfTuples());
6749   for(int i=0;i<nbOfTuples;i++,cptr++)
6750     if(*cptr>=vmin && *cptr<vmax)
6751       ret->pushBackSilent(i);
6752   return ret.retn();
6753 }
6754
6755 /*!
6756  * This method works only on data array with one component.
6757  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6758  * this[*id] \b not in [\b vmin,\b vmax)
6759  * 
6760  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6761  * \param [in] vmax end of range. This value is included in range (included).
6762  * \return a newly allocated data array that the caller should deal with.
6763  * 
6764  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6765  */
6766 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6767 {
6768   checkAllocated();
6769   if(getNumberOfComponents()!=1)
6770     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
6771   const int *cptr(getConstPointer());
6772   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6773   int nbOfTuples(getNumberOfTuples());
6774   for(int i=0;i<nbOfTuples;i++,cptr++)
6775     if(*cptr<vmin || *cptr>=vmax)
6776       ret->pushBackSilent(i);
6777   return ret.retn();
6778 }
6779
6780 /*!
6781  * 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.
6782  *
6783  * \return a newly allocated data array that the caller should deal with.
6784  * \sa DataArrayInt::findIdsInRange
6785  */
6786 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6787 {
6788   checkAllocated();
6789   if(getNumberOfComponents()!=1)
6790     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
6791   const int *cptr(getConstPointer());
6792   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6793   int nbOfTuples(getNumberOfTuples());
6794   for(int i=0;i<nbOfTuples;i++,cptr++)
6795     if(*cptr<0)
6796       ret->pushBackSilent(i);
6797   return ret.retn();
6798 }
6799
6800 /*!
6801  * This method works only on data array with one component.
6802  * 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.
6803  * 
6804  * \param [in] vmin begin of range. This value is included in range (included).
6805  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6806  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6807 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6808 {
6809   checkAllocated();
6810   if(getNumberOfComponents()!=1)
6811     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6812   int nbOfTuples=getNumberOfTuples();
6813   bool ret=true;
6814   const int *cptr=getConstPointer();
6815   for(int i=0;i<nbOfTuples;i++,cptr++)
6816     {
6817       if(*cptr>=vmin && *cptr<vmax)
6818         { ret=ret && *cptr==i; }
6819       else
6820         {
6821           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6822           throw INTERP_KERNEL::Exception(oss.str().c_str());
6823         }
6824     }
6825   return ret;
6826 }
6827
6828 /*!
6829  * Modify all elements of \a this array, so that
6830  * an element _x_ becomes <em> val % x </em>.
6831  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6832  *           array, all elements processed before detection of the zero element remain
6833  *           modified.
6834  *  \param [in] val - the divident used to modify array elements.
6835  *  \throw If \a this is not allocated.
6836  *  \throw If there is an element equal to or less than 0 in \a this array.
6837  */
6838 void DataArrayInt::applyRModulus(int val)
6839 {
6840   checkAllocated();
6841   int *ptr=getPointer();
6842   std::size_t nbOfElems=getNbOfElems();
6843   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6844     {
6845       if(*ptr>0)
6846         {
6847           *ptr=val%(*ptr);
6848         }
6849       else
6850         {
6851           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6852           oss << " !";
6853           throw INTERP_KERNEL::Exception(oss.str().c_str());
6854         }
6855     }
6856   declareAsNew();
6857 }
6858
6859 /*!
6860  * Modify all elements of \a this array, so that
6861  * an element _x_ becomes <em> val ^ x </em>.
6862  *  \param [in] val - the value used to apply pow on all array elements.
6863  *  \throw If \a this is not allocated.
6864  *  \throw If \a val < 0.
6865  */
6866 void DataArrayInt::applyPow(int val)
6867 {
6868   checkAllocated();
6869   if(val<0)
6870     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
6871   int *ptr=getPointer();
6872   std::size_t nbOfElems=getNbOfElems();
6873   if(val==0)
6874     {
6875       std::fill(ptr,ptr+nbOfElems,1);
6876       return ;
6877     }
6878   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6879     {
6880       int tmp=1;
6881       for(int j=0;j<val;j++)
6882         tmp*=*ptr;
6883       *ptr=tmp;
6884     }
6885   declareAsNew();
6886 }
6887
6888 /*!
6889  * Modify all elements of \a this array, so that
6890  * an element _x_ becomes \f$ val ^ x \f$.
6891  *  \param [in] val - the value used to apply pow on all array elements.
6892  *  \throw If \a this is not allocated.
6893  *  \throw If there is an element < 0 in \a this array.
6894  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6895  *           array, all elements processed before detection of the zero element remain
6896  *           modified.
6897  */
6898 void DataArrayInt::applyRPow(int val)
6899 {
6900   checkAllocated();
6901   int *ptr=getPointer();
6902   std::size_t nbOfElems=getNbOfElems();
6903   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6904     {
6905       if(*ptr>=0)
6906         {
6907           int tmp=1;
6908           for(int j=0;j<*ptr;j++)
6909             tmp*=val;
6910           *ptr=tmp;
6911         }
6912       else
6913         {
6914           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6915           oss << " !";
6916           throw INTERP_KERNEL::Exception(oss.str().c_str());
6917         }
6918     }
6919   declareAsNew();
6920 }
6921
6922 /*!
6923  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
6924  * of components in the result array is a sum of the number of components of given arrays
6925  * and (2) the number of tuples in the result array is same as that of each of given
6926  * arrays. In other words the i-th tuple of result array includes all components of
6927  * i-th tuples of all given arrays.
6928  * Number of tuples in the given arrays must be the same.
6929  *  \param [in] a1 - an array to include in the result array.
6930  *  \param [in] a2 - another array to include in the result array.
6931  *  \return DataArrayInt * - the new instance of DataArrayInt.
6932  *          The caller is to delete this result array using decrRef() as it is no more
6933  *          needed.
6934  *  \throw If both \a a1 and \a a2 are NULL.
6935  *  \throw If any given array is not allocated.
6936  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6937  */
6938 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
6939 {
6940   std::vector<const DataArrayInt *> arr(2);
6941   arr[0]=a1; arr[1]=a2;
6942   return Meld(arr);
6943 }
6944
6945 /*!
6946  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
6947  * of components in the result array is a sum of the number of components of given arrays
6948  * and (2) the number of tuples in the result array is same as that of each of given
6949  * arrays. In other words the i-th tuple of result array includes all components of
6950  * i-th tuples of all given arrays.
6951  * Number of tuples in the given arrays must be  the same.
6952  *  \param [in] arr - a sequence of arrays to include in the result array.
6953  *  \return DataArrayInt * - the new instance of DataArrayInt.
6954  *          The caller is to delete this result array using decrRef() as it is no more
6955  *          needed.
6956  *  \throw If all arrays within \a arr are NULL.
6957  *  \throw If any given array is not allocated.
6958  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
6959  */
6960 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
6961 {
6962   std::vector<const DataArrayInt *> a;
6963   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6964     if(*it4)
6965       a.push_back(*it4);
6966   if(a.empty())
6967     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
6968   std::vector<const DataArrayInt *>::const_iterator it;
6969   for(it=a.begin();it!=a.end();it++)
6970     (*it)->checkAllocated();
6971   it=a.begin();
6972   int nbOfTuples=(*it)->getNumberOfTuples();
6973   std::vector<int> nbc(a.size());
6974   std::vector<const int *> pts(a.size());
6975   nbc[0]=(*it)->getNumberOfComponents();
6976   pts[0]=(*it++)->getConstPointer();
6977   for(int i=1;it!=a.end();it++,i++)
6978     {
6979       if(nbOfTuples!=(*it)->getNumberOfTuples())
6980         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
6981       nbc[i]=(*it)->getNumberOfComponents();
6982       pts[i]=(*it)->getConstPointer();
6983     }
6984   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
6985   DataArrayInt *ret=DataArrayInt::New();
6986   ret->alloc(nbOfTuples,totalNbOfComp);
6987   int *retPtr=ret->getPointer();
6988   for(int i=0;i<nbOfTuples;i++)
6989     for(int j=0;j<(int)a.size();j++)
6990       {
6991         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
6992         pts[j]+=nbc[j];
6993       }
6994   int k=0;
6995   for(int i=0;i<(int)a.size();i++)
6996     for(int j=0;j<nbc[i];j++,k++)
6997       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
6998   return ret;
6999 }
7000
7001 /*!
7002  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7003  * The i-th item of the result array is an ID of a set of elements belonging to a
7004  * unique set of groups, which the i-th element is a part of. This set of elements
7005  * belonging to a unique set of groups is called \a family, so the result array contains
7006  * IDs of families each element belongs to.
7007  *
7008  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7009  * then there are 3 families:
7010  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7011  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7012  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7013  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7014  * stands for the element #3 which is in none of groups.
7015  *
7016  *  \param [in] groups - sequence of groups of element IDs.
7017  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7018  *         in \a groups.
7019  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7020  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7021  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7022  *         delete this array using decrRef() as it is no more needed.
7023  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7024  */
7025 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7026 {
7027   std::vector<const DataArrayInt *> groups2;
7028   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7029     if(*it4)
7030       groups2.push_back(*it4);
7031   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7032   ret->alloc(newNb,1);
7033   int *retPtr=ret->getPointer();
7034   std::fill(retPtr,retPtr+newNb,0);
7035   int fid=1;
7036   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7037     {
7038       const int *ptr=(*iter)->getConstPointer();
7039       std::size_t nbOfElem=(*iter)->getNbOfElems();
7040       int sfid=fid;
7041       for(int j=0;j<sfid;j++)
7042         {
7043           bool found=false;
7044           for(std::size_t i=0;i<nbOfElem;i++)
7045             {
7046               if(ptr[i]>=0 && ptr[i]<newNb)
7047                 {
7048                   if(retPtr[ptr[i]]==j)
7049                     {
7050                       retPtr[ptr[i]]=fid;
7051                       found=true;
7052                     }
7053                 }
7054               else
7055                 {
7056                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7057                   oss << ") !";
7058                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7059                 }
7060             }
7061           if(found)
7062             fid++;
7063         }
7064     }
7065   fidsOfGroups.clear();
7066   fidsOfGroups.resize(groups2.size());
7067   int grId=0;
7068   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7069     {
7070       std::set<int> tmp;
7071       const int *ptr=(*iter)->getConstPointer();
7072       std::size_t nbOfElem=(*iter)->getNbOfElems();
7073       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7074         tmp.insert(retPtr[*p]);
7075       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7076     }
7077   return ret.retn();
7078 }
7079
7080 /*!
7081  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7082  * arrays. The result array does not contain any duplicates and its values
7083  * are sorted in ascending order.
7084  *  \param [in] arr - sequence of DataArrayInt's to unite.
7085  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7086  *         array using decrRef() as it is no more needed.
7087  *  \throw If any \a arr[i] is not allocated.
7088  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7089  */
7090 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7091 {
7092   std::vector<const DataArrayInt *> a;
7093   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7094     if(*it4)
7095       a.push_back(*it4);
7096   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7097     {
7098       (*it)->checkAllocated();
7099       if((*it)->getNumberOfComponents()!=1)
7100         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7101     }
7102   //
7103   std::set<int> r;
7104   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7105     {
7106       const int *pt=(*it)->getConstPointer();
7107       int nbOfTuples=(*it)->getNumberOfTuples();
7108       r.insert(pt,pt+nbOfTuples);
7109     }
7110   DataArrayInt *ret=DataArrayInt::New();
7111   ret->alloc((int)r.size(),1);
7112   std::copy(r.begin(),r.end(),ret->getPointer());
7113   return ret;
7114 }
7115
7116 /*!
7117  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7118  * arrays. The result array does not contain any duplicates and its values
7119  * are sorted in ascending order.
7120  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7121  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7122  *         array using decrRef() as it is no more needed.
7123  *  \throw If any \a arr[i] is not allocated.
7124  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7125  */
7126 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7127 {
7128   std::vector<const DataArrayInt *> a;
7129   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7130     if(*it4)
7131       a.push_back(*it4);
7132   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7133     {
7134       (*it)->checkAllocated();
7135       if((*it)->getNumberOfComponents()!=1)
7136         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7137     }
7138   //
7139   std::set<int> r;
7140   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7141     {
7142       const int *pt=(*it)->getConstPointer();
7143       int nbOfTuples=(*it)->getNumberOfTuples();
7144       std::set<int> s1(pt,pt+nbOfTuples);
7145       if(it!=a.begin())
7146         {
7147           std::set<int> r2;
7148           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7149           r=r2;
7150         }
7151       else
7152         r=s1;
7153     }
7154   DataArrayInt *ret(DataArrayInt::New());
7155   ret->alloc((int)r.size(),1);
7156   std::copy(r.begin(),r.end(),ret->getPointer());
7157   return ret;
7158 }
7159
7160 /// @cond INTERNAL
7161 namespace MEDCouplingImpl
7162 {
7163   class OpSwitchedOn
7164   {
7165   public:
7166     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7167     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7168   private:
7169     int *_pt;
7170     int _cnt;
7171   };
7172
7173   class OpSwitchedOff
7174   {
7175   public:
7176     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7177     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7178   private:
7179     int *_pt;
7180     int _cnt;
7181   };
7182 }
7183 /// @endcond
7184
7185 /*!
7186  * This method returns the list of ids in ascending mode so that v[id]==true.
7187  */
7188 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7189 {
7190   int sz((int)std::count(v.begin(),v.end(),true));
7191   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7192   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7193   return ret.retn();
7194 }
7195
7196 /*!
7197  * This method returns the list of ids in ascending mode so that v[id]==false.
7198  */
7199 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7200 {
7201   int sz((int)std::count(v.begin(),v.end(),false));
7202   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7203   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7204   return ret.retn();
7205 }
7206
7207 /*!
7208  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7209  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7210  *
7211  * \param [in] v the input data structure to be translate into skyline format.
7212  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7213  * \param [out] dataIndex the second element of the skyline format.
7214  */
7215 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7216 {
7217   int sz((int)v.size());
7218   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7219   ret1->alloc(sz+1,1);
7220   int *pt(ret1->getPointer()); *pt=0;
7221   for(int i=0;i<sz;i++,pt++)
7222     pt[1]=pt[0]+(int)v[i].size();
7223   ret0->alloc(ret1->back(),1);
7224   pt=ret0->getPointer();
7225   for(int i=0;i<sz;i++)
7226     pt=std::copy(v[i].begin(),v[i].end(),pt);
7227   data=ret0.retn(); dataIndex=ret1.retn();
7228 }
7229
7230 /*!
7231  * Returns a new DataArrayInt which contains a complement of elements of \a this
7232  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7233  * \a nbOfElement) not present in \a this array.
7234  *  \param [in] nbOfElement - maximal size of the result array.
7235  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7236  *         array using decrRef() as it is no more needed.
7237  *  \throw If \a this is not allocated.
7238  *  \throw If \a this->getNumberOfComponents() != 1.
7239  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7240  *         nbOfElement ).
7241  */
7242 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7243 {
7244   checkAllocated();
7245   if(getNumberOfComponents()!=1)
7246     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7247   std::vector<bool> tmp(nbOfElement);
7248   const int *pt=getConstPointer();
7249   int nbOfTuples=getNumberOfTuples();
7250   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7251     if(*w>=0 && *w<nbOfElement)
7252       tmp[*w]=true;
7253     else
7254       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7255   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7256   DataArrayInt *ret=DataArrayInt::New();
7257   ret->alloc(nbOfRetVal,1);
7258   int j=0;
7259   int *retPtr=ret->getPointer();
7260   for(int i=0;i<nbOfElement;i++)
7261     if(!tmp[i])
7262       retPtr[j++]=i;
7263   return ret;
7264 }
7265
7266 /*!
7267  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7268  * from an \a other one-dimensional array.
7269  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7270  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7271  *         caller is to delete this array using decrRef() as it is no more needed.
7272  *  \throw If \a other is NULL.
7273  *  \throw If \a other is not allocated.
7274  *  \throw If \a other->getNumberOfComponents() != 1.
7275  *  \throw If \a this is not allocated.
7276  *  \throw If \a this->getNumberOfComponents() != 1.
7277  *  \sa DataArrayInt::buildSubstractionOptimized()
7278  */
7279 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7280 {
7281   if(!other)
7282     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7283   checkAllocated();
7284   other->checkAllocated();
7285   if(getNumberOfComponents()!=1)
7286     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7287   if(other->getNumberOfComponents()!=1)
7288     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7289   const int *pt=getConstPointer();
7290   int nbOfTuples=getNumberOfTuples();
7291   std::set<int> s1(pt,pt+nbOfTuples);
7292   pt=other->getConstPointer();
7293   nbOfTuples=other->getNumberOfTuples();
7294   std::set<int> s2(pt,pt+nbOfTuples);
7295   std::vector<int> r;
7296   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7297   DataArrayInt *ret=DataArrayInt::New();
7298   ret->alloc((int)r.size(),1);
7299   std::copy(r.begin(),r.end(),ret->getPointer());
7300   return ret;
7301 }
7302
7303 /*!
7304  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7305  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7306  * 
7307  * \param [in] other an array with one component and expected to be sorted ascendingly.
7308  * \ret list of ids in \a this but not in \a other.
7309  * \sa DataArrayInt::buildSubstraction
7310  */
7311 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7312 {
7313   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7314   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7315   checkAllocated(); other->checkAllocated();
7316   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7317   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7318   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7319   const int *work1(pt1Bg),*work2(pt2Bg);
7320   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7321   for(;work1!=pt1End;work1++)
7322     {
7323       if(work2!=pt2End && *work1==*work2)
7324         work2++;
7325       else
7326         ret->pushBackSilent(*work1);
7327     }
7328   return ret.retn();
7329 }
7330
7331
7332 /*!
7333  * Returns a new DataArrayInt which contains all elements of \a this and a given
7334  * one-dimensional arrays. The result array does not contain any duplicates
7335  * and its values are sorted in ascending order.
7336  *  \param [in] other - an array to unite with \a this one.
7337  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7338  *         array using decrRef() as it is no more needed.
7339  *  \throw If \a this or \a other is not allocated.
7340  *  \throw If \a this->getNumberOfComponents() != 1.
7341  *  \throw If \a other->getNumberOfComponents() != 1.
7342  */
7343 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7344 {
7345   std::vector<const DataArrayInt *>arrs(2);
7346   arrs[0]=this; arrs[1]=other;
7347   return BuildUnion(arrs);
7348 }
7349
7350
7351 /*!
7352  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7353  * one-dimensional arrays. The result array does not contain any duplicates
7354  * and its values are sorted in ascending order.
7355  *  \param [in] other - an array to intersect with \a this one.
7356  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7357  *         array using decrRef() as it is no more needed.
7358  *  \throw If \a this or \a other is not allocated.
7359  *  \throw If \a this->getNumberOfComponents() != 1.
7360  *  \throw If \a other->getNumberOfComponents() != 1.
7361  */
7362 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7363 {
7364   std::vector<const DataArrayInt *>arrs(2);
7365   arrs[0]=this; arrs[1]=other;
7366   return BuildIntersection(arrs);
7367 }
7368
7369 /*!
7370  * This method can be applied on allocated with one component DataArrayInt instance.
7371  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7372  * 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]
7373  * 
7374  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7375  * \throw if \a this is not allocated or if \a this has not exactly one component.
7376  * \sa DataArrayInt::buildUniqueNotSorted
7377  */
7378 DataArrayInt *DataArrayInt::buildUnique() const
7379 {
7380   checkAllocated();
7381   if(getNumberOfComponents()!=1)
7382     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7383   int nbOfTuples=getNumberOfTuples();
7384   MCAuto<DataArrayInt> tmp=deepCopy();
7385   int *data=tmp->getPointer();
7386   int *last=std::unique(data,data+nbOfTuples);
7387   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7388   ret->alloc(std::distance(data,last),1);
7389   std::copy(data,last,ret->getPointer());
7390   return ret.retn();
7391 }
7392
7393 /*!
7394  * This method can be applied on allocated with one component DataArrayInt instance.
7395  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7396  *
7397  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7398  *
7399  * \throw if \a this is not allocated or if \a this has not exactly one component.
7400  *
7401  * \sa DataArrayInt::buildUnique
7402  */
7403 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7404 {
7405   checkAllocated();
7406     if(getNumberOfComponents()!=1)
7407       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7408   int minVal,maxVal;
7409   getMinMaxValues(minVal,maxVal);
7410   std::vector<bool> b(maxVal-minVal+1,false);
7411   const int *ptBg(begin()),*endBg(end());
7412   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7413   for(const int *pt=ptBg;pt!=endBg;pt++)
7414     {
7415       if(!b[*pt-minVal])
7416         {
7417           ret->pushBackSilent(*pt);
7418           b[*pt-minVal]=true;
7419         }
7420     }
7421   ret->copyStringInfoFrom(*this);
7422   return ret.retn();
7423 }
7424
7425 /*!
7426  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7427  * "index" array. Such "index" array is returned for example by 
7428  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7429  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7430  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7431  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7432  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7433  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7434  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7435  *          The caller is to delete this array using decrRef() as it is no more needed. 
7436  *  \throw If \a this is not allocated.
7437  *  \throw If \a this->getNumberOfComponents() != 1.
7438  *  \throw If \a this->getNumberOfTuples() < 2.
7439  *
7440  *  \b Example: <br> 
7441  *         - this contains [1,3,6,7,7,9,15]
7442  *         - result array contains [2,3,1,0,2,6],
7443  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7444  *
7445  * \sa DataArrayInt::computeOffsetsFull
7446  */
7447 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7448 {
7449   checkAllocated();
7450   if(getNumberOfComponents()!=1)
7451     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7452   int nbOfTuples=getNumberOfTuples();
7453   if(nbOfTuples<2)
7454     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7455   const int *ptr=getConstPointer();
7456   DataArrayInt *ret=DataArrayInt::New();
7457   ret->alloc(nbOfTuples-1,1);
7458   int *out=ret->getPointer();
7459   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7460   return ret;
7461 }
7462
7463 /*!
7464  * Modifies \a this one-dimensional array so that value of each element \a x
7465  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7466  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7467  * and components remains the same.<br>
7468  * This method is useful for allToAllV in MPI with contiguous policy. This method
7469  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7470  * this one.
7471  *  \throw If \a this is not allocated.
7472  *  \throw If \a this->getNumberOfComponents() != 1.
7473  *
7474  *  \b Example: <br>
7475  *          - Before \a this contains [3,5,1,2,0,8]
7476  *          - After \a this contains  [0,3,8,9,11,11]<br>
7477  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7478  *          array is retained and thus there is no space to store the last element.
7479  */
7480 void DataArrayInt::computeOffsets()
7481 {
7482   checkAllocated();
7483   if(getNumberOfComponents()!=1)
7484     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7485   int nbOfTuples=getNumberOfTuples();
7486   if(nbOfTuples==0)
7487     return ;
7488   int *work=getPointer();
7489   int tmp=work[0];
7490   work[0]=0;
7491   for(int i=1;i<nbOfTuples;i++)
7492     {
7493       int tmp2=work[i];
7494       work[i]=work[i-1]+tmp;
7495       tmp=tmp2;
7496     }
7497   declareAsNew();
7498 }
7499
7500
7501 /*!
7502  * Modifies \a this one-dimensional array so that value of each element \a x
7503  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7504  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7505  * components remains the same and number of tuples is inceamented by one.<br>
7506  * This method is useful for allToAllV in MPI with contiguous policy. This method
7507  * differs from computeOffsets() in that the number of tuples is changed by this one.
7508  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7509  *  \throw If \a this is not allocated.
7510  *  \throw If \a this->getNumberOfComponents() != 1.
7511  *
7512  *  \b Example: <br>
7513  *          - Before \a this contains [3,5,1,2,0,8]
7514  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7515  * \sa DataArrayInt::deltaShiftIndex
7516  */
7517 void DataArrayInt::computeOffsetsFull()
7518 {
7519   checkAllocated();
7520   if(getNumberOfComponents()!=1)
7521     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7522   int nbOfTuples=getNumberOfTuples();
7523   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7524   const int *work=getConstPointer();
7525   ret[0]=0;
7526   for(int i=0;i<nbOfTuples;i++)
7527     ret[i+1]=work[i]+ret[i];
7528   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7529   declareAsNew();
7530 }
7531
7532 /*!
7533  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7534  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7535  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7536  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7537  * filling completely one of the ranges in \a this.
7538  *
7539  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7540  * \param [out] rangeIdsFetched the range ids fetched
7541  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7542  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7543  *
7544  * \sa DataArrayInt::computeOffsetsFull
7545  *
7546  *  \b Example: <br>
7547  *          - \a this : [0,3,7,9,15,18]
7548  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7549  *          - \a rangeIdsFetched result array: [0,2,4]
7550  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7551  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7552  * <br>
7553  */
7554 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7555 {
7556   if(!listOfIds)
7557     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7558   listOfIds->checkAllocated(); checkAllocated();
7559   if(listOfIds->getNumberOfComponents()!=1)
7560     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7561   if(getNumberOfComponents()!=1)
7562     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7563   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7564   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7565   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7566   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7567   while(tupPtr!=tupEnd && offPtr!=offEnd)
7568     {
7569       if(*tupPtr==*offPtr)
7570         {
7571           int i=offPtr[0];
7572           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7573           if(i==offPtr[1])
7574             {
7575               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7576               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7577               offPtr++;
7578             }
7579         }
7580       else
7581         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7582     }
7583   rangeIdsFetched=ret0.retn();
7584   idsInInputListThatFetch=ret1.retn();
7585 }
7586
7587 /*!
7588  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7589  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7590  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7591  * beginning within the "iota" array. And \a this is a one-dimensional array
7592  * considered as a selector of groups described by \a offsets to include into the result array.
7593  *  \throw If \a offsets is NULL.
7594  *  \throw If \a offsets is not allocated.
7595  *  \throw If \a offsets->getNumberOfComponents() != 1.
7596  *  \throw If \a offsets is not monotonically increasing.
7597  *  \throw If \a this is not allocated.
7598  *  \throw If \a this->getNumberOfComponents() != 1.
7599  *  \throw If any element of \a this is not a valid index for \a offsets array.
7600  *
7601  *  \b Example: <br>
7602  *          - \a this: [0,2,3]
7603  *          - \a offsets: [0,3,6,10,14,20]
7604  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7605  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7606  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7607  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7608  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7609  */
7610 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7611 {
7612   if(!offsets)
7613     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7614   checkAllocated();
7615   if(getNumberOfComponents()!=1)
7616     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7617   offsets->checkAllocated();
7618   if(offsets->getNumberOfComponents()!=1)
7619     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7620   int othNbTuples=offsets->getNumberOfTuples()-1;
7621   int nbOfTuples=getNumberOfTuples();
7622   int retNbOftuples=0;
7623   const int *work=getConstPointer();
7624   const int *offPtr=offsets->getConstPointer();
7625   for(int i=0;i<nbOfTuples;i++)
7626     {
7627       int val=work[i];
7628       if(val>=0 && val<othNbTuples)
7629         {
7630           int delta=offPtr[val+1]-offPtr[val];
7631           if(delta>=0)
7632             retNbOftuples+=delta;
7633           else
7634             {
7635               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7636               throw INTERP_KERNEL::Exception(oss.str().c_str());
7637             }
7638         }
7639       else
7640         {
7641           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7642           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7643           throw INTERP_KERNEL::Exception(oss.str().c_str());
7644         }
7645     }
7646   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7647   ret->alloc(retNbOftuples,1);
7648   int *retPtr=ret->getPointer();
7649   for(int i=0;i<nbOfTuples;i++)
7650     {
7651       int val=work[i];
7652       int start=offPtr[val];
7653       int off=offPtr[val+1]-start;
7654       for(int j=0;j<off;j++,retPtr++)
7655         *retPtr=start+j;
7656     }
7657   return ret.retn();
7658 }
7659
7660 /*!
7661  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7662  * scaled array (monotonically increasing).
7663 from that of \a this and \a
7664  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7665  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7666  * beginning within the "iota" array. And \a this is a one-dimensional array
7667  * considered as a selector of groups described by \a offsets to include into the result array.
7668  *  \throw If \a  is NULL.
7669  *  \throw If \a this is not allocated.
7670  *  \throw If \a this->getNumberOfComponents() != 1.
7671  *  \throw If \a this->getNumberOfTuples() == 0.
7672  *  \throw If \a this is not monotonically increasing.
7673  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7674  *
7675  *  \b Example: <br>
7676  *          - \a bg , \a stop and \a step : (0,5,2)
7677  *          - \a this: [0,3,6,10,14,20]
7678  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7679  */
7680 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7681 {
7682   if(!isAllocated())
7683     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7684   if(getNumberOfComponents()!=1)
7685     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7686   int nbOfTuples(getNumberOfTuples());
7687   if(nbOfTuples==0)
7688     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7689   const int *ids(begin());
7690   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7691   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7692     {
7693       if(pos>=0 && pos<nbOfTuples-1)
7694         {
7695           int delta(ids[pos+1]-ids[pos]);
7696           sz+=delta;
7697           if(delta<0)
7698             {
7699               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7700               throw INTERP_KERNEL::Exception(oss.str().c_str());
7701             }          
7702         }
7703       else
7704         {
7705           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7706           throw INTERP_KERNEL::Exception(oss.str().c_str());
7707         }
7708     }
7709   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7710   int *retPtr(ret->getPointer());
7711   pos=bg;
7712   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7713     {
7714       int delta(ids[pos+1]-ids[pos]);
7715       for(int j=0;j<delta;j++,retPtr++)
7716         *retPtr=pos;
7717     }
7718   return ret.retn();
7719 }
7720
7721 /*!
7722  * 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.
7723  * 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
7724  * in tuple **i** of returned DataArrayInt.
7725  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7726  *
7727  * 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)]
7728  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7729  * 
7730  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7731  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7732  * \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
7733  *        is thrown if no ranges in \a ranges contains value in \a this.
7734  * 
7735  * \sa DataArrayInt::findIdInRangeForEachTuple
7736  */
7737 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7738 {
7739   if(!ranges)
7740     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7741   if(ranges->getNumberOfComponents()!=2)
7742     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7743   checkAllocated();
7744   if(getNumberOfComponents()!=1)
7745     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7746   int nbTuples=getNumberOfTuples();
7747   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7748   int nbOfRanges=ranges->getNumberOfTuples();
7749   const int *rangesPtr=ranges->getConstPointer();
7750   int *retPtr=ret->getPointer();
7751   const int *inPtr=getConstPointer();
7752   for(int i=0;i<nbTuples;i++,retPtr++)
7753     {
7754       int val=inPtr[i];
7755       bool found=false;
7756       for(int j=0;j<nbOfRanges && !found;j++)
7757         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7758           { *retPtr=j; found=true; }
7759       if(found)
7760         continue;
7761       else
7762         {
7763           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7764           throw INTERP_KERNEL::Exception(oss.str().c_str());
7765         }
7766     }
7767   return ret.retn();
7768 }
7769
7770 /*!
7771  * 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.
7772  * 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
7773  * in tuple **i** of returned DataArrayInt.
7774  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7775  *
7776  * 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)]
7777  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7778  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7779  * 
7780  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7781  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7782  * \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
7783  *        is thrown if no ranges in \a ranges contains value in \a this.
7784  * \sa DataArrayInt::findRangeIdForEachTuple
7785  */
7786 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7787 {
7788   if(!ranges)
7789     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7790   if(ranges->getNumberOfComponents()!=2)
7791     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7792   checkAllocated();
7793   if(getNumberOfComponents()!=1)
7794     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7795   int nbTuples=getNumberOfTuples();
7796   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7797   int nbOfRanges=ranges->getNumberOfTuples();
7798   const int *rangesPtr=ranges->getConstPointer();
7799   int *retPtr=ret->getPointer();
7800   const int *inPtr=getConstPointer();
7801   for(int i=0;i<nbTuples;i++,retPtr++)
7802     {
7803       int val=inPtr[i];
7804       bool found=false;
7805       for(int j=0;j<nbOfRanges && !found;j++)
7806         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7807           { *retPtr=val-rangesPtr[2*j]; found=true; }
7808       if(found)
7809         continue;
7810       else
7811         {
7812           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7813           throw INTERP_KERNEL::Exception(oss.str().c_str());
7814         }
7815     }
7816   return ret.retn();
7817 }
7818
7819 /*!
7820  * \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).
7821  * 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).
7822  * 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 !
7823  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7824  * This method does nothing if number of tuples is lower of equal to 1.
7825  *
7826  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7827  *
7828  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
7829  */
7830 void DataArrayInt::sortEachPairToMakeALinkedList()
7831 {
7832   checkAllocated();
7833   if(getNumberOfComponents()!=2)
7834     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7835   int nbOfTuples(getNumberOfTuples());
7836   if(nbOfTuples<=1)
7837     return ;
7838   int *conn(getPointer());
7839   for(int i=1;i<nbOfTuples;i++,conn+=2)
7840     {
7841       if(i>1)
7842         {
7843           if(conn[2]==conn[3])
7844             {
7845               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7846               throw INTERP_KERNEL::Exception(oss.str().c_str());
7847             }
7848           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
7849             std::swap(conn[2],conn[3]);
7850           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
7851           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
7852             {
7853               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
7854               throw INTERP_KERNEL::Exception(oss.str().c_str());
7855             }
7856         }
7857       else
7858         {
7859           if(conn[0]==conn[1] || conn[2]==conn[3])
7860             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
7861           int tmp[4];
7862           std::set<int> s;
7863           s.insert(conn,conn+4);
7864           if(s.size()!=3)
7865             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
7866           if(std::count(conn,conn+4,conn[0])==2)
7867             {
7868               tmp[0]=conn[1];
7869               tmp[1]=conn[0];
7870               tmp[2]=conn[0];
7871               if(conn[2]==conn[0])
7872                 { tmp[3]=conn[3]; }
7873               else
7874                 { tmp[3]=conn[2];}
7875               std::copy(tmp,tmp+4,conn);
7876             }
7877           else
7878             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
7879               if(conn[1]==conn[3])
7880                 std::swap(conn[2],conn[3]);
7881             }
7882         }
7883     }
7884 }
7885
7886 /*!
7887  * 
7888  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
7889  *             \a nbTimes  should be at least equal to 1.
7890  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
7891  * \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.
7892  */
7893 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
7894 {
7895   checkAllocated();
7896   if(getNumberOfComponents()!=1)
7897     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
7898   if(nbTimes<1)
7899     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
7900   int nbTuples=getNumberOfTuples();
7901   const int *inPtr=getConstPointer();
7902   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
7903   int *retPtr=ret->getPointer();
7904   for(int i=0;i<nbTuples;i++,inPtr++)
7905     {
7906       int val=*inPtr;
7907       for(int j=0;j<nbTimes;j++,retPtr++)
7908         *retPtr=val;
7909     }
7910   ret->copyStringInfoFrom(*this);
7911   return ret.retn();
7912 }
7913
7914 /*!
7915  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
7916  * But the number of components can be different from one.
7917  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
7918  */
7919 DataArrayInt *DataArrayInt::getDifferentValues() const
7920 {
7921   checkAllocated();
7922   std::set<int> ret;
7923   ret.insert(begin(),end());
7924   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
7925   std::copy(ret.begin(),ret.end(),ret2->getPointer());
7926   return ret2.retn();
7927 }
7928
7929 /*!
7930  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
7931  * them it tells which tuple id have this id.
7932  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
7933  * This method returns two arrays having same size.
7934  * 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.
7935  * 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]]
7936  */
7937 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
7938 {
7939   checkAllocated();
7940   if(getNumberOfComponents()!=1)
7941     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
7942   int id=0;
7943   std::map<int,int> m,m2,m3;
7944   for(const int *w=begin();w!=end();w++)
7945     m[*w]++;
7946   differentIds.resize(m.size());
7947   std::vector<DataArrayInt *> ret(m.size());
7948   std::vector<int *> retPtr(m.size());
7949   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
7950     {
7951       m2[(*it).first]=id;
7952       ret[id]=DataArrayInt::New();
7953       ret[id]->alloc((*it).second,1);
7954       retPtr[id]=ret[id]->getPointer();
7955       differentIds[id]=(*it).first;
7956     }
7957   id=0;
7958   for(const int *w=begin();w!=end();w++,id++)
7959     {
7960       retPtr[m2[*w]][m3[*w]++]=id;
7961     }
7962   return ret;
7963 }
7964
7965 /*!
7966  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
7967  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
7968  *
7969  * \param [in] nbOfSlices - number of slices expected.
7970  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
7971  * 
7972  * \sa DataArray::GetSlice
7973  * \throw If \a this is not allocated or not with exactly one component.
7974  * \throw If an element in \a this if < 0.
7975  */
7976 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
7977 {
7978   if(!isAllocated() || getNumberOfComponents()!=1)
7979     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
7980   if(nbOfSlices<=0)
7981     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
7982   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
7983   int sumPerSlc(sum/nbOfSlices),pos(0);
7984   const int *w(begin());
7985   std::vector< std::pair<int,int> > ret(nbOfSlices);
7986   for(int i=0;i<nbOfSlices;i++)
7987     {
7988       std::pair<int,int> p(pos,-1);
7989       int locSum(0);
7990       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
7991       if(i!=nbOfSlices-1)
7992         p.second=pos;
7993       else
7994         p.second=nbOfTuples;
7995       ret[i]=p;
7996     }
7997   return ret;
7998 }
7999
8000 /*!
8001  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8002  * valid cases.
8003  * 1.  The arrays have same number of tuples and components. Then each value of
8004  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8005  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8006  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8007  *   component. Then
8008  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8009  * 3.  The arrays have same number of components and one array, say _a2_, has one
8010  *   tuple. Then
8011  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8012  *
8013  * Info on components is copied either from the first array (in the first case) or from
8014  * the array with maximal number of elements (getNbOfElems()).
8015  *  \param [in] a1 - an array to sum up.
8016  *  \param [in] a2 - another array to sum up.
8017  *  \return DataArrayInt * - the new instance of DataArrayInt.
8018  *          The caller is to delete this result array using decrRef() as it is no more
8019  *          needed.
8020  *  \throw If either \a a1 or \a a2 is NULL.
8021  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8022  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8023  *         none of them has number of tuples or components equal to 1.
8024  */
8025 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8026 {
8027   if(!a1 || !a2)
8028     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8029   int nbOfTuple=a1->getNumberOfTuples();
8030   int nbOfTuple2=a2->getNumberOfTuples();
8031   int nbOfComp=a1->getNumberOfComponents();
8032   int nbOfComp2=a2->getNumberOfComponents();
8033   MCAuto<DataArrayInt> ret=0;
8034   if(nbOfTuple==nbOfTuple2)
8035     {
8036       if(nbOfComp==nbOfComp2)
8037         {
8038           ret=DataArrayInt::New();
8039           ret->alloc(nbOfTuple,nbOfComp);
8040           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8041           ret->copyStringInfoFrom(*a1);
8042         }
8043       else
8044         {
8045           int nbOfCompMin,nbOfCompMax;
8046           const DataArrayInt *aMin, *aMax;
8047           if(nbOfComp>nbOfComp2)
8048             {
8049               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8050               aMin=a2; aMax=a1;
8051             }
8052           else
8053             {
8054               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8055               aMin=a1; aMax=a2;
8056             }
8057           if(nbOfCompMin==1)
8058             {
8059               ret=DataArrayInt::New();
8060               ret->alloc(nbOfTuple,nbOfCompMax);
8061               const int *aMinPtr=aMin->getConstPointer();
8062               const int *aMaxPtr=aMax->getConstPointer();
8063               int *res=ret->getPointer();
8064               for(int i=0;i<nbOfTuple;i++)
8065                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8066               ret->copyStringInfoFrom(*aMax);
8067             }
8068           else
8069             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8070         }
8071     }
8072   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8073     {
8074       if(nbOfComp==nbOfComp2)
8075         {
8076           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8077           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8078           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8079           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8080           ret=DataArrayInt::New();
8081           ret->alloc(nbOfTupleMax,nbOfComp);
8082           int *res=ret->getPointer();
8083           for(int i=0;i<nbOfTupleMax;i++)
8084             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8085           ret->copyStringInfoFrom(*aMax);
8086         }
8087       else
8088         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8089     }
8090   else
8091     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8092   return ret.retn();
8093 }
8094
8095 /*!
8096  * Adds values of another DataArrayInt to values of \a this one. There are 3
8097  * valid cases.
8098  * 1.  The arrays have same number of tuples and components. Then each value of
8099  *   \a other array is added to the corresponding value of \a this array, i.e.:
8100  *   _a_ [ i, j ] += _other_ [ i, j ].
8101  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8102  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8103  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8104  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8105  *
8106  *  \param [in] other - an array to add to \a this one.
8107  *  \throw If \a other is NULL.
8108  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8109  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8110  *         \a other has number of both tuples and components not equal to 1.
8111  */
8112 void DataArrayInt::addEqual(const DataArrayInt *other)
8113 {
8114   if(!other)
8115     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8116   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8117   checkAllocated(); other->checkAllocated();
8118   int nbOfTuple=getNumberOfTuples();
8119   int nbOfTuple2=other->getNumberOfTuples();
8120   int nbOfComp=getNumberOfComponents();
8121   int nbOfComp2=other->getNumberOfComponents();
8122   if(nbOfTuple==nbOfTuple2)
8123     {
8124       if(nbOfComp==nbOfComp2)
8125         {
8126           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8127         }
8128       else if(nbOfComp2==1)
8129         {
8130           int *ptr=getPointer();
8131           const int *ptrc=other->getConstPointer();
8132           for(int i=0;i<nbOfTuple;i++)
8133             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8134         }
8135       else
8136         throw INTERP_KERNEL::Exception(msg);
8137     }
8138   else if(nbOfTuple2==1)
8139     {
8140       if(nbOfComp2==nbOfComp)
8141         {
8142           int *ptr=getPointer();
8143           const int *ptrc=other->getConstPointer();
8144           for(int i=0;i<nbOfTuple;i++)
8145             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8146         }
8147       else
8148         throw INTERP_KERNEL::Exception(msg);
8149     }
8150   else
8151     throw INTERP_KERNEL::Exception(msg);
8152   declareAsNew();
8153 }
8154
8155 /*!
8156  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8157  * valid cases.
8158  * 1.  The arrays have same number of tuples and components. Then each value of
8159  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8160  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8161  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8162  *   component. Then
8163  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8164  * 3.  The arrays have same number of components and one array, say _a2_, has one
8165  *   tuple. Then
8166  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8167  *
8168  * Info on components is copied either from the first array (in the first case) or from
8169  * the array with maximal number of elements (getNbOfElems()).
8170  *  \param [in] a1 - an array to subtract from.
8171  *  \param [in] a2 - an array to subtract.
8172  *  \return DataArrayInt * - the new instance of DataArrayInt.
8173  *          The caller is to delete this result array using decrRef() as it is no more
8174  *          needed.
8175  *  \throw If either \a a1 or \a a2 is NULL.
8176  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8177  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8178  *         none of them has number of tuples or components equal to 1.
8179  */
8180 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8181 {
8182   if(!a1 || !a2)
8183     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8184   int nbOfTuple1=a1->getNumberOfTuples();
8185   int nbOfTuple2=a2->getNumberOfTuples();
8186   int nbOfComp1=a1->getNumberOfComponents();
8187   int nbOfComp2=a2->getNumberOfComponents();
8188   if(nbOfTuple2==nbOfTuple1)
8189     {
8190       if(nbOfComp1==nbOfComp2)
8191         {
8192           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8193           ret->alloc(nbOfTuple2,nbOfComp1);
8194           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8195           ret->copyStringInfoFrom(*a1);
8196           return ret.retn();
8197         }
8198       else if(nbOfComp2==1)
8199         {
8200           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8201           ret->alloc(nbOfTuple1,nbOfComp1);
8202           const int *a2Ptr=a2->getConstPointer();
8203           const int *a1Ptr=a1->getConstPointer();
8204           int *res=ret->getPointer();
8205           for(int i=0;i<nbOfTuple1;i++)
8206             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8207           ret->copyStringInfoFrom(*a1);
8208           return ret.retn();
8209         }
8210       else
8211         {
8212           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8213           return 0;
8214         }
8215     }
8216   else if(nbOfTuple2==1)
8217     {
8218       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8219       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8220       ret->alloc(nbOfTuple1,nbOfComp1);
8221       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8222       int *pt=ret->getPointer();
8223       for(int i=0;i<nbOfTuple1;i++)
8224         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8225       ret->copyStringInfoFrom(*a1);
8226       return ret.retn();
8227     }
8228   else
8229     {
8230       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8231       return 0;
8232     }
8233 }
8234
8235 /*!
8236  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8237  * valid cases.
8238  * 1.  The arrays have same number of tuples and components. Then each value of
8239  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8240  *   _a_ [ i, j ] -= _other_ [ i, j ].
8241  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8242  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8243  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8244  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8245  *
8246  *  \param [in] other - an array to subtract from \a this one.
8247  *  \throw If \a other is NULL.
8248  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8249  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8250  *         \a other has number of both tuples and components not equal to 1.
8251  */
8252 void DataArrayInt::substractEqual(const DataArrayInt *other)
8253 {
8254   if(!other)
8255     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8256   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8257   checkAllocated(); other->checkAllocated();
8258   int nbOfTuple=getNumberOfTuples();
8259   int nbOfTuple2=other->getNumberOfTuples();
8260   int nbOfComp=getNumberOfComponents();
8261   int nbOfComp2=other->getNumberOfComponents();
8262   if(nbOfTuple==nbOfTuple2)
8263     {
8264       if(nbOfComp==nbOfComp2)
8265         {
8266           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8267         }
8268       else if(nbOfComp2==1)
8269         {
8270           int *ptr=getPointer();
8271           const int *ptrc=other->getConstPointer();
8272           for(int i=0;i<nbOfTuple;i++)
8273             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8274         }
8275       else
8276         throw INTERP_KERNEL::Exception(msg);
8277     }
8278   else if(nbOfTuple2==1)
8279     {
8280       int *ptr=getPointer();
8281       const int *ptrc=other->getConstPointer();
8282       for(int i=0;i<nbOfTuple;i++)
8283         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8284     }
8285   else
8286     throw INTERP_KERNEL::Exception(msg);
8287   declareAsNew();
8288 }
8289
8290 /*!
8291  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8292  * valid cases.
8293  * 1.  The arrays have same number of tuples and components. Then each value of
8294  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8295  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8296  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8297  *   component. Then
8298  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8299  * 3.  The arrays have same number of components and one array, say _a2_, has one
8300  *   tuple. Then
8301  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8302  *
8303  * Info on components is copied either from the first array (in the first case) or from
8304  * the array with maximal number of elements (getNbOfElems()).
8305  *  \param [in] a1 - a factor array.
8306  *  \param [in] a2 - another factor array.
8307  *  \return DataArrayInt * - the new instance of DataArrayInt.
8308  *          The caller is to delete this result array using decrRef() as it is no more
8309  *          needed.
8310  *  \throw If either \a a1 or \a a2 is NULL.
8311  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8312  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8313  *         none of them has number of tuples or components equal to 1.
8314  */
8315 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8316 {
8317   if(!a1 || !a2)
8318     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8319   int nbOfTuple=a1->getNumberOfTuples();
8320   int nbOfTuple2=a2->getNumberOfTuples();
8321   int nbOfComp=a1->getNumberOfComponents();
8322   int nbOfComp2=a2->getNumberOfComponents();
8323   MCAuto<DataArrayInt> ret=0;
8324   if(nbOfTuple==nbOfTuple2)
8325     {
8326       if(nbOfComp==nbOfComp2)
8327         {
8328           ret=DataArrayInt::New();
8329           ret->alloc(nbOfTuple,nbOfComp);
8330           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8331           ret->copyStringInfoFrom(*a1);
8332         }
8333       else
8334         {
8335           int nbOfCompMin,nbOfCompMax;
8336           const DataArrayInt *aMin, *aMax;
8337           if(nbOfComp>nbOfComp2)
8338             {
8339               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8340               aMin=a2; aMax=a1;
8341             }
8342           else
8343             {
8344               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8345               aMin=a1; aMax=a2;
8346             }
8347           if(nbOfCompMin==1)
8348             {
8349               ret=DataArrayInt::New();
8350               ret->alloc(nbOfTuple,nbOfCompMax);
8351               const int *aMinPtr=aMin->getConstPointer();
8352               const int *aMaxPtr=aMax->getConstPointer();
8353               int *res=ret->getPointer();
8354               for(int i=0;i<nbOfTuple;i++)
8355                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8356               ret->copyStringInfoFrom(*aMax);
8357             }
8358           else
8359             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8360         }
8361     }
8362   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8363     {
8364       if(nbOfComp==nbOfComp2)
8365         {
8366           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8367           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8368           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8369           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8370           ret=DataArrayInt::New();
8371           ret->alloc(nbOfTupleMax,nbOfComp);
8372           int *res=ret->getPointer();
8373           for(int i=0;i<nbOfTupleMax;i++)
8374             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8375           ret->copyStringInfoFrom(*aMax);
8376         }
8377       else
8378         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8379     }
8380   else
8381     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8382   return ret.retn();
8383 }
8384
8385
8386 /*!
8387  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8388  * valid cases.
8389  * 1.  The arrays have same number of tuples and components. Then each value of
8390  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8391  *   _a_ [ i, j ] *= _other_ [ i, j ].
8392  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8393  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8394  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8395  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8396  *
8397  *  \param [in] other - an array to multiply to \a this one.
8398  *  \throw If \a other is NULL.
8399  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8400  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8401  *         \a other has number of both tuples and components not equal to 1.
8402  */
8403 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8404 {
8405   if(!other)
8406     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8407   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8408   checkAllocated(); other->checkAllocated();
8409   int nbOfTuple=getNumberOfTuples();
8410   int nbOfTuple2=other->getNumberOfTuples();
8411   int nbOfComp=getNumberOfComponents();
8412   int nbOfComp2=other->getNumberOfComponents();
8413   if(nbOfTuple==nbOfTuple2)
8414     {
8415       if(nbOfComp==nbOfComp2)
8416         {
8417           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8418         }
8419       else if(nbOfComp2==1)
8420         {
8421           int *ptr=getPointer();
8422           const int *ptrc=other->getConstPointer();
8423           for(int i=0;i<nbOfTuple;i++)
8424             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8425         }
8426       else
8427         throw INTERP_KERNEL::Exception(msg);
8428     }
8429   else if(nbOfTuple2==1)
8430     {
8431       if(nbOfComp2==nbOfComp)
8432         {
8433           int *ptr=getPointer();
8434           const int *ptrc=other->getConstPointer();
8435           for(int i=0;i<nbOfTuple;i++)
8436             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8437         }
8438       else
8439         throw INTERP_KERNEL::Exception(msg);
8440     }
8441   else
8442     throw INTERP_KERNEL::Exception(msg);
8443   declareAsNew();
8444 }
8445
8446
8447 /*!
8448  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8449  * valid cases.
8450  * 1.  The arrays have same number of tuples and components. Then each value of
8451  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8452  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8453  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8454  *   component. Then
8455  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8456  * 3.  The arrays have same number of components and one array, say _a2_, has one
8457  *   tuple. Then
8458  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8459  *
8460  * Info on components is copied either from the first array (in the first case) or from
8461  * the array with maximal number of elements (getNbOfElems()).
8462  *  \warning No check of division by zero is performed!
8463  *  \param [in] a1 - a numerator array.
8464  *  \param [in] a2 - a denominator array.
8465  *  \return DataArrayInt * - the new instance of DataArrayInt.
8466  *          The caller is to delete this result array using decrRef() as it is no more
8467  *          needed.
8468  *  \throw If either \a a1 or \a a2 is NULL.
8469  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8470  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8471  *         none of them has number of tuples or components equal to 1.
8472  */
8473 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8474 {
8475   if(!a1 || !a2)
8476     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8477   int nbOfTuple1=a1->getNumberOfTuples();
8478   int nbOfTuple2=a2->getNumberOfTuples();
8479   int nbOfComp1=a1->getNumberOfComponents();
8480   int nbOfComp2=a2->getNumberOfComponents();
8481   if(nbOfTuple2==nbOfTuple1)
8482     {
8483       if(nbOfComp1==nbOfComp2)
8484         {
8485           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8486           ret->alloc(nbOfTuple2,nbOfComp1);
8487           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8488           ret->copyStringInfoFrom(*a1);
8489           return ret.retn();
8490         }
8491       else if(nbOfComp2==1)
8492         {
8493           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8494           ret->alloc(nbOfTuple1,nbOfComp1);
8495           const int *a2Ptr=a2->getConstPointer();
8496           const int *a1Ptr=a1->getConstPointer();
8497           int *res=ret->getPointer();
8498           for(int i=0;i<nbOfTuple1;i++)
8499             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8500           ret->copyStringInfoFrom(*a1);
8501           return ret.retn();
8502         }
8503       else
8504         {
8505           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8506           return 0;
8507         }
8508     }
8509   else if(nbOfTuple2==1)
8510     {
8511       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8512       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8513       ret->alloc(nbOfTuple1,nbOfComp1);
8514       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8515       int *pt=ret->getPointer();
8516       for(int i=0;i<nbOfTuple1;i++)
8517         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8518       ret->copyStringInfoFrom(*a1);
8519       return ret.retn();
8520     }
8521   else
8522     {
8523       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8524       return 0;
8525     }
8526 }
8527
8528 /*!
8529  * Divide values of \a this array by values of another DataArrayInt. There are 3
8530  * valid cases.
8531  * 1.  The arrays have same number of tuples and components. Then each value of
8532  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8533  *   _a_ [ i, j ] /= _other_ [ i, j ].
8534  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8535  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8536  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8537  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8538  *
8539  *  \warning No check of division by zero is performed!
8540  *  \param [in] other - an array to divide \a this one by.
8541  *  \throw If \a other is NULL.
8542  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8543  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8544  *         \a other has number of both tuples and components not equal to 1.
8545  */
8546 void DataArrayInt::divideEqual(const DataArrayInt *other)
8547 {
8548   if(!other)
8549     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8550   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8551   checkAllocated(); other->checkAllocated();
8552   int nbOfTuple=getNumberOfTuples();
8553   int nbOfTuple2=other->getNumberOfTuples();
8554   int nbOfComp=getNumberOfComponents();
8555   int nbOfComp2=other->getNumberOfComponents();
8556   if(nbOfTuple==nbOfTuple2)
8557     {
8558       if(nbOfComp==nbOfComp2)
8559         {
8560           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8561         }
8562       else if(nbOfComp2==1)
8563         {
8564           int *ptr=getPointer();
8565           const int *ptrc=other->getConstPointer();
8566           for(int i=0;i<nbOfTuple;i++)
8567             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8568         }
8569       else
8570         throw INTERP_KERNEL::Exception(msg);
8571     }
8572   else if(nbOfTuple2==1)
8573     {
8574       if(nbOfComp2==nbOfComp)
8575         {
8576           int *ptr=getPointer();
8577           const int *ptrc=other->getConstPointer();
8578           for(int i=0;i<nbOfTuple;i++)
8579             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8580         }
8581       else
8582         throw INTERP_KERNEL::Exception(msg);
8583     }
8584   else
8585     throw INTERP_KERNEL::Exception(msg);
8586   declareAsNew();
8587 }
8588
8589
8590 /*!
8591  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8592  * valid cases.
8593  * 1.  The arrays have same number of tuples and components. Then each value of
8594  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8595  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8596  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8597  *   component. Then
8598  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8599  * 3.  The arrays have same number of components and one array, say _a2_, has one
8600  *   tuple. Then
8601  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8602  *
8603  * Info on components is copied either from the first array (in the first case) or from
8604  * the array with maximal number of elements (getNbOfElems()).
8605  *  \warning No check of division by zero is performed!
8606  *  \param [in] a1 - a dividend array.
8607  *  \param [in] a2 - a divisor array.
8608  *  \return DataArrayInt * - the new instance of DataArrayInt.
8609  *          The caller is to delete this result array using decrRef() as it is no more
8610  *          needed.
8611  *  \throw If either \a a1 or \a a2 is NULL.
8612  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8613  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8614  *         none of them has number of tuples or components equal to 1.
8615  */
8616 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8617 {
8618   if(!a1 || !a2)
8619     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8620   int nbOfTuple1=a1->getNumberOfTuples();
8621   int nbOfTuple2=a2->getNumberOfTuples();
8622   int nbOfComp1=a1->getNumberOfComponents();
8623   int nbOfComp2=a2->getNumberOfComponents();
8624   if(nbOfTuple2==nbOfTuple1)
8625     {
8626       if(nbOfComp1==nbOfComp2)
8627         {
8628           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8629           ret->alloc(nbOfTuple2,nbOfComp1);
8630           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8631           ret->copyStringInfoFrom(*a1);
8632           return ret.retn();
8633         }
8634       else if(nbOfComp2==1)
8635         {
8636           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8637           ret->alloc(nbOfTuple1,nbOfComp1);
8638           const int *a2Ptr=a2->getConstPointer();
8639           const int *a1Ptr=a1->getConstPointer();
8640           int *res=ret->getPointer();
8641           for(int i=0;i<nbOfTuple1;i++)
8642             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8643           ret->copyStringInfoFrom(*a1);
8644           return ret.retn();
8645         }
8646       else
8647         {
8648           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8649           return 0;
8650         }
8651     }
8652   else if(nbOfTuple2==1)
8653     {
8654       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8655       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8656       ret->alloc(nbOfTuple1,nbOfComp1);
8657       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8658       int *pt=ret->getPointer();
8659       for(int i=0;i<nbOfTuple1;i++)
8660         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8661       ret->copyStringInfoFrom(*a1);
8662       return ret.retn();
8663     }
8664   else
8665     {
8666       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8667       return 0;
8668     }
8669 }
8670
8671 /*!
8672  * Modify \a this array so that each value becomes a modulus of division of this value by
8673  * a value of another DataArrayInt. There are 3 valid cases.
8674  * 1.  The arrays have same number of tuples and components. Then each value of
8675  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8676  *   _a_ [ i, j ] %= _other_ [ i, j ].
8677  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8678  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8679  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8680  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8681  *
8682  *  \warning No check of division by zero is performed!
8683  *  \param [in] other - a divisor array.
8684  *  \throw If \a other is NULL.
8685  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8686  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8687  *         \a other has number of both tuples and components not equal to 1.
8688  */
8689 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8690 {
8691   if(!other)
8692     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8693   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8694   checkAllocated(); other->checkAllocated();
8695   int nbOfTuple=getNumberOfTuples();
8696   int nbOfTuple2=other->getNumberOfTuples();
8697   int nbOfComp=getNumberOfComponents();
8698   int nbOfComp2=other->getNumberOfComponents();
8699   if(nbOfTuple==nbOfTuple2)
8700     {
8701       if(nbOfComp==nbOfComp2)
8702         {
8703           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8704         }
8705       else if(nbOfComp2==1)
8706         {
8707           if(nbOfComp2==nbOfComp)
8708             {
8709               int *ptr=getPointer();
8710               const int *ptrc=other->getConstPointer();
8711               for(int i=0;i<nbOfTuple;i++)
8712                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8713             }
8714           else
8715             throw INTERP_KERNEL::Exception(msg);
8716         }
8717       else
8718         throw INTERP_KERNEL::Exception(msg);
8719     }
8720   else if(nbOfTuple2==1)
8721     {
8722       int *ptr=getPointer();
8723       const int *ptrc=other->getConstPointer();
8724       for(int i=0;i<nbOfTuple;i++)
8725         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8726     }
8727   else
8728     throw INTERP_KERNEL::Exception(msg);
8729   declareAsNew();
8730 }
8731
8732 /*!
8733  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8734  * valid cases.
8735  *
8736  *  \param [in] a1 - an array to pow up.
8737  *  \param [in] a2 - another array to sum up.
8738  *  \return DataArrayInt * - the new instance of DataArrayInt.
8739  *          The caller is to delete this result array using decrRef() as it is no more
8740  *          needed.
8741  *  \throw If either \a a1 or \a a2 is NULL.
8742  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8743  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8744  *  \throw If there is a negative value in \a a2.
8745  */
8746 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8747 {
8748   if(!a1 || !a2)
8749     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8750   int nbOfTuple=a1->getNumberOfTuples();
8751   int nbOfTuple2=a2->getNumberOfTuples();
8752   int nbOfComp=a1->getNumberOfComponents();
8753   int nbOfComp2=a2->getNumberOfComponents();
8754   if(nbOfTuple!=nbOfTuple2)
8755     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8756   if(nbOfComp!=1 || nbOfComp2!=1)
8757     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8758   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8759   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8760   int *ptr=ret->getPointer();
8761   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8762     {
8763       if(*ptr2>=0)
8764         {
8765           int tmp=1;
8766           for(int j=0;j<*ptr2;j++)
8767             tmp*=*ptr1;
8768           *ptr=tmp;
8769         }
8770       else
8771         {
8772           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8773           throw INTERP_KERNEL::Exception(oss.str().c_str());
8774         }
8775     }
8776   return ret.retn();
8777 }
8778
8779 /*!
8780  * Apply pow on values of another DataArrayInt to values of \a this one.
8781  *
8782  *  \param [in] other - an array to pow to \a this one.
8783  *  \throw If \a other is NULL.
8784  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8785  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8786  *  \throw If there is a negative value in \a other.
8787  */
8788 void DataArrayInt::powEqual(const DataArrayInt *other)
8789 {
8790   if(!other)
8791     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8792   int nbOfTuple=getNumberOfTuples();
8793   int nbOfTuple2=other->getNumberOfTuples();
8794   int nbOfComp=getNumberOfComponents();
8795   int nbOfComp2=other->getNumberOfComponents();
8796   if(nbOfTuple!=nbOfTuple2)
8797     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8798   if(nbOfComp!=1 || nbOfComp2!=1)
8799     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8800   int *ptr=getPointer();
8801   const int *ptrc=other->begin();
8802   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8803     {
8804       if(*ptrc>=0)
8805         {
8806           int tmp=1;
8807           for(int j=0;j<*ptrc;j++)
8808             tmp*=*ptr;
8809           *ptr=tmp;
8810         }
8811       else
8812         {
8813           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8814           throw INTERP_KERNEL::Exception(oss.str().c_str());
8815         }
8816     }
8817   declareAsNew();
8818 }
8819
8820 /*!
8821  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8822  * This map, if applied to \a start array, would make it sorted. For example, if
8823  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8824  * [5,6,0,3,2,7,1,4].
8825  *  \param [in] start - pointer to the first element of the array for which the
8826  *         permutation map is computed.
8827  *  \param [in] end - pointer specifying the end of the array \a start, so that
8828  *         the last value of \a start is \a end[ -1 ].
8829  *  \return int * - the result permutation array that the caller is to delete as it is no
8830  *         more needed.
8831  *  \throw If there are equal values in the input array.
8832  */
8833 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
8834 {
8835   std::size_t sz=std::distance(start,end);
8836   int *ret=(int *)malloc(sz*sizeof(int));
8837   int *work=new int[sz];
8838   std::copy(start,end,work);
8839   std::sort(work,work+sz);
8840   if(std::unique(work,work+sz)!=work+sz)
8841     {
8842       delete [] work;
8843       free(ret);
8844       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
8845     }
8846   std::map<int,int> m;
8847   for(int *workPt=work;workPt!=work+sz;workPt++)
8848     m[*workPt]=(int)std::distance(work,workPt);
8849   int *iter2=ret;
8850   for(const int *iter=start;iter!=end;iter++,iter2++)
8851     *iter2=m[*iter];
8852   delete [] work;
8853   return ret;
8854 }
8855
8856 /*!
8857  * Returns a new DataArrayInt containing an arithmetic progression
8858  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
8859  * function.
8860  *  \param [in] begin - the start value of the result sequence.
8861  *  \param [in] end - limiting value, so that every value of the result array is less than
8862  *              \a end.
8863  *  \param [in] step - specifies the increment or decrement.
8864  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8865  *          array using decrRef() as it is no more needed.
8866  *  \throw If \a step == 0.
8867  *  \throw If \a end < \a begin && \a step > 0.
8868  *  \throw If \a end > \a begin && \a step < 0.
8869  */
8870 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
8871 {
8872   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
8873   MCAuto<DataArrayInt> ret=DataArrayInt::New();
8874   ret->alloc(nbOfTuples,1);
8875   int *ptr=ret->getPointer();
8876   if(step>0)
8877     {
8878       for(int i=begin;i<end;i+=step,ptr++)
8879         *ptr=i;
8880     }
8881   else
8882     {
8883       for(int i=begin;i>end;i+=step,ptr++)
8884         *ptr=i;
8885     }
8886   return ret.retn();
8887 }
8888
8889 /*!
8890  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8891  * Server side.
8892  */
8893 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
8894 {
8895   tinyInfo.resize(2);
8896   if(isAllocated())
8897     {
8898       tinyInfo[0]=getNumberOfTuples();
8899       tinyInfo[1]=getNumberOfComponents();
8900     }
8901   else
8902     {
8903       tinyInfo[0]=-1;
8904       tinyInfo[1]=-1;
8905     }
8906 }
8907
8908 /*!
8909  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8910  * Server side.
8911  */
8912 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
8913 {
8914   if(isAllocated())
8915     {
8916       int nbOfCompo=getNumberOfComponents();
8917       tinyInfo.resize(nbOfCompo+1);
8918       tinyInfo[0]=getName();
8919       for(int i=0;i<nbOfCompo;i++)
8920         tinyInfo[i+1]=getInfoOnComponent(i);
8921     }
8922   else
8923     {
8924       tinyInfo.resize(1);
8925       tinyInfo[0]=getName();
8926     }
8927 }
8928
8929 /*!
8930  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8931  * This method returns if a feeding is needed.
8932  */
8933 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
8934 {
8935   int nbOfTuple=tinyInfoI[0];
8936   int nbOfComp=tinyInfoI[1];
8937   if(nbOfTuple!=-1 || nbOfComp!=-1)
8938     {
8939       alloc(nbOfTuple,nbOfComp);
8940       return true;
8941     }
8942   return false;
8943 }
8944
8945 /*!
8946  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8947  * This method returns if a feeding is needed.
8948  */
8949 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
8950 {
8951   setName(tinyInfoS[0]);
8952   if(isAllocated())
8953     {
8954       int nbOfCompo=tinyInfoI[1];
8955       for(int i=0;i<nbOfCompo;i++)
8956         setInfoOnComponent(i,tinyInfoS[i+1]);
8957     }
8958 }
8959
8960 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
8961 {
8962   if(_da)
8963     {
8964       _da->incrRef();
8965       if(_da->isAllocated())
8966         {
8967           _nb_comp=da->getNumberOfComponents();
8968           _nb_tuple=da->getNumberOfTuples();
8969           _pt=da->getPointer();
8970         }
8971     }
8972 }
8973
8974 DataArrayIntIterator::~DataArrayIntIterator()
8975 {
8976   if(_da)
8977     _da->decrRef();
8978 }
8979
8980 DataArrayIntTuple *DataArrayIntIterator::nextt()
8981 {
8982   if(_tuple_id<_nb_tuple)
8983     {
8984       _tuple_id++;
8985       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
8986       _pt+=_nb_comp;
8987       return ret;
8988     }
8989   else
8990     return 0;
8991 }
8992
8993 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
8994 {
8995 }
8996
8997 std::string DataArrayIntTuple::repr() const
8998 {
8999   std::ostringstream oss; oss << "(";
9000   for(int i=0;i<_nb_of_compo-1;i++)
9001     oss << _pt[i] << ", ";
9002   oss << _pt[_nb_of_compo-1] << ")";
9003   return oss.str();
9004 }
9005
9006 int DataArrayIntTuple::intValue() const
9007 {
9008   if(_nb_of_compo==1)
9009     return *_pt;
9010   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9011 }
9012
9013 /*!
9014  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9015  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9016  * 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
9017  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9018  */
9019 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9020 {
9021   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9022     {
9023       DataArrayInt *ret=DataArrayInt::New();
9024       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9025       return ret;
9026     }
9027   else
9028     {
9029       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9030       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9031       throw INTERP_KERNEL::Exception(oss.str().c_str());
9032     }
9033 }