Salome HOME
24142a4b285a0f35ef5055242e9b4dd5cfc83d9b
[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 (EDF R&D)
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 MEDCoupling::MemArray<int>;
40 template class MEDCoupling::MemArray<double>;
41 template class MEDCoupling::DataArrayTemplate<int>;
42 template class MEDCoupling::DataArrayTemplate<double>;
43 template class MEDCoupling::DataArrayTemplateClassic<int>;
44 template class MEDCoupling::DataArrayTemplateClassic<double>;
45 template class MEDCoupling::DataArrayTemplateFP<double>;
46 template class MEDCoupling::DataArrayIterator<double>;
47 template class MEDCoupling::DataArrayIterator<int>;
48 template class MEDCoupling::DataArrayDiscrete<Int32>;
49 template class MEDCoupling::DataArrayDiscreteSigned<Int32>;
50
51 template<int SPACEDIM>
52 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
53 {
54   const double *coordsPtr=getConstPointer();
55   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
56   std::vector<bool> isDone(nbNodes);
57   for(int i=0;i<nbNodes;i++)
58     {
59       if(!isDone[i])
60         {
61           std::vector<int> intersectingElems;
62           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
63           if(intersectingElems.size()>1)
64             {
65               std::vector<int> commonNodes;
66               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
67                 if(*it!=i)
68                   if(*it>=limitNodeId)
69                     {
70                       commonNodes.push_back(*it);
71                       isDone[*it]=true;
72                     }
73               if(!commonNodes.empty())
74                 {
75                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
76                   c->pushBackSilent(i);
77                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
78                 }
79             }
80         }
81     }
82 }
83
84 template<int SPACEDIM>
85 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
86                                                 DataArrayInt *c, DataArrayInt *cI)
87 {
88   for(int i=0;i<nbOfTuples;i++)
89     {
90       std::vector<int> intersectingElems;
91       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
92       std::vector<int> commonNodes;
93       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
94         commonNodes.push_back(*it);
95       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
96       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
97     }
98 }
99
100 template<int SPACEDIM>
101 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
102 {
103   double distOpt(dist);
104   const double *p(pos);
105   int *r(res);
106   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
107     {
108       while(true)
109         {
110           int elem=-1;
111           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
112           if(ret!=std::numeric_limits<double>::max())
113             {
114               distOpt=std::max(ret,1e-4);
115               *r=elem;
116               break;
117             }
118           else
119             { distOpt=2*distOpt; continue; }
120         }
121     }
122 }
123
124 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
125 {
126   if(nbOfTuples<=0)
127     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
128   if(nbOfShift>=0)
129     {
130       return nbOfShift%nbOfTuples;
131     }
132   else
133     {
134       int tmp(-nbOfShift);
135       tmp=tmp%nbOfTuples;
136       return nbOfTuples-tmp;
137     }
138 }
139
140 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
141 {
142   std::size_t sz1=_name.capacity();
143   std::size_t sz2=_info_on_compo.capacity();
144   std::size_t sz3=0;
145   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
146     sz3+=(*it).capacity();
147   return sz1+sz2+sz3;
148 }
149
150 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
151 {
152   return std::vector<const BigMemoryObject *>();
153 }
154
155 /*!
156  * Sets the attribute \a _name of \a this array.
157  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
158  *  \param [in] name - new array name
159  */
160 void DataArray::setName(const std::string& name)
161 {
162   _name=name;
163 }
164
165 /*!
166  * Copies textual data from an \a other DataArray. The copied data are
167  * - the name attribute,
168  * - the information of components.
169  *
170  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
171  *
172  *  \param [in] other - another instance of DataArray to copy the textual data from.
173  *  \throw If number of components of \a this array differs from that of the \a other.
174  */
175 void DataArray::copyStringInfoFrom(const DataArray& other)
176 {
177   if(_info_on_compo.size()!=other._info_on_compo.size())
178     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
179   _name=other._name;
180   _info_on_compo=other._info_on_compo;
181 }
182
183 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
184 {
185   int nbOfCompoOth=other.getNumberOfComponents();
186   std::size_t newNbOfCompo=compoIds.size();
187   for(std::size_t i=0;i<newNbOfCompo;i++)
188     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
189       {
190         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
191         throw INTERP_KERNEL::Exception(oss.str().c_str());
192       }
193   for(std::size_t i=0;i<newNbOfCompo;i++)
194     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
195 }
196
197 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
198 {
199   std::size_t nbOfCompo(getNumberOfComponents());
200   std::size_t partOfCompoToSet=compoIds.size();
201   if(partOfCompoToSet!=other.getNumberOfComponents())
202     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
203   for(std::size_t i=0;i<partOfCompoToSet;i++)
204     if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
205       {
206         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
207         throw INTERP_KERNEL::Exception(oss.str().c_str());
208       }
209   for(std::size_t i=0;i<partOfCompoToSet;i++)
210     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
211 }
212
213 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
214 {
215   std::ostringstream oss;
216   if(_name!=other._name)
217     {
218       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
219       reason=oss.str();
220       return false;
221     }
222   if(_info_on_compo!=other._info_on_compo)
223     {
224       oss << "Components DataArray mismatch : \nThis components=";
225       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
226         oss << "\"" << *it << "\",";
227       oss << "\nOther components=";
228       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
229         oss << "\"" << *it << "\",";
230       reason=oss.str();
231       return false;
232     }
233   return true;
234 }
235
236 /*!
237  * Compares textual information of \a this DataArray with that of an \a other one.
238  * The compared data are
239  * - the name attribute,
240  * - the information of components.
241  *
242  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
243  *  \param [in] other - another instance of DataArray to compare the textual data of.
244  *  \return bool - \a true if the textual information is same, \a false else.
245  */
246 bool DataArray::areInfoEquals(const DataArray& other) const
247 {
248   std::string tmp;
249   return areInfoEqualsIfNotWhy(other,tmp);
250 }
251
252 void DataArray::reprWithoutNameStream(std::ostream& stream) const
253 {
254   stream << "Number of components : "<< getNumberOfComponents() << "\n";
255   stream << "Info of these components : ";
256   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
257     stream << "\"" << *iter << "\"   ";
258   stream << "\n";
259 }
260
261 std::string DataArray::cppRepr(const std::string& varName) const
262 {
263   std::ostringstream ret;
264   reprCppStream(varName,ret);
265   return ret.str();
266 }
267
268 /*!
269  * Sets information on all components. To know more on format of this information
270  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
271  *  \param [in] info - a vector of strings.
272  *  \throw If size of \a info differs from the number of components of \a this.
273  */
274 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
275 {
276   if(getNumberOfComponents()!=info.size())
277     {
278       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
279       throw INTERP_KERNEL::Exception(oss.str().c_str());
280     }
281   _info_on_compo=info;
282 }
283
284 /*!
285  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
286  * type of \a this and \a aBase.
287  *
288  * \throw If \a aBase and \a this do not have the same type.
289  *
290  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
291  */
292 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
293 {
294   if(!aBase)
295     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
296   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
297   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
298   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
299   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
300   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
301   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
302   if(this1 && a1)
303     {
304       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
305       return ;
306     }
307   if(this2 && a2)
308     {
309       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
310       return ;
311     }
312   if(this3 && a3)
313     {
314       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
315       return ;
316     }
317   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
318 }
319
320 std::vector<std::string> DataArray::getVarsOnComponent() const
321 {
322   int nbOfCompo=(int)_info_on_compo.size();
323   std::vector<std::string> ret(nbOfCompo);
324   for(int i=0;i<nbOfCompo;i++)
325     ret[i]=getVarOnComponent(i);
326   return ret;
327 }
328
329 std::vector<std::string> DataArray::getUnitsOnComponent() const
330 {
331   int nbOfCompo=(int)_info_on_compo.size();
332   std::vector<std::string> ret(nbOfCompo);
333   for(int i=0;i<nbOfCompo;i++)
334     ret[i]=getUnitOnComponent(i);
335   return ret;
336 }
337
338 /*!
339  * Returns information on a component specified by an index.
340  * To know more on format of this information
341  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
342  *  \param [in] i - the index (zero based) of the component of interest.
343  *  \return std::string - a string containing the information on \a i-th component.
344  *  \throw If \a i is not a valid component index.
345  */
346 std::string DataArray::getInfoOnComponent(int i) const
347 {
348   if(i<(int)_info_on_compo.size() && i>=0)
349     return _info_on_compo[i];
350   else
351     {
352       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();
353       throw INTERP_KERNEL::Exception(oss.str().c_str());
354     }
355 }
356
357 /*!
358  * Returns the var 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 getVarOnComponent(0) returns "SIGXY".
361  * If a unit part of information is not detected by presence of
362  * two square brackets, then the full information 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 var information, or the full info.
367  *  \throw If \a i is not a valid component index.
368  */
369 std::string DataArray::getVarOnComponent(int i) const
370 {
371   if(i<(int)_info_on_compo.size() && i>=0)
372     {
373       return GetVarNameFromInfo(_info_on_compo[i]);
374     }
375   else
376     {
377       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();
378       throw INTERP_KERNEL::Exception(oss.str().c_str());
379     }
380 }
381
382 /*!
383  * Returns the unit part of the full information of the \a i-th component.
384  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
385  * \c getUnitOnComponent(0) returns " N/m^2".
386  * If a unit part of information is not detected by presence of
387  * two square brackets, then an empty string is returned.
388  * To read more about the component information format, see
389  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
390  *  \param [in] i - the index (zero based) of the component of interest.
391  *  \return std::string - a string containing the unit information, if any, or "".
392  *  \throw If \a i is not a valid component index.
393  */
394 std::string DataArray::getUnitOnComponent(int i) const
395 {
396   if(i<(int)_info_on_compo.size() && i>=0)
397     {
398       return GetUnitFromInfo(_info_on_compo[i]);
399     }
400   else
401     {
402       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();
403       throw INTERP_KERNEL::Exception(oss.str().c_str());
404     }
405 }
406
407 /*!
408  * Returns the var part of the full component information.
409  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
410  * If a unit part of information is not detected by presence of
411  * two square brackets, then the whole \a info is returned.
412  * To read more about the component information format, see
413  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
414  *  \param [in] info - the full component information.
415  *  \return std::string - a string containing only var information, or the \a info.
416  */
417 std::string DataArray::GetVarNameFromInfo(const std::string& info)
418 {
419   std::size_t p1=info.find_last_of('[');
420   std::size_t p2=info.find_last_of(']');
421   if(p1==std::string::npos || p2==std::string::npos)
422     return info;
423   if(p1>p2)
424     return info;
425   if(p1==0)
426     return std::string();
427   std::size_t p3=info.find_last_not_of(' ',p1-1);
428   return info.substr(0,p3+1);
429 }
430
431 /*!
432  * Returns the unit part of the full component information.
433  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
434  * If a unit part of information is not detected by presence of
435  * two square brackets, then an empty string is returned.
436  * To read more about the component information format, see
437  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
438  *  \param [in] info - the full component information.
439  *  \return std::string - a string containing only unit information, if any, or "".
440  */
441 std::string DataArray::GetUnitFromInfo(const std::string& info)
442 {
443   std::size_t p1=info.find_last_of('[');
444   std::size_t p2=info.find_last_of(']');
445   if(p1==std::string::npos || p2==std::string::npos)
446     return std::string();
447   if(p1>p2)
448     return std::string();
449   return info.substr(p1+1,p2-p1-1);
450 }
451
452 /*!
453  * This method put in info format the result of the merge of \a var and \a unit.
454  * The standard format for that is "var [unit]".
455  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
456  */
457 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
458 {
459   std::ostringstream oss;
460   oss << var << " [" << unit << "]";
461   return oss.str();
462 }
463
464 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
465 {
466   switch(at)
467     {
468     case AX_CART:
469       return std::string("AX_CART");
470     case AX_CYL:
471       return std::string("AX_CYL");
472     case AX_SPHER:
473       return std::string("AX_SPHER");
474     default:
475       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
476     }
477 }
478
479 /*!
480  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
481  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
482  * the number of component in the result array is same as that of each of given arrays.
483  * Info on components is copied from the first of the given arrays. Number of components
484  * in the given arrays must be  the same.
485  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
486  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
487  *          The caller is to delete this result array using decrRef() as it is no more
488  *          needed.
489  *  \throw If all arrays within \a arrs are NULL.
490  *  \throw If all not null arrays in \a arrs have not the same type.
491  *  \throw If getNumberOfComponents() of arrays within \a arrs.
492  */
493 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
494 {
495   std::vector<const DataArray *> arr2;
496   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
497     if(*it)
498       arr2.push_back(*it);
499   if(arr2.empty())
500     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
501   std::vector<const DataArrayDouble *> arrd;
502   std::vector<const DataArrayInt *> arri;
503   std::vector<const DataArrayChar *> arrc;
504   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
505     {
506       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
507       if(a)
508         { arrd.push_back(a); continue; }
509       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
510       if(b)
511         { arri.push_back(b); continue; }
512       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
513       if(c)
514         { arrc.push_back(c); continue; }
515       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
516     }
517   if(arr2.size()==arrd.size())
518     return DataArrayDouble::Aggregate(arrd);
519   if(arr2.size()==arri.size())
520     return DataArrayInt::Aggregate(arri);
521   if(arr2.size()==arrc.size())
522     return DataArrayChar::Aggregate(arrc);
523   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
524 }
525
526 /*!
527  * Sets information on a component specified by an index.
528  * To know more on format of this information
529  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
530  *  \warning Don't pass NULL as \a info!
531  *  \param [in] i - the index (zero based) of the component of interest.
532  *  \param [in] info - the string containing the information.
533  *  \throw If \a i is not a valid component index.
534  */
535 void DataArray::setInfoOnComponent(int i, const std::string& info)
536 {
537   if(i<(int)_info_on_compo.size() && i>=0)
538     _info_on_compo[i]=info;
539   else
540     {
541       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();
542       throw INTERP_KERNEL::Exception(oss.str().c_str());
543     }
544 }
545
546 /*!
547  * Sets information on all components. This method can change number of components
548  * at certain conditions; if the conditions are not respected, an exception is thrown.
549  * The number of components can be changed in \a this only if \a this is not allocated.
550  * The condition of number of components must not be changed.
551  *
552  * To know more on format of the component information see
553  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
554  *  \param [in] info - a vector of component infos.
555  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
556  */
557 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
558 {
559   if(getNumberOfComponents()!=info.size())
560     {
561       if(!isAllocated())
562         _info_on_compo=info;
563       else
564         {
565           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 !";
566           throw INTERP_KERNEL::Exception(oss.str().c_str());
567         }
568     }
569   else
570     _info_on_compo=info;
571 }
572
573 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
574 {
575   if(getNumberOfTuples()!=nbOfTuples)
576     {
577       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
578       throw INTERP_KERNEL::Exception(oss.str().c_str());
579     }
580 }
581
582 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
583 {
584   if((int)getNumberOfComponents()!=nbOfCompo)
585     {
586       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
587       throw INTERP_KERNEL::Exception(oss.str().c_str());
588     }
589 }
590
591 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
592 {
593   if(getNbOfElems()!=nbOfElems)
594     {
595       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
596       throw INTERP_KERNEL::Exception(oss.str().c_str());
597     }
598 }
599
600 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
601 {
602   if(getNumberOfTuples()!=other.getNumberOfTuples())
603     {
604       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
605       throw INTERP_KERNEL::Exception(oss.str().c_str());
606     }
607   if(getNumberOfComponents()!=other.getNumberOfComponents())
608     {
609       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
610       throw INTERP_KERNEL::Exception(oss.str().c_str());
611     }
612 }
613
614 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
615 {
616   checkNbOfTuples(nbOfTuples,msg);
617   checkNbOfComps(nbOfCompo,msg);
618 }
619
620 /*!
621  * Simply this method checks that \b value is in [0,\b ref).
622  */
623 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
624 {
625   if(value<0 || value>=ref)
626     {
627       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
628       throw INTERP_KERNEL::Exception(oss.str().c_str());
629     }
630 }
631
632 /*!
633  * This method checks that [\b start, \b end) is compliant with ref length \b value.
634  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
635  */
636 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
637 {
638   if(start<0 || start>=value)
639     {
640       if(value!=start || end!=start)
641         {
642           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
643           throw INTERP_KERNEL::Exception(oss.str().c_str());
644         }
645     }
646   if(end<0 || end>value)
647     {
648       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
649       throw INTERP_KERNEL::Exception(oss.str().c_str());
650     }
651 }
652
653 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
654 {
655   if(value<0 || value>ref)
656     {
657       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
658       throw INTERP_KERNEL::Exception(oss.str().c_str());
659     }
660 }
661
662 /*!
663  * 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, 
664  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
665  *
666  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
667  *
668  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
669  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
670  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
671  * \param [in] sliceId - the slice id considered
672  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
673  * \param [out] startSlice - the start of the slice considered
674  * \param [out] stopSlice - the stop of the slice consided
675  * 
676  * \throw If \a step == 0
677  * \throw If \a nbOfSlices not > 0
678  * \throw If \a sliceId not in [0,nbOfSlices)
679  */
680 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
681 {
682   if(nbOfSlices<=0)
683     {
684       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
685       throw INTERP_KERNEL::Exception(oss.str().c_str());
686     }
687   if(sliceId<0 || sliceId>=nbOfSlices)
688     {
689       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
690       throw INTERP_KERNEL::Exception(oss.str().c_str());
691     }
692   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
693   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
694   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
695   if(sliceId<nbOfSlices-1)
696     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
697   else
698     stopSlice=stop;
699 }
700
701 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
702 {
703   if(end<begin)
704     {
705       std::ostringstream oss; oss << msg << " : end before begin !";
706       throw INTERP_KERNEL::Exception(oss.str().c_str());
707     }
708   if(end==begin)
709     return 0;
710   if(step<=0)
711     {
712       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
713       throw INTERP_KERNEL::Exception(oss.str().c_str());
714     }
715   return (end-1-begin)/step+1;
716 }
717
718 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
719 {
720   if(step==0)
721     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
722   if(end<begin && step>0)
723     {
724       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
725       throw INTERP_KERNEL::Exception(oss.str().c_str());
726     }
727   if(begin<end && step<0)
728     {
729       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
730       throw INTERP_KERNEL::Exception(oss.str().c_str());
731     }
732   if(begin!=end)
733     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
734   else
735     return 0;
736 }
737
738 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
739 {
740   if(step!=0)
741     {
742       if(step>0)
743         {
744           if(begin<=value && value<end)
745             {
746               if((value-begin)%step==0)
747                 return (value-begin)/step;
748               else
749                 return -1;
750             }
751           else
752             return -1;
753         }
754       else
755         {
756           if(begin>=value && value>end)
757             {
758               if((begin-value)%(-step)==0)
759                 return (begin-value)/(-step);
760               else
761                 return -1;
762             }
763           else
764             return -1;
765         }
766     }
767   else
768     return -1;
769 }
770
771 /*!
772  * Returns a new instance of DataArrayDouble. The caller is to delete this array
773  * using decrRef() as it is no more needed. 
774  */
775 DataArrayDouble *DataArrayDouble::New()
776 {
777   return new DataArrayDouble;
778 }
779
780 /*!
781  * Returns the only one value in \a this, if and only if number of elements
782  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
783  *  \return double - the sole value stored in \a this array.
784  *  \throw If at least one of conditions stated above is not fulfilled.
785  */
786 double DataArrayDouble::doubleValue() const
787 {
788   if(isAllocated())
789     {
790       if(getNbOfElems()==1)
791         {
792           return *getConstPointer();
793         }
794       else
795         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
796     }
797   else
798     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
799 }
800
801 /*!
802  * Returns a full copy of \a this. For more info on copying data arrays see
803  * \ref MEDCouplingArrayBasicsCopyDeep.
804  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
805  *          delete this array using decrRef() as it is no more needed. 
806  */
807 DataArrayDouble *DataArrayDouble::deepCopy() const
808 {
809   return new DataArrayDouble(*this);
810 }
811
812 /*!
813  * Assign zero to all values in \a this array. To know more on filling arrays see
814  * \ref MEDCouplingArrayFill.
815  * \throw If \a this is not allocated.
816  */
817 void DataArrayDouble::fillWithZero()
818 {
819   fillWithValue(0.);
820 }
821
822 /*!
823  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
824  * with at least absolute difference value of |\a eps| at each step.
825  * If not an exception is thrown.
826  *  \param [in] increasing - if \a true, the array values should be increasing.
827  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
828  *                    the values are considered different.
829  *  \throw If sequence of values is not strictly monotonic in agreement with \a
830  *         increasing arg.
831  *  \throw If \a this->getNumberOfComponents() != 1.
832  *  \throw If \a this is not allocated.
833  */
834 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
835 {
836   if(!isMonotonic(increasing,eps))
837     {
838       if (increasing)
839         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
840       else
841         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
842     }
843 }
844
845 /*!
846  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
847  * with at least absolute difference value of |\a eps| at each step.
848  *  \param [in] increasing - if \a true, array values should be increasing.
849  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
850  *                    the values are considered different.
851  *  \return bool - \a true if values change in accordance with \a increasing arg.
852  *  \throw If \a this->getNumberOfComponents() != 1.
853  *  \throw If \a this is not allocated.
854  */
855 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
856 {
857   checkAllocated();
858   if(getNumberOfComponents()!=1)
859     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
860   int nbOfElements=getNumberOfTuples();
861   const double *ptr=getConstPointer();
862   if(nbOfElements==0)
863     return true;
864   double ref=ptr[0];
865   double absEps=fabs(eps);
866   if(increasing)
867     {
868       for(int i=1;i<nbOfElements;i++)
869         {
870           if(ptr[i]<(ref+absEps))
871             return false;
872           ref=ptr[i];
873         }
874       return true;
875     }
876   else
877     {
878       for(int i=1;i<nbOfElements;i++)
879         {
880           if(ptr[i]>(ref-absEps))
881             return false;
882           ref=ptr[i];
883         }
884       return true;
885     }
886 }
887
888 /*!
889  * Returns a textual and human readable representation of \a this instance of
890  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
891  * \return std::string - text describing \a this DataArrayDouble.
892  *
893  * \sa reprNotTooLong, reprZip
894  */
895 std::string DataArrayDouble::repr() const
896 {
897   std::ostringstream ret;
898   reprStream(ret);
899   return ret.str();
900 }
901
902 std::string DataArrayDouble::reprZip() const
903 {
904   std::ostringstream ret;
905   reprZipStream(ret);
906   return ret.str();
907 }
908
909 /*!
910  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
911  * printed out to avoid to consume too much space in interpretor.
912  * \sa repr
913  */
914 std::string DataArrayDouble::reprNotTooLong() const
915 {
916   std::ostringstream ret;
917   reprNotTooLongStream(ret);
918   return ret.str();
919 }
920
921 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
922 {
923   static const char SPACE[4]={' ',' ',' ',' '};
924   checkAllocated();
925   std::string idt(indent,' ');
926   ofs.precision(17);
927   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
928   //
929   bool areAllEmpty(true);
930   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
931     if(!(*it).empty())
932       areAllEmpty=false;
933   if(!areAllEmpty)
934     for(std::size_t i=0;i<_info_on_compo.size();i++)
935       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
936   //
937   if(byteArr)
938     {
939       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
940       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
941       float *pt(tmp);
942       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
943       for(const double *src=begin();src!=end();src++,pt++)
944         *pt=float(*src);
945       const char *data(reinterpret_cast<const char *>((float *)tmp));
946       std::size_t sz(getNbOfElems()*sizeof(float));
947       byteArr->insertAtTheEnd(data,data+sz);
948       byteArr->insertAtTheEnd(SPACE,SPACE+4);
949     }
950   else
951     {
952       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
953       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
954     }
955   ofs << std::endl << idt << "</DataArray>\n";
956 }
957
958 void DataArrayDouble::reprStream(std::ostream& stream) const
959 {
960   stream << "Name of double array : \"" << _name << "\"\n";
961   reprWithoutNameStream(stream);
962 }
963
964 void DataArrayDouble::reprZipStream(std::ostream& stream) const
965 {
966   stream << "Name of double array : \"" << _name << "\"\n";
967   reprZipWithoutNameStream(stream);
968 }
969
970 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
971 {
972   stream << "Name of double array : \"" << _name << "\"\n";
973   reprNotTooLongWithoutNameStream(stream);
974 }
975
976 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
977 {
978   DataArray::reprWithoutNameStream(stream);
979   stream.precision(17);
980   _mem.repr(getNumberOfComponents(),stream);
981 }
982
983 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
984 {
985   DataArray::reprWithoutNameStream(stream);
986   stream.precision(17);
987   _mem.reprZip(getNumberOfComponents(),stream);
988 }
989
990 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
991 {
992   DataArray::reprWithoutNameStream(stream);
993   stream.precision(17);
994   _mem.reprNotTooLong(getNumberOfComponents(),stream);
995 }
996
997 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
998 {
999   int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
1000   const double *data(getConstPointer());
1001   stream.precision(17);
1002   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1003   if(nbTuples*nbComp>=1)
1004     {
1005       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1006       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1007       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1008       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1009     }
1010   else
1011     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1012   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1013 }
1014
1015 /*!
1016  * Method that gives a quick overvien of \a this for python.
1017  */
1018 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1019 {
1020   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1021   stream << "DataArrayDouble C++ instance at " << this << ". ";
1022   if(isAllocated())
1023     {
1024       int nbOfCompo=(int)_info_on_compo.size();
1025       if(nbOfCompo>=1)
1026         {
1027           int nbOfTuples=getNumberOfTuples();
1028           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1029           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1030         }
1031       else
1032         stream << "Number of components : 0.";
1033     }
1034   else
1035     stream << "*** No data allocated ****";
1036 }
1037
1038 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1039 {
1040   const double *data=begin();
1041   int nbOfTuples=getNumberOfTuples();
1042   int nbOfCompo=(int)_info_on_compo.size();
1043   std::ostringstream oss2; oss2 << "[";
1044   oss2.precision(17);
1045   std::string oss2Str(oss2.str());
1046   bool isFinished=true;
1047   for(int i=0;i<nbOfTuples && isFinished;i++)
1048     {
1049       if(nbOfCompo>1)
1050         {
1051           oss2 << "(";
1052           for(int j=0;j<nbOfCompo;j++,data++)
1053             {
1054               oss2 << *data;
1055               if(j!=nbOfCompo-1) oss2 << ", ";
1056             }
1057           oss2 << ")";
1058         }
1059       else
1060         oss2 << *data++;
1061       if(i!=nbOfTuples-1) oss2 << ", ";
1062       std::string oss3Str(oss2.str());
1063       if(oss3Str.length()<maxNbOfByteInRepr)
1064         oss2Str=oss3Str;
1065       else
1066         isFinished=false;
1067     }
1068   stream << oss2Str;
1069   if(!isFinished)
1070     stream << "... ";
1071   stream << "]";
1072 }
1073
1074 /*!
1075  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1076  * mismatch is given.
1077  * 
1078  * \param [in] other the instance to be compared with \a this
1079  * \param [in] prec the precision to compare numeric data of the arrays.
1080  * \param [out] reason In case of inequality returns the reason.
1081  * \sa DataArrayDouble::isEqual
1082  */
1083 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1084 {
1085   if(!areInfoEqualsIfNotWhy(other,reason))
1086     return false;
1087   return _mem.isEqual(other._mem,prec,reason);
1088 }
1089
1090 /*!
1091  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1092  * \ref MEDCouplingArrayBasicsCompare.
1093  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1094  *  \param [in] prec - precision value to compare numeric data of the arrays.
1095  *  \return bool - \a true if the two arrays are equal, \a false else.
1096  */
1097 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1098 {
1099   std::string tmp;
1100   return isEqualIfNotWhy(other,prec,tmp);
1101 }
1102
1103 /*!
1104  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1105  * \ref MEDCouplingArrayBasicsCompare.
1106  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1107  *  \param [in] prec - precision value to compare numeric data of the arrays.
1108  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1109  */
1110 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1111 {
1112   std::string tmp;
1113   return _mem.isEqual(other._mem,prec,tmp);
1114 }
1115
1116 /*!
1117  * This method checks that all tuples in \a other are in \a this.
1118  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1119  * 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.
1120  *
1121  * \param [in] other - the array having the same number of components than \a this.
1122  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1123  * \sa DataArrayDouble::findCommonTuples
1124  */
1125 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1126 {
1127   if(!other)
1128     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1129   checkAllocated(); other->checkAllocated();
1130   if(getNumberOfComponents()!=other->getNumberOfComponents())
1131     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1132   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1133   DataArrayInt *c=0,*ci=0;
1134   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1135   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1136   int newNbOfTuples=-1;
1137   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1138   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1139   tupleIds=ret1.retn();
1140   return newNbOfTuples==getNumberOfTuples();
1141 }
1142
1143 /*!
1144  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1145  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1146  * distance separating two points is computed with the infinite norm.
1147  *
1148  * Indices of coincident tuples are stored in output arrays.
1149  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1150  *
1151  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1152  * MEDCouplingUMesh::mergeNodes().
1153  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1154  *              considered not coincident.
1155  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1156  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1157  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1158  *               \a comm->getNumberOfComponents() == 1. 
1159  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1160  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1161  *               groups of (indices of) coincident tuples. Its every value is a tuple
1162  *               index where a next group of tuples begins. For example the second
1163  *               group of tuples in \a comm is described by following range of indices:
1164  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1165  *               gives the number of groups of coincident tuples.
1166  *  \throw If \a this is not allocated.
1167  *  \throw If the number of components is not in [1,2,3,4].
1168  *
1169  *  \if ENABLE_EXAMPLES
1170  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1171  *
1172  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1173  *  \endif
1174  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1175  */
1176 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1177 {
1178   checkAllocated();
1179   int nbOfCompo=getNumberOfComponents();
1180   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1181     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1182
1183   int nbOfTuples=getNumberOfTuples();
1184   //
1185   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1186   switch(nbOfCompo)
1187   {
1188     case 4:
1189       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1190       break;
1191     case 3:
1192       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1193       break;
1194     case 2:
1195       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1196       break;
1197     case 1:
1198       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1199       break;
1200     default:
1201       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1202   }
1203   comm=c.retn();
1204   commIndex=cI.retn();
1205 }
1206
1207 /*!
1208  * This methods returns the minimal distance between the two set of points \a this and \a other.
1209  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1210  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1211  *
1212  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1213  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1214  * \return the minimal distance between the two set of points \a this and \a other.
1215  * \sa DataArrayDouble::findClosestTupleId
1216  */
1217 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1218 {
1219   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1220   int nbOfCompo(getNumberOfComponents());
1221   int otherNbTuples(other->getNumberOfTuples());
1222   const double *thisPt(begin()),*otherPt(other->begin());
1223   const int *part1Pt(part1->begin());
1224   double ret=std::numeric_limits<double>::max();
1225   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1226     {
1227       double tmp(0.);
1228       for(int j=0;j<nbOfCompo;j++)
1229         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1230       if(tmp<ret)
1231         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1232     }
1233   return sqrt(ret);
1234 }
1235
1236 /*!
1237  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1238  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1239  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1240  *
1241  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1242  * \sa DataArrayDouble::minimalDistanceTo
1243  */
1244 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1245 {
1246   if(!other)
1247     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1248   checkAllocated(); other->checkAllocated();
1249   std::size_t nbOfCompo(getNumberOfComponents());
1250   if(nbOfCompo!=other->getNumberOfComponents())
1251     {
1252       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1253       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1254       throw INTERP_KERNEL::Exception(oss.str().c_str());
1255     }
1256   int nbOfTuples=other->getNumberOfTuples();
1257   int thisNbOfTuples=getNumberOfTuples();
1258   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1259   double bounds[6];
1260   getMinMaxPerComponent(bounds);
1261   switch(nbOfCompo)
1262   {
1263     case 3:
1264       {
1265         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1266         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1267         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1268         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1269         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1270         break;
1271       }
1272     case 2:
1273       {
1274         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1275         double delta=std::max(xDelta,yDelta);
1276         double characSize=sqrt(delta/(double)thisNbOfTuples);
1277         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1278         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1279         break;
1280       }
1281     case 1:
1282       {
1283         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1284         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1285         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1286         break;
1287       }
1288     default:
1289       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1290   }
1291   return ret.retn();
1292 }
1293
1294 /*!
1295  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1296  * 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
1297  * how many bounding boxes in \a otherBBoxFrmt.
1298  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1299  *
1300  * \param [in] otherBBoxFrmt - It is an array .
1301  * \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.
1302  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1303  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1304  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1305  */
1306 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1307 {
1308   if(!otherBBoxFrmt)
1309     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1310   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1311     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1312   std::size_t nbOfComp(getNumberOfComponents());
1313   int nbOfTuples(getNumberOfTuples());
1314   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1315     {
1316       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1317       throw INTERP_KERNEL::Exception(oss.str().c_str());
1318     }
1319   if(nbOfComp%2!=0)
1320     {
1321       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1322       throw INTERP_KERNEL::Exception(oss.str().c_str());
1323     }
1324   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1325   const double *thisBBPtr(begin());
1326   int *retPtr(ret->getPointer());
1327   switch(nbOfComp/2)
1328   {
1329     case 3:
1330       {
1331         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1332         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1333           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1334         break;
1335       }
1336     case 2:
1337       {
1338         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1339         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1340           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1341         break;
1342       }
1343     case 1:
1344       {
1345         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1346         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1347           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1348         break;
1349       }
1350     default:
1351       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1352   }
1353
1354   return ret.retn();
1355 }
1356
1357 /*!
1358  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1359  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1360  * space. The distance between tuples is computed using norm2. If several tuples are
1361  * not far each from other than \a prec, only one of them remains in the result
1362  * array. The order of tuples in the result array is same as in \a this one except
1363  * that coincident tuples are excluded.
1364  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1365  *              considered not coincident.
1366  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1367  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1368  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1369  *          is to delete using decrRef() as it is no more needed.
1370  *  \throw If \a this is not allocated.
1371  *  \throw If the number of components is not in [1,2,3,4].
1372  *
1373  *  \if ENABLE_EXAMPLES
1374  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1375  *  \endif
1376  */
1377 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1378 {
1379   checkAllocated();
1380   DataArrayInt *c0=0,*cI0=0;
1381   findCommonTuples(prec,limitTupleId,c0,cI0);
1382   MCAuto<DataArrayInt> c(c0),cI(cI0);
1383   int newNbOfTuples=-1;
1384   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1385   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1386 }
1387
1388 /*!
1389  * Copy all components in a specified order from another DataArrayDouble.
1390  * Both numerical and textual data is copied. The number of tuples in \a this and
1391  * the other array can be different.
1392  *  \param [in] a - the array to copy data from.
1393  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1394  *              to be copied.
1395  *  \throw If \a a is NULL.
1396  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1397  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1398  *
1399  *  \if ENABLE_EXAMPLES
1400  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1401  *  \endif
1402  */
1403 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1404 {
1405   if(!a)
1406     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1407   checkAllocated();
1408   copyPartOfStringInfoFrom2(compoIds,*a);
1409   std::size_t partOfCompoSz=compoIds.size();
1410   int nbOfCompo=getNumberOfComponents();
1411   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1412   const double *ac=a->getConstPointer();
1413   double *nc=getPointer();
1414   for(int i=0;i<nbOfTuples;i++)
1415     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1416       nc[nbOfCompo*i+compoIds[j]]=*ac;
1417 }
1418
1419 /*!
1420  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1421  * is thrown.
1422  * \throw If zero is found in \a this array.
1423  */
1424 void DataArrayDouble::checkNoNullValues() const
1425 {
1426   const double *tmp=getConstPointer();
1427   std::size_t nbOfElems=getNbOfElems();
1428   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1429   if(where!=tmp+nbOfElems)
1430     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1431 }
1432
1433 /*!
1434  * Computes minimal and maximal value in each component. An output array is filled
1435  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1436  * enough memory before calling this method.
1437  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1438  *               It is filled as follows:<br>
1439  *               \a bounds[0] = \c min_of_component_0 <br>
1440  *               \a bounds[1] = \c max_of_component_0 <br>
1441  *               \a bounds[2] = \c min_of_component_1 <br>
1442  *               \a bounds[3] = \c max_of_component_1 <br>
1443  *               ...
1444  */
1445 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1446 {
1447   checkAllocated();
1448   int dim=getNumberOfComponents();
1449   for (int idim=0; idim<dim; idim++)
1450     {
1451       bounds[idim*2]=std::numeric_limits<double>::max();
1452       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1453     } 
1454   const double *ptr=getConstPointer();
1455   int nbOfTuples=getNumberOfTuples();
1456   for(int i=0;i<nbOfTuples;i++)
1457     {
1458       for(int idim=0;idim<dim;idim++)
1459         {
1460           if(bounds[idim*2]>ptr[i*dim+idim])
1461             {
1462               bounds[idim*2]=ptr[i*dim+idim];
1463             }
1464           if(bounds[idim*2+1]<ptr[i*dim+idim])
1465             {
1466               bounds[idim*2+1]=ptr[i*dim+idim];
1467             }
1468         }
1469     }
1470 }
1471
1472 /*!
1473  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1474  * to store both the min and max per component of each tuples. 
1475  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1476  *
1477  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1478  *
1479  * \throw If \a this is not allocated yet.
1480  */
1481 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1482 {
1483   checkAllocated();
1484   const double *dataPtr=getConstPointer();
1485   int nbOfCompo=getNumberOfComponents();
1486   int nbTuples=getNumberOfTuples();
1487   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1488   bbox->alloc(nbTuples,2*nbOfCompo);
1489   double *bboxPtr=bbox->getPointer();
1490   for(int i=0;i<nbTuples;i++)
1491     {
1492       for(int j=0;j<nbOfCompo;j++)
1493         {
1494           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1495           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1496         }
1497     }
1498   return bbox.retn();
1499 }
1500
1501 /*!
1502  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1503  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1504  * 
1505  * \param [in] other a DataArrayDouble having same number of components than \a this.
1506  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1507  * \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.
1508  *             \a cI allows to extract information in \a c.
1509  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1510  *
1511  * \throw In case of:
1512  *  - \a this is not allocated
1513  *  - \a other is not allocated or null
1514  *  - \a this and \a other do not have the same number of components
1515  *  - if number of components of \a this is not in [1,2,3]
1516  *
1517  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1518  */
1519 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1520 {
1521   if(!other)
1522     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1523   checkAllocated();
1524   other->checkAllocated();
1525   int nbOfCompo=getNumberOfComponents();
1526   int otherNbOfCompo=other->getNumberOfComponents();
1527   if(nbOfCompo!=otherNbOfCompo)
1528     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1529   int nbOfTuplesOther=other->getNumberOfTuples();
1530   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1531   switch(nbOfCompo)
1532   {
1533     case 3:
1534       {
1535         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1536         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1537         break;
1538       }
1539     case 2:
1540       {
1541         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1542         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1543         break;
1544       }
1545     case 1:
1546       {
1547         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1548         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1549         break;
1550       }
1551     default:
1552       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1553   }
1554   c=cArr.retn(); cI=cIArr.retn();
1555 }
1556
1557 /*!
1558  * 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
1559  * around origin of 'radius' 1.
1560  * 
1561  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1562  */
1563 void DataArrayDouble::recenterForMaxPrecision(double eps)
1564 {
1565   checkAllocated();
1566   int dim=getNumberOfComponents();
1567   std::vector<double> bounds(2*dim);
1568   getMinMaxPerComponent(&bounds[0]);
1569   for(int i=0;i<dim;i++)
1570     {
1571       double delta=bounds[2*i+1]-bounds[2*i];
1572       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1573       if(delta>eps)
1574         applyLin(1./delta,-offset/delta,i);
1575       else
1576         applyLin(1.,-offset,i);
1577     }
1578 }
1579
1580 /*!
1581  * Returns the maximal value and all its locations within \a this one-dimensional array.
1582  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1583  *               tuples holding the maximal value. The caller is to delete it using
1584  *               decrRef() as it is no more needed.
1585  *  \return double - the maximal value among all values of \a this array.
1586  *  \throw If \a this->getNumberOfComponents() != 1
1587  *  \throw If \a this->getNumberOfTuples() < 1
1588  */
1589 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1590 {
1591   int tmp;
1592   tupleIds=0;
1593   double ret=getMaxValue(tmp);
1594   tupleIds=findIdsInRange(ret,ret);
1595   return ret;
1596 }
1597
1598 /*!
1599  * Returns the minimal value and all its locations within \a this one-dimensional array.
1600  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1601  *               tuples holding the minimal value. The caller is to delete it using
1602  *               decrRef() as it is no more needed.
1603  *  \return double - the minimal value among all values of \a this array.
1604  *  \throw If \a this->getNumberOfComponents() != 1
1605  *  \throw If \a this->getNumberOfTuples() < 1
1606  */
1607 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1608 {
1609   int tmp;
1610   tupleIds=0;
1611   double ret=getMinValue(tmp);
1612   tupleIds=findIdsInRange(ret,ret);
1613   return ret;
1614 }
1615
1616 /*!
1617  * 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.
1618  * This method only works for single component array.
1619  *
1620  * \return a value in [ 0, \c this->getNumberOfTuples() )
1621  *
1622  * \throw If \a this is not allocated
1623  *
1624  */
1625 int DataArrayDouble::count(double value, double eps) const
1626 {
1627   int ret=0;
1628   checkAllocated();
1629   if(getNumberOfComponents()!=1)
1630     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1631   const double *vals=begin();
1632   int nbOfTuples=getNumberOfTuples();
1633   for(int i=0;i<nbOfTuples;i++,vals++)
1634     if(fabs(*vals-value)<=eps)
1635       ret++;
1636   return ret;
1637 }
1638
1639 /*!
1640  * Returns the average value of \a this one-dimensional array.
1641  *  \return double - the average value over all values of \a this array.
1642  *  \throw If \a this->getNumberOfComponents() != 1
1643  *  \throw If \a this->getNumberOfTuples() < 1
1644  */
1645 double DataArrayDouble::getAverageValue() const
1646 {
1647   if(getNumberOfComponents()!=1)
1648     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1649   int nbOfTuples=getNumberOfTuples();
1650   if(nbOfTuples<=0)
1651     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1652   const double *vals=getConstPointer();
1653   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1654   return ret/nbOfTuples;
1655 }
1656
1657 /*!
1658  * Returns the Euclidean norm of the vector defined by \a this array.
1659  *  \return double - the value of the Euclidean norm, i.e.
1660  *          the square root of the inner product of vector.
1661  *  \throw If \a this is not allocated.
1662  */
1663 double DataArrayDouble::norm2() const
1664 {
1665   checkAllocated();
1666   double ret=0.;
1667   std::size_t nbOfElems=getNbOfElems();
1668   const double *pt=getConstPointer();
1669   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1670     ret+=(*pt)*(*pt);
1671   return sqrt(ret);
1672 }
1673
1674 /*!
1675  * Returns the maximum norm of the vector defined by \a this array.
1676  * This method works even if the number of components is diferent from one.
1677  * If the number of elements in \a this is 0, -1. is returned.
1678  *  \return double - the value of the maximum norm, i.e.
1679  *          the maximal absolute value among values of \a this array (whatever its number of components).
1680  *  \throw If \a this is not allocated.
1681  */
1682 double DataArrayDouble::normMax() const
1683 {
1684   checkAllocated();
1685   double ret(-1.);
1686   std::size_t nbOfElems(getNbOfElems());
1687   const double *pt(getConstPointer());
1688   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1689     {
1690       double val(std::abs(*pt));
1691       if(val>ret)
1692         ret=val;
1693     }
1694   return ret;
1695 }
1696
1697 /*!
1698  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1699  * This method works even if the number of components is diferent from one.
1700  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1701  *  \return double - the value of the minimum norm, i.e.
1702  *          the minimal absolute value among values of \a this array (whatever its number of components).
1703  *  \throw If \a this is not allocated.
1704  */
1705 double DataArrayDouble::normMin() const
1706 {
1707   checkAllocated();
1708   double ret(std::numeric_limits<double>::max());
1709   std::size_t nbOfElems(getNbOfElems());
1710   const double *pt(getConstPointer());
1711   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1712     {
1713       double val(std::abs(*pt));
1714       if(val<ret)
1715         ret=val;
1716     }
1717   return ret;
1718 }
1719
1720 /*!
1721  * Accumulates values of each component of \a this array.
1722  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1723  *         by the caller, that is filled by this method with sum value for each
1724  *         component.
1725  *  \throw If \a this is not allocated.
1726  */
1727 void DataArrayDouble::accumulate(double *res) const
1728 {
1729   checkAllocated();
1730   const double *ptr=getConstPointer();
1731   int nbTuple=getNumberOfTuples();
1732   int nbComps=getNumberOfComponents();
1733   std::fill(res,res+nbComps,0.);
1734   for(int i=0;i<nbTuple;i++)
1735     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1736 }
1737
1738 /*!
1739  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1740  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1741  *
1742  *
1743  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1744  * \a tupleEnd. If not an exception will be thrown.
1745  *
1746  * \param [in] tupleBg start pointer (included) of input external tuple
1747  * \param [in] tupleEnd end pointer (not included) of input external tuple
1748  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1749  * \return the min distance.
1750  * \sa MEDCouplingUMesh::distanceToPoint
1751  */
1752 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1753 {
1754   checkAllocated();
1755   int nbTuple=getNumberOfTuples();
1756   int nbComps=getNumberOfComponents();
1757   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1758     { 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()); }
1759   if(nbTuple==0)
1760     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1761   double ret0=std::numeric_limits<double>::max();
1762   tupleId=-1;
1763   const double *work=getConstPointer();
1764   for(int i=0;i<nbTuple;i++)
1765     {
1766       double val=0.;
1767       for(int j=0;j<nbComps;j++,work++) 
1768         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1769       if(val>=ret0)
1770         continue;
1771       else
1772         { ret0=val; tupleId=i; }
1773     }
1774   return sqrt(ret0);
1775 }
1776
1777 /*!
1778  * Accumulate values of the given component of \a this array.
1779  *  \param [in] compId - the index of the component of interest.
1780  *  \return double - a sum value of \a compId-th component.
1781  *  \throw If \a this is not allocated.
1782  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1783  *         not respected.
1784  */
1785 double DataArrayDouble::accumulate(int compId) const
1786 {
1787   checkAllocated();
1788   const double *ptr=getConstPointer();
1789   int nbTuple=getNumberOfTuples();
1790   int nbComps=getNumberOfComponents();
1791   if(compId<0 || compId>=nbComps)
1792     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1793   double ret=0.;
1794   for(int i=0;i<nbTuple;i++)
1795     ret+=ptr[i*nbComps+compId];
1796   return ret;
1797 }
1798
1799 /*!
1800  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1801  * The returned array will have same number of components than \a this and number of tuples equal to
1802  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1803  *
1804  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1805  * 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.
1806  *
1807  * \param [in] bgOfIndex - begin (included) of the input index array.
1808  * \param [in] endOfIndex - end (excluded) of the input index array.
1809  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1810  * 
1811  * \throw If bgOfIndex or end is NULL.
1812  * \throw If input index array is not ascendingly sorted.
1813  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1814  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1815  */
1816 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1817 {
1818   if(!bgOfIndex || !endOfIndex)
1819     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1820   checkAllocated();
1821   int nbCompo=getNumberOfComponents();
1822   int nbOfTuples=getNumberOfTuples();
1823   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1824   if(sz<1)
1825     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1826   sz--;
1827   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1828   const int *w=bgOfIndex;
1829   if(*w<0 || *w>=nbOfTuples)
1830     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1831   const double *srcPt=begin()+(*w)*nbCompo;
1832   double *tmp=ret->getPointer();
1833   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1834     {
1835       std::fill(tmp,tmp+nbCompo,0.);
1836       if(w[1]>=w[0])
1837         {
1838           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1839             {
1840               if(j>=0 && j<nbOfTuples)
1841                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1842               else
1843                 {
1844                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1845                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1846                 }
1847             }
1848         }
1849       else
1850         {
1851           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1852           throw INTERP_KERNEL::Exception(oss.str().c_str());
1853         }
1854     }
1855   ret->copyStringInfoFrom(*this);
1856   return ret.retn();
1857 }
1858
1859 /*!
1860  * This method is close to numpy cumSum except that number of element is equal to \a this->getNumberOfTuples()+1. First element of DataArray returned is equal to 0.
1861  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1862  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1863  *
1864  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1865  */
1866 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1867 {
1868   checkAllocated();
1869   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1870   int nbOfTuple(getNumberOfTuples());
1871   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1872   double *ptr(ret->getPointer());
1873   ptr[0]=0.;
1874   const double *thisPtr(begin());
1875   for(int i=0;i<nbOfTuple;i++)
1876     ptr[i+1]=ptr[i]+thisPtr[i];
1877   return ret;
1878 }
1879
1880 /*!
1881  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1882  * Cartesian coordinate system. The two components of the tuple of \a this array are 
1883  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1884  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1885  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
1886  *          is to delete this array using decrRef() as it is no more needed. The array
1887  *          does not contain any textual info on components.
1888  *  \throw If \a this->getNumberOfComponents() != 2.
1889  * \sa fromCartToPolar
1890  */
1891 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1892 {
1893   checkAllocated();
1894   int nbOfComp(getNumberOfComponents());
1895   if(nbOfComp!=2)
1896     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1897   int nbOfTuple(getNumberOfTuples());
1898   DataArrayDouble *ret(DataArrayDouble::New());
1899   ret->alloc(nbOfTuple,2);
1900   double *w(ret->getPointer());
1901   const double *wIn(getConstPointer());
1902   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1903     {
1904       w[0]=wIn[0]*cos(wIn[1]);
1905       w[1]=wIn[0]*sin(wIn[1]);
1906     }
1907   return ret;
1908 }
1909
1910 /*!
1911  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1912  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1913  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1914  * the Cylindrical CS.
1915  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1916  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1917  *          on the third component is copied from \a this array. The caller
1918  *          is to delete this array using decrRef() as it is no more needed. 
1919  *  \throw If \a this->getNumberOfComponents() != 3.
1920  * \sa fromCartToCyl
1921  */
1922 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1923 {
1924   checkAllocated();
1925   int nbOfComp(getNumberOfComponents());
1926   if(nbOfComp!=3)
1927     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1928   int nbOfTuple(getNumberOfTuples());
1929   DataArrayDouble *ret(DataArrayDouble::New());
1930   ret->alloc(getNumberOfTuples(),3);
1931   double *w(ret->getPointer());
1932   const double *wIn(getConstPointer());
1933   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1934     {
1935       w[0]=wIn[0]*cos(wIn[1]);
1936       w[1]=wIn[0]*sin(wIn[1]);
1937       w[2]=wIn[2];
1938     }
1939   ret->setInfoOnComponent(2,getInfoOnComponent(2));
1940   return ret;
1941 }
1942
1943 /*!
1944  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1945  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1946  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1947  * point in the Cylindrical CS.
1948  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1949  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1950  *          on the third component is copied from \a this array. The caller
1951  *          is to delete this array using decrRef() as it is no more needed.
1952  *  \throw If \a this->getNumberOfComponents() != 3.
1953  * \sa fromCartToSpher
1954  */
1955 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1956 {
1957   checkAllocated();
1958   int nbOfComp(getNumberOfComponents());
1959   if(nbOfComp!=3)
1960     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1961   int nbOfTuple(getNumberOfTuples());
1962   DataArrayDouble *ret(DataArrayDouble::New());
1963   ret->alloc(getNumberOfTuples(),3);
1964   double *w(ret->getPointer());
1965   const double *wIn(getConstPointer());
1966   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1967     {
1968       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1969       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1970       w[2]=wIn[0]*cos(wIn[1]);
1971     }
1972   return ret;
1973 }
1974
1975 /*!
1976  * 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.
1977  * 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.
1978  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1979  *
1980  * \param [in] atOfThis - The axis type of \a this.
1981  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1982  */
1983 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1984 {
1985   checkAllocated();
1986   int nbOfComp(getNumberOfComponents());
1987   MCAuto<DataArrayDouble> ret;
1988   switch(atOfThis)
1989     {
1990     case AX_CART:
1991       ret=deepCopy();
1992     case AX_CYL:
1993       if(nbOfComp==3)
1994         {
1995           ret=fromCylToCart();
1996           break;
1997         }
1998       if(nbOfComp==2)
1999         {
2000           ret=fromPolarToCart();
2001           break;
2002         }
2003       else
2004         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2005     case AX_SPHER:
2006       if(nbOfComp==3)
2007         {
2008           ret=fromSpherToCart();
2009           break;
2010         }
2011       if(nbOfComp==2)
2012         {
2013           ret=fromPolarToCart();
2014           break;
2015         }
2016       else
2017         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2018     default:
2019       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2020     }
2021   ret->copyStringInfoFrom(*this);
2022   return ret.retn();
2023 }
2024
2025 /*!
2026  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2027  * This method expects that \a this has exactly 2 components.
2028  * \sa fromPolarToCart
2029  */
2030 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2031 {
2032   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2033   checkAllocated();
2034   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2035   if(nbOfComp!=2)
2036     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2037   ret->alloc(nbTuples,2);
2038   double *retPtr(ret->getPointer());
2039   const double *ptr(begin());
2040   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2041     {
2042       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2043       retPtr[1]=atan2(ptr[1],ptr[0]);
2044     }
2045   return ret.retn();
2046 }
2047
2048 /*!
2049  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2050  * This method expects that \a this has exactly 3 components.
2051  * \sa fromCylToCart
2052  */
2053 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2054 {
2055   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2056   checkAllocated();
2057   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2058   if(nbOfComp!=3)
2059     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2060   ret->alloc(nbTuples,3);
2061   double *retPtr(ret->getPointer());
2062   const double *ptr(begin());
2063   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2064     {
2065       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2066       retPtr[1]=atan2(ptr[1],ptr[0]);
2067       retPtr[2]=ptr[2];
2068     }
2069   return ret.retn();
2070 }
2071
2072 /*!
2073  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2074  * \sa fromSpherToCart
2075  */
2076 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2077 {
2078   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2079   checkAllocated();
2080   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2081   if(nbOfComp!=3)
2082     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2083   ret->alloc(nbTuples,3);
2084   double *retPtr(ret->getPointer());
2085   const double *ptr(begin());
2086   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2087     {
2088       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2089       retPtr[1]=acos(ptr[2]/retPtr[0]);
2090       retPtr[2]=atan2(ptr[1],ptr[0]);
2091     }
2092   return ret.retn();
2093 }
2094
2095 /*!
2096  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical relative to the given \a center and a \a vector.
2097  * This method expects that \a this has exactly 3 components.
2098  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2099  */
2100 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2101 {
2102   if(!coords)
2103     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2104   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2105   checkAllocated(); coords->checkAllocated();
2106   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2107   if(nbOfComp!=3)
2108     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2109   if(coords->getNumberOfComponents()!=3)
2110     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2111   if(coords->getNumberOfTuples()!=nbTuples)
2112     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2113   ret->alloc(nbTuples,nbOfComp);
2114   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2115   if(magOfVect<1e-12)
2116     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2117   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2118   const double *coo(coords->begin()),*vectField(begin());
2119   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2120   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2121     {
2122       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2123       Uteta[0]=Uz[1]*Ur[2]-Uz[2]*Ur[1]; Uteta[1]=Uz[2]*Ur[0]-Uz[0]*Ur[2]; Uteta[2]=Uz[0]*Ur[1]-Uz[1]*Ur[0];
2124       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2125       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2126       Ur[0]=Uteta[1]*Uz[2]-Uteta[2]*Uz[1]; Ur[1]=Uteta[2]*Uz[0]-Uteta[0]*Uz[2]; Ur[2]=Uteta[0]*Uz[1]-Uteta[1]*Uz[0];
2127       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2128       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2129       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2130     }
2131   ret->copyStringInfoFrom(*this);
2132   return ret.retn();
2133 }
2134
2135 /*!
2136  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2137  * array contating 6 components.
2138  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2139  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2140  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2141  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2142  *  \throw If \a this->getNumberOfComponents() != 6.
2143  */
2144 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2145 {
2146   checkAllocated();
2147   int nbOfComp(getNumberOfComponents());
2148   if(nbOfComp!=6)
2149     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2150   DataArrayDouble *ret=DataArrayDouble::New();
2151   int nbOfTuple=getNumberOfTuples();
2152   ret->alloc(nbOfTuple,1);
2153   const double *src=getConstPointer();
2154   double *dest=ret->getPointer();
2155   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2156     *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];
2157   return ret;
2158 }
2159
2160 /*!
2161  * Computes the determinant of every square matrix defined by the tuple of \a this
2162  * array, which contains either 4, 6 or 9 components. The case of 6 components
2163  * corresponds to that of the upper triangular matrix.
2164  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2165  *          is the determinant of matrix of the corresponding tuple of \a this array.
2166  *          The caller is to delete this result array using decrRef() as it is no more
2167  *          needed. 
2168  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2169  */
2170 DataArrayDouble *DataArrayDouble::determinant() const
2171 {
2172   checkAllocated();
2173   DataArrayDouble *ret=DataArrayDouble::New();
2174   int nbOfTuple=getNumberOfTuples();
2175   ret->alloc(nbOfTuple,1);
2176   const double *src=getConstPointer();
2177   double *dest=ret->getPointer();
2178   switch(getNumberOfComponents())
2179   {
2180     case 6:
2181       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2182         *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];
2183       return ret;
2184     case 4:
2185       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2186         *dest=src[0]*src[3]-src[1]*src[2];
2187       return ret;
2188     case 9:
2189       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2190         *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];
2191       return ret;
2192     default:
2193       ret->decrRef();
2194       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2195   }
2196 }
2197
2198 /*!
2199  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2200  * \a this array, which contains 6 components.
2201  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2202  *          components, whose each tuple contains the eigenvalues of the matrix of
2203  *          corresponding tuple of \a this array. 
2204  *          The caller is to delete this result array using decrRef() as it is no more
2205  *          needed. 
2206  *  \throw If \a this->getNumberOfComponents() != 6.
2207  */
2208 DataArrayDouble *DataArrayDouble::eigenValues() const
2209 {
2210   checkAllocated();
2211   int nbOfComp=getNumberOfComponents();
2212   if(nbOfComp!=6)
2213     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2214   DataArrayDouble *ret=DataArrayDouble::New();
2215   int nbOfTuple=getNumberOfTuples();
2216   ret->alloc(nbOfTuple,3);
2217   const double *src=getConstPointer();
2218   double *dest=ret->getPointer();
2219   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2220     INTERP_KERNEL::computeEigenValues6(src,dest);
2221   return ret;
2222 }
2223
2224 /*!
2225  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2226  * \a this array, which contains 6 components.
2227  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2228  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2229  *          corresponding tuple of \a this array.
2230  *          The caller is to delete this result array using decrRef() as it is no more
2231  *          needed.
2232  *  \throw If \a this->getNumberOfComponents() != 6.
2233  */
2234 DataArrayDouble *DataArrayDouble::eigenVectors() const
2235 {
2236   checkAllocated();
2237   int nbOfComp=getNumberOfComponents();
2238   if(nbOfComp!=6)
2239     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2240   DataArrayDouble *ret=DataArrayDouble::New();
2241   int nbOfTuple=getNumberOfTuples();
2242   ret->alloc(nbOfTuple,9);
2243   const double *src=getConstPointer();
2244   double *dest=ret->getPointer();
2245   for(int i=0;i<nbOfTuple;i++,src+=6)
2246     {
2247       double tmp[3];
2248       INTERP_KERNEL::computeEigenValues6(src,tmp);
2249       for(int j=0;j<3;j++,dest+=3)
2250         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2251     }
2252   return ret;
2253 }
2254
2255 /*!
2256  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2257  * array, which contains either 4, 6 or 9 components. The case of 6 components
2258  * corresponds to that of the upper triangular matrix.
2259  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2260  *          same number of components as \a this one, whose each tuple is the inverse
2261  *          matrix of the matrix of corresponding tuple of \a this array. 
2262  *          The caller is to delete this result array using decrRef() as it is no more
2263  *          needed. 
2264  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2265  */
2266 DataArrayDouble *DataArrayDouble::inverse() const
2267 {
2268   checkAllocated();
2269   int nbOfComp=getNumberOfComponents();
2270   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2271     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2272   DataArrayDouble *ret=DataArrayDouble::New();
2273   int nbOfTuple=getNumberOfTuples();
2274   ret->alloc(nbOfTuple,nbOfComp);
2275   const double *src=getConstPointer();
2276   double *dest=ret->getPointer();
2277   if(nbOfComp==6)
2278     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2279       {
2280         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];
2281         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2282         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2283         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2284         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2285         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2286         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2287       }
2288   else if(nbOfComp==4)
2289     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2290       {
2291         double det=src[0]*src[3]-src[1]*src[2];
2292         dest[0]=src[3]/det;
2293         dest[1]=-src[1]/det;
2294         dest[2]=-src[2]/det;
2295         dest[3]=src[0]/det;
2296       }
2297   else
2298     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2299       {
2300         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];
2301         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2302         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2303         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2304         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2305         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2306         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2307         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2308         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2309         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2310       }
2311   return ret;
2312 }
2313
2314 /*!
2315  * Computes the trace of every matrix defined by the tuple of \a this
2316  * array, which contains either 4, 6 or 9 components. The case of 6 components
2317  * corresponds to that of the upper triangular matrix.
2318  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2319  *          1 component, whose each tuple is the trace of
2320  *          the matrix of corresponding tuple of \a this array. 
2321  *          The caller is to delete this result array using decrRef() as it is no more
2322  *          needed. 
2323  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2324  */
2325 DataArrayDouble *DataArrayDouble::trace() const
2326 {
2327   checkAllocated();
2328   int nbOfComp=getNumberOfComponents();
2329   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2330     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2331   DataArrayDouble *ret=DataArrayDouble::New();
2332   int nbOfTuple=getNumberOfTuples();
2333   ret->alloc(nbOfTuple,1);
2334   const double *src=getConstPointer();
2335   double *dest=ret->getPointer();
2336   if(nbOfComp==6)
2337     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2338       *dest=src[0]+src[1]+src[2];
2339   else if(nbOfComp==4)
2340     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2341       *dest=src[0]+src[3];
2342   else
2343     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2344       *dest=src[0]+src[4]+src[8];
2345   return ret;
2346 }
2347
2348 /*!
2349  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2350  * \a this array, which contains 6 components.
2351  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2352  *          same number of components and tuples as \a this array.
2353  *          The caller is to delete this result array using decrRef() as it is no more
2354  *          needed.
2355  *  \throw If \a this->getNumberOfComponents() != 6.
2356  */
2357 DataArrayDouble *DataArrayDouble::deviator() const
2358 {
2359   checkAllocated();
2360   int nbOfComp=getNumberOfComponents();
2361   if(nbOfComp!=6)
2362     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2363   DataArrayDouble *ret=DataArrayDouble::New();
2364   int nbOfTuple=getNumberOfTuples();
2365   ret->alloc(nbOfTuple,6);
2366   const double *src=getConstPointer();
2367   double *dest=ret->getPointer();
2368   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2369     {
2370       double tr=(src[0]+src[1]+src[2])/3.;
2371       dest[0]=src[0]-tr;
2372       dest[1]=src[1]-tr;
2373       dest[2]=src[2]-tr;
2374       dest[3]=src[3];
2375       dest[4]=src[4];
2376       dest[5]=src[5];
2377     }
2378   return ret;
2379 }
2380
2381 /*!
2382  * Computes the magnitude of every vector defined by the tuple of
2383  * \a this array.
2384  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2385  *          same number of tuples as \a this array and one component.
2386  *          The caller is to delete this result array using decrRef() as it is no more
2387  *          needed.
2388  *  \throw If \a this is not allocated.
2389  */
2390 DataArrayDouble *DataArrayDouble::magnitude() const
2391 {
2392   checkAllocated();
2393   int nbOfComp=getNumberOfComponents();
2394   DataArrayDouble *ret=DataArrayDouble::New();
2395   int nbOfTuple=getNumberOfTuples();
2396   ret->alloc(nbOfTuple,1);
2397   const double *src=getConstPointer();
2398   double *dest=ret->getPointer();
2399   for(int i=0;i<nbOfTuple;i++,dest++)
2400     {
2401       double sum=0.;
2402       for(int j=0;j<nbOfComp;j++,src++)
2403         sum+=(*src)*(*src);
2404       *dest=sqrt(sum);
2405     }
2406   return ret;
2407 }
2408
2409 /*!
2410  * Computes for each tuple the sum of number of components values in the tuple and return it.
2411  * 
2412  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2413  *          same number of tuples as \a this array and one component.
2414  *          The caller is to delete this result array using decrRef() as it is no more
2415  *          needed.
2416  *  \throw If \a this is not allocated.
2417  */
2418 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2419 {
2420   checkAllocated();
2421   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2422   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2423   ret->alloc(nbOfTuple,1);
2424   const double *src(getConstPointer());
2425   double *dest(ret->getPointer());
2426   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2427     *dest=std::accumulate(src,src+nbOfComp,0.);
2428   return ret.retn();
2429 }
2430
2431 /*!
2432  * Computes the maximal value within every tuple of \a this array.
2433  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2434  *          same number of tuples as \a this array and one component.
2435  *          The caller is to delete this result array using decrRef() as it is no more
2436  *          needed.
2437  *  \throw If \a this is not allocated.
2438  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2439  */
2440 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2441 {
2442   checkAllocated();
2443   int nbOfComp=getNumberOfComponents();
2444   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2445   int nbOfTuple=getNumberOfTuples();
2446   ret->alloc(nbOfTuple,1);
2447   const double *src=getConstPointer();
2448   double *dest=ret->getPointer();
2449   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2450     *dest=*std::max_element(src,src+nbOfComp);
2451   return ret.retn();
2452 }
2453
2454 /*!
2455  * Computes the maximal value within every tuple of \a this array and it returns the first component
2456  * id for each tuple that corresponds to the maximal value within the tuple.
2457  * 
2458  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2459  *          same number of tuples and only one component.
2460  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2461  *          same number of tuples as \a this array and one component.
2462  *          The caller is to delete this result array using decrRef() as it is no more
2463  *          needed.
2464  *  \throw If \a this is not allocated.
2465  *  \sa DataArrayDouble::maxPerTuple
2466  */
2467 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2468 {
2469   checkAllocated();
2470   int nbOfComp=getNumberOfComponents();
2471   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2472   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2473   int nbOfTuple=getNumberOfTuples();
2474   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2475   const double *src=getConstPointer();
2476   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2477   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2478     {
2479       const double *loc=std::max_element(src,src+nbOfComp);
2480       *dest=*loc;
2481       *dest1=(int)std::distance(src,loc);
2482     }
2483   compoIdOfMaxPerTuple=ret1.retn();
2484   return ret0.retn();
2485 }
2486
2487 /*!
2488  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2489  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2490  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2491  * \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)
2492  *
2493  * \warning use this method with care because it can leads to big amount of consumed memory !
2494  * 
2495  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2496  *
2497  * \throw If \a this is not allocated.
2498  *
2499  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2500  */
2501 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2502 {
2503   checkAllocated();
2504   int nbOfComp=getNumberOfComponents();
2505   int nbOfTuples=getNumberOfTuples();
2506   const double *inData=getConstPointer();
2507   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2508   ret->alloc(nbOfTuples*nbOfTuples,1);
2509   double *outData=ret->getPointer();
2510   for(int i=0;i<nbOfTuples;i++)
2511     {
2512       outData[i*nbOfTuples+i]=0.;
2513       for(int j=i+1;j<nbOfTuples;j++)
2514         {
2515           double dist=0.;
2516           for(int k=0;k<nbOfComp;k++)
2517             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2518           dist=sqrt(dist);
2519           outData[i*nbOfTuples+j]=dist;
2520           outData[j*nbOfTuples+i]=dist;
2521         }
2522     }
2523   return ret.retn();
2524 }
2525
2526 /*!
2527  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2528  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2529  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2530  * \n Output rectangular matrix is sorted along rows.
2531  * \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)
2532  *
2533  * \warning use this method with care because it can leads to big amount of consumed memory !
2534  * 
2535  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2536  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2537  *
2538  * \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.
2539  *
2540  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2541  */
2542 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2543 {
2544   if(!other)
2545     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2546   checkAllocated();
2547   other->checkAllocated();
2548   int nbOfComp=getNumberOfComponents();
2549   int otherNbOfComp=other->getNumberOfComponents();
2550   if(nbOfComp!=otherNbOfComp)
2551     {
2552       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2553       throw INTERP_KERNEL::Exception(oss.str().c_str());
2554     }
2555   int nbOfTuples=getNumberOfTuples();
2556   int otherNbOfTuples=other->getNumberOfTuples();
2557   const double *inData=getConstPointer();
2558   const double *inDataOther=other->getConstPointer();
2559   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2560   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2561   double *outData=ret->getPointer();
2562   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2563     {
2564       for(int j=0;j<nbOfTuples;j++)
2565         {
2566           double dist=0.;
2567           for(int k=0;k<nbOfComp;k++)
2568             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2569           dist=sqrt(dist);
2570           outData[i*nbOfTuples+j]=dist;
2571         }
2572     }
2573   return ret.retn();
2574 }
2575
2576 /*!
2577  * Sorts value within every tuple of \a this array.
2578  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2579  *              in descending order.
2580  *  \throw If \a this is not allocated.
2581  */
2582 void DataArrayDouble::sortPerTuple(bool asc)
2583 {
2584   checkAllocated();
2585   double *pt=getPointer();
2586   int nbOfTuple=getNumberOfTuples();
2587   int nbOfComp=getNumberOfComponents();
2588   if(asc)
2589     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2590       std::sort(pt,pt+nbOfComp);
2591   else
2592     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2593       std::sort(pt,pt+nbOfComp,std::greater<double>());
2594   declareAsNew();
2595 }
2596
2597 /*!
2598  * Modify all elements of \a this array, so that
2599  * an element _x_ becomes \f$ numerator / x \f$.
2600  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2601  *           array, all elements processed before detection of the zero element remain
2602  *           modified.
2603  *  \param [in] numerator - the numerator used to modify array elements.
2604  *  \throw If \a this is not allocated.
2605  *  \throw If there is an element equal to 0.0 in \a this array.
2606  */
2607 void DataArrayDouble::applyInv(double numerator)
2608 {
2609   checkAllocated();
2610   double *ptr=getPointer();
2611   std::size_t nbOfElems=getNbOfElems();
2612   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2613     {
2614       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2615         {
2616           *ptr=numerator/(*ptr);
2617         }
2618       else
2619         {
2620           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2621           oss << " !";
2622           throw INTERP_KERNEL::Exception(oss.str().c_str());
2623         }
2624     }
2625   declareAsNew();
2626 }
2627
2628 /*!
2629  * Modify all elements of \a this array, so that
2630  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2631  * all values in \a this have to be >= 0 if val is \b not integer.
2632  *  \param [in] val - the value used to apply pow on all array elements.
2633  *  \throw If \a this is not allocated.
2634  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2635  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2636  *           modified.
2637  */
2638 void DataArrayDouble::applyPow(double val)
2639 {
2640   checkAllocated();
2641   double *ptr=getPointer();
2642   std::size_t nbOfElems=getNbOfElems();
2643   int val2=(int)val;
2644   bool isInt=((double)val2)==val;
2645   if(!isInt)
2646     {
2647       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2648         {
2649           if(*ptr>=0)
2650             *ptr=pow(*ptr,val);
2651           else
2652             {
2653               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2654               throw INTERP_KERNEL::Exception(oss.str().c_str());
2655             }
2656         }
2657     }
2658   else
2659     {
2660       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2661         *ptr=pow(*ptr,val2);
2662     }
2663   declareAsNew();
2664 }
2665
2666 /*!
2667  * Modify all elements of \a this array, so that
2668  * an element _x_ becomes \f$ val ^ x \f$.
2669  *  \param [in] val - the value used to apply pow on all array elements.
2670  *  \throw If \a this is not allocated.
2671  *  \throw If \a val < 0.
2672  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2673  *           array, all elements processed before detection of the zero element remain
2674  *           modified.
2675  */
2676 void DataArrayDouble::applyRPow(double val)
2677 {
2678   checkAllocated();
2679   if(val<0.)
2680     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2681   double *ptr=getPointer();
2682   std::size_t nbOfElems=getNbOfElems();
2683   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2684     *ptr=pow(val,*ptr);
2685   declareAsNew();
2686 }
2687
2688 /*!
2689  * Returns a new DataArrayDouble created from \a this one by applying \a
2690  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2691  * For more info see \ref MEDCouplingArrayApplyFunc
2692  *  \param [in] nbOfComp - number of components in the result array.
2693  *  \param [in] func - the \a FunctionToEvaluate declared as 
2694  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2695  *              where \a pos points to the first component of a tuple of \a this array
2696  *              and \a res points to the first component of a tuple of the result array.
2697  *              Note that length (number of components) of \a pos can differ from
2698  *              that of \a res.
2699  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2700  *          same number of tuples as \a this array.
2701  *          The caller is to delete this result array using decrRef() as it is no more
2702  *          needed.
2703  *  \throw If \a this is not allocated.
2704  *  \throw If \a func returns \a false.
2705  */
2706 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2707 {
2708   checkAllocated();
2709   DataArrayDouble *newArr=DataArrayDouble::New();
2710   int nbOfTuples=getNumberOfTuples();
2711   int oldNbOfComp=getNumberOfComponents();
2712   newArr->alloc(nbOfTuples,nbOfComp);
2713   const double *ptr=getConstPointer();
2714   double *ptrToFill=newArr->getPointer();
2715   for(int i=0;i<nbOfTuples;i++)
2716     {
2717       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2718         {
2719           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2720           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2721           oss << ") : Evaluation of function failed !";
2722           newArr->decrRef();
2723           throw INTERP_KERNEL::Exception(oss.str().c_str());
2724         }
2725     }
2726   return newArr;
2727 }
2728
2729 /*!
2730  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2731  * tuple of \a this array. Textual data is not copied.
2732  * For more info see \ref MEDCouplingArrayApplyFunc1.
2733  *  \param [in] nbOfComp - number of components in the result array.
2734  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2735  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2736  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2737  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2738  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2739  *          same number of tuples as \a this array and \a nbOfComp components.
2740  *          The caller is to delete this result array using decrRef() as it is no more
2741  *          needed.
2742  *  \throw If \a this is not allocated.
2743  *  \throw If computing \a func fails.
2744  */
2745 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2746 {
2747   INTERP_KERNEL::ExprParser expr(func);
2748   expr.parse();
2749   std::set<std::string> vars;
2750   expr.getTrueSetOfVars(vars);
2751   std::vector<std::string> varsV(vars.begin(),vars.end());
2752   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2753 }
2754
2755 /*!
2756  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2757  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2758  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2759  *
2760  * For more info see \ref MEDCouplingArrayApplyFunc0.
2761  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2762  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2763  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2764  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
2765  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2766  *          same number of tuples and components as \a this array.
2767  *          The caller is to delete this result array using decrRef() as it is no more
2768  *          needed.
2769  *  \sa applyFuncOnThis
2770  *  \throw If \a this is not allocated.
2771  *  \throw If computing \a func fails.
2772  */
2773 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2774 {
2775   int nbOfComp(getNumberOfComponents());
2776   if(nbOfComp<=0)
2777     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2778   checkAllocated();
2779   int nbOfTuples(getNumberOfTuples());
2780   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2781   newArr->alloc(nbOfTuples,nbOfComp);
2782   INTERP_KERNEL::ExprParser expr(func);
2783   expr.parse();
2784   std::set<std::string> vars;
2785   expr.getTrueSetOfVars(vars);
2786   if((int)vars.size()>1)
2787     {
2788       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 : ";
2789       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2790       throw INTERP_KERNEL::Exception(oss.str().c_str());
2791     }
2792   if(vars.empty())
2793     {
2794       expr.prepareFastEvaluator();
2795       newArr->rearrange(1);
2796       newArr->fillWithValue(expr.evaluateDouble());
2797       newArr->rearrange(nbOfComp);
2798       return newArr.retn();
2799     }
2800   std::vector<std::string> vars2(vars.begin(),vars.end());
2801   double buff,*ptrToFill(newArr->getPointer());
2802   const double *ptr(begin());
2803   std::vector<double> stck;
2804   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2805   expr.prepareFastEvaluator();
2806   if(!isSafe)
2807     {
2808       for(int i=0;i<nbOfTuples;i++)
2809         {
2810           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2811             {
2812               buff=*ptr;
2813               expr.evaluateDoubleInternal(stck);
2814               *ptrToFill=stck.back();
2815               stck.pop_back();
2816             }
2817         }
2818     }
2819   else
2820     {
2821       for(int i=0;i<nbOfTuples;i++)
2822         {
2823           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2824             {
2825               buff=*ptr;
2826               try
2827               {
2828                   expr.evaluateDoubleInternalSafe(stck);
2829               }
2830               catch(INTERP_KERNEL::Exception& e)
2831               {
2832                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2833                   oss << buff;
2834                   oss << ") : Evaluation of function failed !" << e.what();
2835                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2836               }
2837               *ptrToFill=stck.back();
2838               stck.pop_back();
2839             }
2840         }
2841     }
2842   return newArr.retn();
2843 }
2844
2845 /*!
2846  * This method is a non const method that modify the array in \a this.
2847  * This method only works on one component array. It means that function \a func must
2848  * contain at most one variable.
2849  * This method is a specialization of applyFunc method with one parameter on one component array.
2850  *
2851  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2852  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2853  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2854  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2855  *
2856  * \sa applyFunc
2857  */
2858 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2859 {
2860   int nbOfComp(getNumberOfComponents());
2861   if(nbOfComp<=0)
2862     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2863   checkAllocated();
2864   int nbOfTuples(getNumberOfTuples());
2865   INTERP_KERNEL::ExprParser expr(func);
2866   expr.parse();
2867   std::set<std::string> vars;
2868   expr.getTrueSetOfVars(vars);
2869   if((int)vars.size()>1)
2870     {
2871       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 : ";
2872       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2873       throw INTERP_KERNEL::Exception(oss.str().c_str());
2874     }
2875   if(vars.empty())
2876     {
2877       expr.prepareFastEvaluator();
2878       std::vector<std::string> compInfo(getInfoOnComponents());
2879       rearrange(1);
2880       fillWithValue(expr.evaluateDouble());
2881       rearrange(nbOfComp);
2882       setInfoOnComponents(compInfo);
2883       return ;
2884     }
2885   std::vector<std::string> vars2(vars.begin(),vars.end());
2886   double buff,*ptrToFill(getPointer());
2887   const double *ptr(begin());
2888   std::vector<double> stck;
2889   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2890   expr.prepareFastEvaluator();
2891   if(!isSafe)
2892     {
2893       for(int i=0;i<nbOfTuples;i++)
2894         {
2895           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2896             {
2897               buff=*ptr;
2898               expr.evaluateDoubleInternal(stck);
2899               *ptrToFill=stck.back();
2900               stck.pop_back();
2901             }
2902         }
2903     }
2904   else
2905     {
2906       for(int i=0;i<nbOfTuples;i++)
2907         {
2908           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2909             {
2910               buff=*ptr;
2911               try
2912               {
2913                   expr.evaluateDoubleInternalSafe(stck);
2914               }
2915               catch(INTERP_KERNEL::Exception& e)
2916               {
2917                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2918                   oss << buff;
2919                   oss << ") : Evaluation of function failed !" << e.what();
2920                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2921               }
2922               *ptrToFill=stck.back();
2923               stck.pop_back();
2924             }
2925         }
2926     }
2927 }
2928
2929 /*!
2930  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2931  * tuple of \a this array. Textual data is not copied.
2932  * For more info see \ref MEDCouplingArrayApplyFunc2.
2933  *  \param [in] nbOfComp - number of components in the result array.
2934  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2935  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2936  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2937  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2938  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2939  *          same number of tuples as \a this array.
2940  *          The caller is to delete this result array using decrRef() as it is no more
2941  *          needed.
2942  *  \throw If \a this is not allocated.
2943  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2944  *  \throw If computing \a func fails.
2945  */
2946 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2947 {
2948   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2949 }
2950
2951 /*!
2952  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2953  * tuple of \a this array. Textual data is not copied.
2954  * For more info see \ref MEDCouplingArrayApplyFunc3.
2955  *  \param [in] nbOfComp - number of components in the result array.
2956  *  \param [in] varsOrder - sequence of vars defining their order.
2957  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2958  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2959  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2960  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2961  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2962  *          same number of tuples as \a this array.
2963  *          The caller is to delete this result array using decrRef() as it is no more
2964  *          needed.
2965  *  \throw If \a this is not allocated.
2966  *  \throw If \a func contains vars not in \a varsOrder.
2967  *  \throw If computing \a func fails.
2968  */
2969 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2970 {
2971   if(nbOfComp<=0)
2972     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2973   std::vector<std::string> varsOrder2(varsOrder);
2974   int oldNbOfComp(getNumberOfComponents());
2975   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2976     varsOrder2.push_back(std::string());
2977   checkAllocated();
2978   int nbOfTuples(getNumberOfTuples());
2979   INTERP_KERNEL::ExprParser expr(func);
2980   expr.parse();
2981   std::set<std::string> vars;
2982   expr.getTrueSetOfVars(vars);
2983   if((int)vars.size()>oldNbOfComp)
2984     {
2985       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2986       oss << vars.size() << " variables : ";
2987       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2988       throw INTERP_KERNEL::Exception(oss.str().c_str());
2989     }
2990   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2991   newArr->alloc(nbOfTuples,nbOfComp);
2992   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2993   double *buffPtr(buff),*ptrToFill;
2994   std::vector<double> stck;
2995   for(int iComp=0;iComp<nbOfComp;iComp++)
2996     {
2997       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2998       expr.prepareFastEvaluator();
2999       const double *ptr(getConstPointer());
3000       ptrToFill=newArr->getPointer()+iComp;
3001       if(!isSafe)
3002         {
3003           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3004             {
3005               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3006               expr.evaluateDoubleInternal(stck);
3007               *ptrToFill=stck.back();
3008               stck.pop_back();
3009             }
3010         }
3011       else
3012         {
3013           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3014             {
3015               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3016               try
3017               {
3018                   expr.evaluateDoubleInternalSafe(stck);
3019                   *ptrToFill=stck.back();
3020                   stck.pop_back();
3021               }
3022               catch(INTERP_KERNEL::Exception& e)
3023               {
3024                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3025                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3026                   oss << ") : Evaluation of function failed !" << e.what();
3027                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3028               }
3029             }
3030         }
3031     }
3032   return newArr.retn();
3033 }
3034
3035 void DataArrayDouble::applyFuncFast32(const std::string& func)
3036 {
3037   checkAllocated();
3038   INTERP_KERNEL::ExprParser expr(func);
3039   expr.parse();
3040   char *funcStr=expr.compileX86();
3041   MYFUNCPTR funcPtr;
3042   *((void **)&funcPtr)=funcStr;//he he...
3043   //
3044   double *ptr=getPointer();
3045   int nbOfComp=getNumberOfComponents();
3046   int nbOfTuples=getNumberOfTuples();
3047   int nbOfElems=nbOfTuples*nbOfComp;
3048   for(int i=0;i<nbOfElems;i++,ptr++)
3049     *ptr=funcPtr(*ptr);
3050   declareAsNew();
3051 }
3052
3053 void DataArrayDouble::applyFuncFast64(const std::string& func)
3054 {
3055   checkAllocated();
3056   INTERP_KERNEL::ExprParser expr(func);
3057   expr.parse();
3058   char *funcStr=expr.compileX86_64();
3059   MYFUNCPTR funcPtr;
3060   *((void **)&funcPtr)=funcStr;//he he...
3061   //
3062   double *ptr=getPointer();
3063   int nbOfComp=getNumberOfComponents();
3064   int nbOfTuples=getNumberOfTuples();
3065   int nbOfElems=nbOfTuples*nbOfComp;
3066   for(int i=0;i<nbOfElems;i++,ptr++)
3067     *ptr=funcPtr(*ptr);
3068   declareAsNew();
3069 }
3070
3071 /*!
3072  * \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.
3073  */
3074 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3075 {
3076   checkAllocated();
3077   if(getNumberOfComponents()!=3)
3078     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3079   int nbTuples(getNumberOfTuples());
3080   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3081   ret->alloc(nbTuples,3);
3082   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3083   return ret;
3084 }
3085
3086 DataArrayDoubleIterator *DataArrayDouble::iterator()
3087 {
3088   return new DataArrayDoubleIterator(this);
3089 }
3090
3091 /*!
3092  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3093  * array whose values are within a given range. Textual data is not copied.
3094  *  \param [in] vmin - a lowest acceptable value (included).
3095  *  \param [in] vmax - a greatest acceptable value (included).
3096  *  \return DataArrayInt * - the new instance of DataArrayInt.
3097  *          The caller is to delete this result array using decrRef() as it is no more
3098  *          needed.
3099  *  \throw If \a this->getNumberOfComponents() != 1.
3100  *
3101  *  \sa DataArrayDouble::findIdsNotInRange
3102  *
3103  *  \if ENABLE_EXAMPLES
3104  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3105  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3106  *  \endif
3107  */
3108 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3109 {
3110   checkAllocated();
3111   if(getNumberOfComponents()!=1)
3112     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3113   const double *cptr(begin());
3114   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3115   int nbOfTuples(getNumberOfTuples());
3116   for(int i=0;i<nbOfTuples;i++,cptr++)
3117     if(*cptr>=vmin && *cptr<=vmax)
3118       ret->pushBackSilent(i);
3119   return ret.retn();
3120 }
3121
3122 /*!
3123  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3124  * array whose values are not within a given range. Textual data is not copied.
3125  *  \param [in] vmin - a lowest not acceptable value (excluded).
3126  *  \param [in] vmax - a greatest not acceptable value (excluded).
3127  *  \return DataArrayInt * - the new instance of DataArrayInt.
3128  *          The caller is to delete this result array using decrRef() as it is no more
3129  *          needed.
3130  *  \throw If \a this->getNumberOfComponents() != 1.
3131  *
3132  *  \sa DataArrayDouble::findIdsInRange
3133  */
3134 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3135 {
3136   checkAllocated();
3137   if(getNumberOfComponents()!=1)
3138     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3139   const double *cptr(begin());
3140   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3141   int nbOfTuples(getNumberOfTuples());
3142   for(int i=0;i<nbOfTuples;i++,cptr++)
3143     if(*cptr<vmin || *cptr>vmax)
3144       ret->pushBackSilent(i);
3145   return ret.retn();
3146 }
3147
3148 /*!
3149  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3150  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3151  * the number of component in the result array is same as that of each of given arrays.
3152  * Info on components is copied from the first of the given arrays. Number of components
3153  * in the given arrays must be  the same.
3154  *  \param [in] a1 - an array to include in the result array.
3155  *  \param [in] a2 - another array to include in the result array.
3156  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3157  *          The caller is to delete this result array using decrRef() as it is no more
3158  *          needed.
3159  *  \throw If both \a a1 and \a a2 are NULL.
3160  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3161  */
3162 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3163 {
3164   std::vector<const DataArrayDouble *> tmp(2);
3165   tmp[0]=a1; tmp[1]=a2;
3166   return Aggregate(tmp);
3167 }
3168
3169 /*!
3170  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3171  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3172  * the number of component in the result array is same as that of each of given arrays.
3173  * Info on components is copied from the first of the given arrays. Number of components
3174  * in the given arrays must be  the same.
3175  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3176  * not the object itself.
3177  *  \param [in] arr - a sequence of arrays to include in the result array.
3178  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3179  *          The caller is to delete this result array using decrRef() as it is no more
3180  *          needed.
3181  *  \throw If all arrays within \a arr are NULL.
3182  *  \throw If getNumberOfComponents() of arrays within \a arr.
3183  */
3184 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3185 {
3186   std::vector<const DataArrayDouble *> a;
3187   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3188     if(*it4)
3189       a.push_back(*it4);
3190   if(a.empty())
3191     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3192   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3193   std::size_t nbOfComp((*it)->getNumberOfComponents());
3194   int nbt=(*it++)->getNumberOfTuples();
3195   for(int i=1;it!=a.end();it++,i++)
3196     {
3197       if((*it)->getNumberOfComponents()!=nbOfComp)
3198         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3199       nbt+=(*it)->getNumberOfTuples();
3200     }
3201   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3202   ret->alloc(nbt,nbOfComp);
3203   double *pt=ret->getPointer();
3204   for(it=a.begin();it!=a.end();it++)
3205     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3206   ret->copyStringInfoFrom(*(a[0]));
3207   return ret.retn();
3208 }
3209
3210 /*!
3211  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3212  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3213  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3214  * Info on components and name is copied from the first of the given arrays.
3215  * Number of tuples and components in the given arrays must be the same.
3216  *  \param [in] a1 - a given array.
3217  *  \param [in] a2 - another given array.
3218  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3219  *          The caller is to delete this result array using decrRef() as it is no more
3220  *          needed.
3221  *  \throw If either \a a1 or \a a2 is NULL.
3222  *  \throw If any given array is not allocated.
3223  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3224  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3225  */
3226 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3227 {
3228   if(!a1 || !a2)
3229     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3230   a1->checkAllocated();
3231   a2->checkAllocated();
3232   std::size_t nbOfComp(a1->getNumberOfComponents());
3233   if(nbOfComp!=a2->getNumberOfComponents())
3234     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3235   int nbOfTuple=a1->getNumberOfTuples();
3236   if(nbOfTuple!=a2->getNumberOfTuples())
3237     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3238   DataArrayDouble *ret=DataArrayDouble::New();
3239   ret->alloc(nbOfTuple,1);
3240   double *retPtr=ret->getPointer();
3241   const double *a1Ptr=a1->getConstPointer();
3242   const double *a2Ptr=a2->getConstPointer();
3243   for(int i=0;i<nbOfTuple;i++)
3244     {
3245       double sum=0.;
3246       for(std::size_t j=0;j<nbOfComp;j++)
3247         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3248       retPtr[i]=sum;
3249     }
3250   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3251   ret->setName(a1->getName());
3252   return ret;
3253 }
3254
3255 /*!
3256  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3257  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3258  * product of two vectors defined by the i-th tuples of given arrays.
3259  * Info on components is copied from the first of the given arrays.
3260  * Number of tuples in the given arrays must be the same.
3261  * Number of components in the given arrays must be 3.
3262  *  \param [in] a1 - a given array.
3263  *  \param [in] a2 - another given array.
3264  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3265  *          The caller is to delete this result array using decrRef() as it is no more
3266  *          needed.
3267  *  \throw If either \a a1 or \a a2 is NULL.
3268  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3269  *  \throw If \a a1->getNumberOfComponents() != 3
3270  *  \throw If \a a2->getNumberOfComponents() != 3
3271  */
3272 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3273 {
3274   if(!a1 || !a2)
3275     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3276   std::size_t nbOfComp(a1->getNumberOfComponents());
3277   if(nbOfComp!=a2->getNumberOfComponents())
3278     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3279   if(nbOfComp!=3)
3280     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3281   int nbOfTuple=a1->getNumberOfTuples();
3282   if(nbOfTuple!=a2->getNumberOfTuples())
3283     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3284   DataArrayDouble *ret=DataArrayDouble::New();
3285   ret->alloc(nbOfTuple,3);
3286   double *retPtr=ret->getPointer();
3287   const double *a1Ptr=a1->getConstPointer();
3288   const double *a2Ptr=a2->getConstPointer();
3289   for(int i=0;i<nbOfTuple;i++)
3290     {
3291       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3292       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3293       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3294     }
3295   ret->copyStringInfoFrom(*a1);
3296   return ret;
3297 }
3298
3299 /*!
3300  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3301  * Info on components is copied from the first of the given arrays.
3302  * Number of tuples and components in the given arrays must be the same.
3303  *  \param [in] a1 - an array to compare values with another one.
3304  *  \param [in] a2 - another array to compare values with the first one.
3305  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3306  *          The caller is to delete this result array using decrRef() as it is no more
3307  *          needed.
3308  *  \throw If either \a a1 or \a a2 is NULL.
3309  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3310  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3311  */
3312 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3313 {
3314   if(!a1 || !a2)
3315     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3316   std::size_t nbOfComp(a1->getNumberOfComponents());
3317   if(nbOfComp!=a2->getNumberOfComponents())
3318     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3319   int nbOfTuple=a1->getNumberOfTuples();
3320   if(nbOfTuple!=a2->getNumberOfTuples())
3321     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3322   DataArrayDouble *ret=DataArrayDouble::New();
3323   ret->alloc(nbOfTuple,nbOfComp);
3324   double *retPtr=ret->getPointer();
3325   const double *a1Ptr=a1->getConstPointer();
3326   const double *a2Ptr=a2->getConstPointer();
3327   int nbElem=nbOfTuple*nbOfComp;
3328   for(int i=0;i<nbElem;i++)
3329     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3330   ret->copyStringInfoFrom(*a1);
3331   return ret;
3332 }
3333
3334 /*!
3335  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3336  * Info on components is copied from the first of the given arrays.
3337  * Number of tuples and components in the given arrays must be the same.
3338  *  \param [in] a1 - an array to compare values with another one.
3339  *  \param [in] a2 - another array to compare values with the first one.
3340  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3341  *          The caller is to delete this result array using decrRef() as it is no more
3342  *          needed.
3343  *  \throw If either \a a1 or \a a2 is NULL.
3344  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3345  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3346  */
3347 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3348 {
3349   if(!a1 || !a2)
3350     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3351   std::size_t nbOfComp(a1->getNumberOfComponents());
3352   if(nbOfComp!=a2->getNumberOfComponents())
3353     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3354   int nbOfTuple=a1->getNumberOfTuples();
3355   if(nbOfTuple!=a2->getNumberOfTuples())
3356     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3357   DataArrayDouble *ret=DataArrayDouble::New();
3358   ret->alloc(nbOfTuple,nbOfComp);
3359   double *retPtr=ret->getPointer();
3360   const double *a1Ptr=a1->getConstPointer();
3361   const double *a2Ptr=a2->getConstPointer();
3362   int nbElem=nbOfTuple*nbOfComp;
3363   for(int i=0;i<nbElem;i++)
3364     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3365   ret->copyStringInfoFrom(*a1);
3366   return ret;
3367 }
3368
3369 /*!
3370  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3371  * valid cases.
3372  *
3373  *  \param [in] a1 - an array to pow up.
3374  *  \param [in] a2 - another array to sum up.
3375  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3376  *          The caller is to delete this result array using decrRef() as it is no more
3377  *          needed.
3378  *  \throw If either \a a1 or \a a2 is NULL.
3379  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3380  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3381  *  \throw If there is a negative value in \a a1.
3382  */
3383 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3384 {
3385   if(!a1 || !a2)
3386     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3387   int nbOfTuple=a1->getNumberOfTuples();
3388   int nbOfTuple2=a2->getNumberOfTuples();
3389   int nbOfComp=a1->getNumberOfComponents();
3390   int nbOfComp2=a2->getNumberOfComponents();
3391   if(nbOfTuple!=nbOfTuple2)
3392     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3393   if(nbOfComp!=1 || nbOfComp2!=1)
3394     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3395   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3396   const double *ptr1(a1->begin()),*ptr2(a2->begin());
3397   double *ptr=ret->getPointer();
3398   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3399     {
3400       if(*ptr1>=0)
3401         {
3402           *ptr=pow(*ptr1,*ptr2);
3403         }
3404       else
3405         {
3406           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3407           throw INTERP_KERNEL::Exception(oss.str().c_str());
3408         }
3409     }
3410   return ret.retn();
3411 }
3412
3413 /*!
3414  * Apply pow on values of another DataArrayDouble to values of \a this one.
3415  *
3416  *  \param [in] other - an array to pow to \a this one.
3417  *  \throw If \a other is NULL.
3418  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3419  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3420  *  \throw If there is a negative value in \a this.
3421  */
3422 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3423 {
3424   if(!other)
3425     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3426   int nbOfTuple=getNumberOfTuples();
3427   int nbOfTuple2=other->getNumberOfTuples();
3428   int nbOfComp=getNumberOfComponents();
3429   int nbOfComp2=other->getNumberOfComponents();
3430   if(nbOfTuple!=nbOfTuple2)
3431     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3432   if(nbOfComp!=1 || nbOfComp2!=1)
3433     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3434   double *ptr=getPointer();
3435   const double *ptrc=other->begin();
3436   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3437     {
3438       if(*ptr>=0)
3439         *ptr=pow(*ptr,*ptrc);
3440       else
3441         {
3442           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3443           throw INTERP_KERNEL::Exception(oss.str().c_str());
3444         }
3445     }
3446   declareAsNew();
3447 }
3448
3449 /*!
3450  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3451  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3452  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3453  *
3454  * \throw if \a this is not allocated.
3455  * \throw if \a this has not exactly one component.
3456  */
3457 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3458 {
3459   checkAllocated();
3460   if(getNumberOfComponents()!=1)
3461     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3462   int nbt(getNumberOfTuples());
3463   std::vector<bool> ret(nbt);
3464   const double *pt(begin());
3465   for(int i=0;i<nbt;i++)
3466     {
3467       if(fabs(pt[i])<eps)
3468         ret[i]=false;
3469       else if(fabs(pt[i]-1.)<eps)
3470         ret[i]=true;
3471       else
3472         {
3473           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3474           throw INTERP_KERNEL::Exception(oss.str().c_str());
3475         }
3476     }
3477   return ret;
3478 }
3479
3480 /*!
3481  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3482  * Server side.
3483  */
3484 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3485 {
3486   tinyInfo.resize(2);
3487   if(isAllocated())
3488     {
3489       tinyInfo[0]=getNumberOfTuples();
3490       tinyInfo[1]=getNumberOfComponents();
3491     }
3492   else
3493     {
3494       tinyInfo[0]=-1;
3495       tinyInfo[1]=-1;
3496     }
3497 }
3498
3499 /*!
3500  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3501  * Server side.
3502  */
3503 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3504 {
3505   if(isAllocated())
3506     {
3507       int nbOfCompo=getNumberOfComponents();
3508       tinyInfo.resize(nbOfCompo+1);
3509       tinyInfo[0]=getName();
3510       for(int i=0;i<nbOfCompo;i++)
3511         tinyInfo[i+1]=getInfoOnComponent(i);
3512     }
3513   else
3514     {
3515       tinyInfo.resize(1);
3516       tinyInfo[0]=getName();
3517     }
3518 }
3519
3520 /*!
3521  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3522  * This method returns if a feeding is needed.
3523  */
3524 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3525 {
3526   int nbOfTuple=tinyInfoI[0];
3527   int nbOfComp=tinyInfoI[1];
3528   if(nbOfTuple!=-1 || nbOfComp!=-1)
3529     {
3530       alloc(nbOfTuple,nbOfComp);
3531       return true;
3532     }
3533   return false;
3534 }
3535
3536 /*!
3537  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3538  */
3539 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3540 {
3541   setName(tinyInfoS[0]);
3542   if(isAllocated())
3543     {
3544       int nbOfCompo=getNumberOfComponents();
3545       for(int i=0;i<nbOfCompo;i++)
3546         setInfoOnComponent(i,tinyInfoS[i+1]);
3547     }
3548 }
3549
3550 /*!
3551  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3552  * around an axe ( \a center, \a vect) and with angle \a angle.
3553  */
3554 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3555 {
3556   if(!center || !vect)
3557     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3558   double sina(sin(angle));
3559   double cosa(cos(angle));
3560   double vectorNorm[3];
3561   double matrix[9];
3562   double matrixTmp[9];
3563   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3564   if(norm<std::numeric_limits<double>::min())
3565     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3566   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3567   //rotation matrix computation
3568   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;
3569   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3570   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3571   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3572   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3573   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3574   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3575   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3576   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3577   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3578   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3579   //rotation matrix computed.
3580   double tmp[3];
3581   for(int i=0; i<nbNodes; i++)
3582     {
3583       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3584       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3585       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3586       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3587     }
3588 }
3589
3590 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3591 {
3592   double matrix[9],matrix2[9],matrix3[9];
3593   double vect[3],crossVect[3];
3594   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3595   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3596   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3597   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3598   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3599   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3600   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3601   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3602   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3603   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3604   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3605   for(int i=0;i<3;i++)
3606     for(int j=0;j<3;j++)
3607       {
3608         double val(0.);
3609         for(int k=0;k<3;k++)
3610           val+=matrix[3*i+k]*matrix2[3*k+j];
3611         matrix3[3*i+j]=val;
3612       }
3613   //rotation matrix computed.
3614   double tmp[3];
3615   for(int i=0; i<nbNodes; i++)
3616     {
3617       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3618       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3619       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3620       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3621     }
3622 }
3623
3624 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3625 {
3626   double vect[3],crossVect[3];
3627   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3628   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3629   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3630   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3631   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3632   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3633   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3634   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3635 }
3636
3637 /*!
3638  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3639  * around the center point \a center and with angle \a angle.
3640  */
3641 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3642 {
3643   double cosa=cos(angle);
3644   double sina=sin(angle);
3645   double matrix[4];
3646   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3647   double tmp[2];
3648   for(int i=0; i<nbNodes; i++)
3649     {
3650       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3651       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3652       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3653     }
3654 }
3655
3656 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3657 {
3658 }
3659
3660 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3661 {
3662 }
3663
3664
3665 std::string DataArrayDoubleTuple::repr() const
3666 {
3667   std::ostringstream oss; oss.precision(17); oss << "(";
3668   for(int i=0;i<_nb_of_compo-1;i++)
3669     oss << _pt[i] << ", ";
3670   oss << _pt[_nb_of_compo-1] << ")";
3671   return oss.str();
3672 }
3673
3674 double DataArrayDoubleTuple::doubleValue() const
3675 {
3676   return this->zeValue();
3677 }
3678
3679 /*!
3680  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3681  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3682  * 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
3683  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3684  */
3685 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3686 {
3687   return this->buildDA(nbOfTuples,nbOfCompo);
3688 }
3689
3690 /*!
3691  * Returns a new instance of DataArrayInt. The caller is to delete this array
3692  * using decrRef() as it is no more needed. 
3693  */
3694 DataArrayInt *DataArrayInt::New()
3695 {
3696   return new DataArrayInt;
3697 }
3698
3699 /*!
3700  * Returns the only one value in \a this, if and only if number of elements
3701  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3702  *  \return double - the sole value stored in \a this array.
3703  *  \throw If at least one of conditions stated above is not fulfilled.
3704  */
3705 int DataArrayInt::intValue() const
3706 {
3707   if(isAllocated())
3708     {
3709       if(getNbOfElems()==1)
3710         {
3711           return *getConstPointer();
3712         }
3713       else
3714         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3715     }
3716   else
3717     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3718 }
3719
3720 /*!
3721  * Returns an integer value characterizing \a this array, which is useful for a quick
3722  * comparison of many instances of DataArrayInt.
3723  *  \return int - the hash value.
3724  *  \throw If \a this is not allocated.
3725  */
3726 int DataArrayInt::getHashCode() const
3727 {
3728   checkAllocated();
3729   std::size_t nbOfElems=getNbOfElems();
3730   int ret=nbOfElems*65536;
3731   int delta=3;
3732   if(nbOfElems>48)
3733     delta=nbOfElems/8;
3734   int ret0=0;
3735   const int *pt=begin();
3736   for(std::size_t i=0;i<nbOfElems;i+=delta)
3737     ret0+=pt[i] & 0x1FFF;
3738   return ret+ret0;
3739 }
3740
3741 /*!
3742  * Returns a full copy of \a this. For more info on copying data arrays see
3743  * \ref MEDCouplingArrayBasicsCopyDeep.
3744  *  \return DataArrayInt * - a new instance of DataArrayInt.
3745  */
3746 DataArrayInt32 *DataArrayInt32::deepCopy() const
3747 {
3748   return new DataArrayInt32(*this);
3749 }
3750
3751 /*!
3752  * Assign zero to all values in \a this array. To know more on filling arrays see
3753  * \ref MEDCouplingArrayFill.
3754  * \throw If \a this is not allocated.
3755  */
3756 void DataArrayInt::fillWithZero()
3757 {
3758   fillWithValue(0);
3759 }
3760
3761 /*!
3762  * Set all values in \a this array so that the i-th element equals to \a init + i
3763  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3764  *  \param [in] init - value to assign to the first element of array.
3765  *  \throw If \a this->getNumberOfComponents() != 1
3766  *  \throw If \a this is not allocated.
3767  */
3768 void DataArrayInt::iota(int init)
3769 {
3770   checkAllocated();
3771   if(getNumberOfComponents()!=1)
3772     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3773   int *ptr=getPointer();
3774   int ntuples=getNumberOfTuples();
3775   for(int i=0;i<ntuples;i++)
3776     ptr[i]=init+i;
3777   declareAsNew();
3778 }
3779
3780 /*!
3781  * Returns a textual and human readable representation of \a this instance of
3782  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3783  * \return std::string - text describing \a this DataArrayInt.
3784  * 
3785  * \sa reprNotTooLong, reprZip
3786  */
3787 std::string DataArrayInt::repr() const
3788 {
3789   std::ostringstream ret;
3790   reprStream(ret);
3791   return ret.str();
3792 }
3793
3794 std::string DataArrayInt::reprZip() const
3795 {
3796   std::ostringstream ret;
3797   reprZipStream(ret);
3798   return ret.str();
3799 }
3800
3801 /*!
3802  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3803  * printed out to avoid to consume too much space in interpretor.
3804  * \sa repr
3805  */
3806 std::string DataArrayInt::reprNotTooLong() const
3807 {
3808   std::ostringstream ret;
3809   reprNotTooLongStream(ret);
3810   return ret.str();
3811 }
3812
3813 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3814 {
3815   static const char SPACE[4]={' ',' ',' ',' '};
3816   checkAllocated();
3817   std::string idt(indent,' ');
3818   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3819   if(byteArr)
3820     {
3821       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3822       if(std::string(type)=="Int32")
3823         {
3824           const char *data(reinterpret_cast<const char *>(begin()));
3825           std::size_t sz(getNbOfElems()*sizeof(int));
3826           byteArr->insertAtTheEnd(data,data+sz);
3827           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3828         }
3829       else if(std::string(type)=="Int8")
3830         {
3831           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3832           std::copy(begin(),end(),(char *)tmp);
3833           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3834           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3835         }
3836       else if(std::string(type)=="UInt8")
3837         {
3838           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3839           std::copy(begin(),end(),(unsigned char *)tmp);
3840           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3841           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3842         }
3843       else
3844         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3845     }
3846   else
3847     {
3848       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3849       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3850     }
3851   ofs << std::endl << idt << "</DataArray>\n";
3852 }
3853
3854 void DataArrayInt::reprStream(std::ostream& stream) const
3855 {
3856   stream << "Name of int array : \"" << _name << "\"\n";
3857   reprWithoutNameStream(stream);
3858 }
3859
3860 void DataArrayInt::reprZipStream(std::ostream& stream) const
3861 {
3862   stream << "Name of int array : \"" << _name << "\"\n";
3863   reprZipWithoutNameStream(stream);
3864 }
3865
3866 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
3867 {
3868   stream << "Name of int array : \"" << _name << "\"\n";
3869   reprNotTooLongWithoutNameStream(stream);
3870 }
3871
3872 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
3873 {
3874   DataArray::reprWithoutNameStream(stream);
3875   _mem.repr(getNumberOfComponents(),stream);
3876 }
3877
3878 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
3879 {
3880   DataArray::reprWithoutNameStream(stream);
3881   _mem.reprZip(getNumberOfComponents(),stream);
3882 }
3883
3884 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3885 {
3886   DataArray::reprWithoutNameStream(stream);
3887   stream.precision(17);
3888   _mem.reprNotTooLong(getNumberOfComponents(),stream);
3889 }
3890
3891 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3892 {
3893   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3894   const int *data=getConstPointer();
3895   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3896   if(nbTuples*nbComp>=1)
3897     {
3898       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3899       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3900       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3901       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3902     }
3903   else
3904     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3905   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3906 }
3907
3908 /*!
3909  * Method that gives a quick overvien of \a this for python.
3910  */
3911 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3912 {
3913   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3914   stream << "DataArrayInt C++ instance at " << this << ". ";
3915   if(isAllocated())
3916     {
3917       int nbOfCompo=(int)_info_on_compo.size();
3918       if(nbOfCompo>=1)
3919         {
3920           int nbOfTuples=getNumberOfTuples();
3921           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3922           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3923         }
3924       else
3925         stream << "Number of components : 0.";
3926     }
3927   else
3928     stream << "*** No data allocated ****";
3929 }
3930
3931 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3932 {
3933   const int *data=begin();
3934   int nbOfTuples=getNumberOfTuples();
3935   int nbOfCompo=(int)_info_on_compo.size();
3936   std::ostringstream oss2; oss2 << "[";
3937   std::string oss2Str(oss2.str());
3938   bool isFinished=true;
3939   for(int i=0;i<nbOfTuples && isFinished;i++)
3940     {
3941       if(nbOfCompo>1)
3942         {
3943           oss2 << "(";
3944           for(int j=0;j<nbOfCompo;j++,data++)
3945             {
3946               oss2 << *data;
3947               if(j!=nbOfCompo-1) oss2 << ", ";
3948             }
3949           oss2 << ")";
3950         }
3951       else
3952         oss2 << *data++;
3953       if(i!=nbOfTuples-1) oss2 << ", ";
3954       std::string oss3Str(oss2.str());
3955       if(oss3Str.length()<maxNbOfByteInRepr)
3956         oss2Str=oss3Str;
3957       else
3958         isFinished=false;
3959     }
3960   stream << oss2Str;
3961   if(!isFinished)
3962     stream << "... ";
3963   stream << "]";
3964 }
3965
3966 /*!
3967  * Computes distribution of values of \a this one-dimensional array between given value
3968  * ranges (casts). This method is typically useful for entity number spliting by types,
3969  * for example. 
3970  *  \warning The values contained in \a arrBg should be sorted ascendently. No
3971  *           check of this is be done. If not, the result is not warranted. 
3972  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3973  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3974  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3975  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3976  *         should be more than every value in \a this array.
3977  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3978  *              the last value of \a arrBg is \a arrEnd[ -1 ].
3979  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3980  *         (same number of tuples and components), the caller is to delete 
3981  *         using decrRef() as it is no more needed.
3982  *         This array contains indices of ranges for every value of \a this array. I.e.
3983  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
3984  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
3985  *         this in which cast it holds.
3986  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3987  *         array, the caller is to delete using decrRef() as it is no more needed.
3988  *         This array contains ranks of values of \a this array within ranges
3989  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3990  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3991  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
3992  *         for each tuple its rank inside its cast. The rank is computed as difference
3993  *         between the value and the lowest value of range.
3994  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3995  *         ranges (casts) to which at least one value of \a this array belongs.
3996  *         Or, in other words, this param contains the casts that \a this contains.
3997  *         The caller is to delete this array using decrRef() as it is no more needed.
3998  *
3999  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4000  *            the output of this method will be : 
4001  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4002  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4003  * - \a castsPresent  : [0,1]
4004  *
4005  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4006  * range #1 and its rank within this range is 2; etc.
4007  *
4008  *  \throw If \a this->getNumberOfComponents() != 1.
4009  *  \throw If \a arrEnd - arrBg < 2.
4010  *  \throw If any value of \a this is not less than \a arrEnd[-1].
4011  */
4012 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4013                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4014 {
4015   checkAllocated();
4016   if(getNumberOfComponents()!=1)
4017     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4018   int nbOfTuples=getNumberOfTuples();
4019   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4020   if(nbOfCast<2)
4021     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4022   nbOfCast--;
4023   const int *work=getConstPointer();
4024   typedef std::reverse_iterator<const int *> rintstart;
4025   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4026   rintstart end2(arrBg);
4027   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4028   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4029   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4030   ret1->alloc(nbOfTuples,1);
4031   ret2->alloc(nbOfTuples,1);
4032   int *ret1Ptr=ret1->getPointer();
4033   int *ret2Ptr=ret2->getPointer();
4034   std::set<std::size_t> castsDetected;
4035   for(int i=0;i<nbOfTuples;i++)
4036     {
4037       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4038       std::size_t pos=std::distance(bg,res);
4039       std::size_t pos2=nbOfCast-pos;
4040       if(pos2<nbOfCast)
4041         {
4042           ret1Ptr[i]=(int)pos2;
4043           ret2Ptr[i]=work[i]-arrBg[pos2];
4044           castsDetected.insert(pos2);
4045         }
4046       else
4047         {
4048           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4049           throw INTERP_KERNEL::Exception(oss.str().c_str());
4050         }
4051     }
4052   ret3->alloc((int)castsDetected.size(),1);
4053   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4054   castArr=ret1.retn();
4055   rankInsideCast=ret2.retn();
4056   castsPresent=ret3.retn();
4057 }
4058
4059 /*!
4060  * 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 ).
4061  * 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 ).
4062  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4063  *
4064  * \param [out] strt - the start of the range (included) if true is returned.
4065  * \param [out] sttoopp - the end of the range (not included) if true is returned.
4066  * \param [out] stteepp - the step of the range if true is returned.
4067  * \return the verdict of the check.
4068  *
4069  * \sa DataArray::GetNumberOfItemGivenBES
4070  */
4071 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4072 {
4073   checkAllocated();
4074   if(getNumberOfComponents()!=1)
4075     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4076   int nbTuples(getNumberOfTuples());
4077   if(nbTuples==0)
4078     { strt=0; sttoopp=0; stteepp=1; return true; }
4079   const int *pt(begin());
4080   strt=*pt; 
4081   if(nbTuples==1)
4082     { sttoopp=strt+1; stteepp=1; return true; }
4083   strt=*pt; sttoopp=pt[nbTuples-1];
4084   if(strt==sttoopp)
4085     return false;
4086   if(sttoopp>strt)
4087     {
4088       sttoopp++;
4089       int a(sttoopp-1-strt),tmp(strt);
4090       if(a%(nbTuples-1)!=0)
4091         return false;
4092       stteepp=a/(nbTuples-1);
4093       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4094         if(pt[i]!=tmp)
4095           return false;
4096       return true;
4097     }
4098   else
4099     {
4100       sttoopp--;
4101       int a(strt-sttoopp-1),tmp(strt);
4102       if(a%(nbTuples-1)!=0)
4103         return false;
4104       stteepp=-(a/(nbTuples-1));
4105       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4106         if(pt[i]!=tmp)
4107           return false;
4108       return true;
4109     }
4110 }
4111
4112
4113 /*!
4114  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4115  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4116  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4117  *         to \a this array.
4118  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4119  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4120  *  \throw If \a this->getNumberOfComponents() != 1
4121  *  \throw If any value of \a this can't be used as a valid index for 
4122  *         [\a indArrBg, \a indArrEnd).
4123  *
4124  *  \sa changeValue
4125  */
4126 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4127 {
4128   this->checkAllocated();
4129   if(this->getNumberOfComponents()!=1)
4130     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4131   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4132   for(int i=0;i<nbOfTuples;i++,pt++)
4133     {
4134       if(*pt>=0 && *pt<nbElemsIn)
4135         *pt=indArrBg[*pt];
4136       else
4137         {
4138           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4139           throw INTERP_KERNEL::Exception(oss.str().c_str());
4140         }
4141     }
4142   this->declareAsNew();
4143 }
4144
4145 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4146 {
4147   this->checkAllocated();
4148   if(this->getNumberOfComponents()!=1)
4149     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4150   const std::map<int,int> dat(m.data());
4151   int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4152   for(int i=0;i<nbOfTuples;i++,pt++)
4153     {
4154       std::map<int,int>::const_iterator it(dat.find(*pt));
4155       if(it!=dat.end())
4156         *pt=(*it).second;
4157       else
4158         {
4159           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4160           throw INTERP_KERNEL::Exception(oss.str().c_str());
4161         }
4162     }
4163   this->declareAsNew();
4164 }
4165
4166 /*!
4167  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
4168  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4169  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4170  * new value in place \a indArr[ \a v ] is i.
4171  *  \param [in] indArrBg - the array holding indices within the result array to assign
4172  *         indices of values of \a this array pointing to values of \a indArrBg.
4173  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4174  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4175  *  \return DataArrayInt * - the new instance of DataArrayInt.
4176  *          The caller is to delete this result array using decrRef() as it is no more
4177  *          needed.
4178  *  \throw If \a this->getNumberOfComponents() != 1.
4179  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
4180  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
4181  */
4182 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4183 {
4184   checkAllocated();
4185   if(getNumberOfComponents()!=1)
4186     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4187   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4188   int nbOfTuples=getNumberOfTuples();
4189   const int *pt=getConstPointer();
4190   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4191   ret->alloc(nbOfTuples,1);
4192   ret->fillWithValue(-1);
4193   int *tmp=ret->getPointer();
4194   for(int i=0;i<nbOfTuples;i++,pt++)
4195     {
4196       if(*pt>=0 && *pt<nbElemsIn)
4197         {
4198           int pos=indArrBg[*pt];
4199           if(pos>=0 && pos<nbOfTuples)
4200             tmp[pos]=i;
4201           else
4202             {
4203               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4204               throw INTERP_KERNEL::Exception(oss.str().c_str());
4205             }
4206         }
4207       else
4208         {
4209           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4210           throw INTERP_KERNEL::Exception(oss.str().c_str());
4211         }
4212     }
4213   return ret.retn();
4214 }
4215
4216 /*!
4217  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4218  * from values of \a this array, which is supposed to contain a renumbering map in 
4219  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4220  * To know how to use the renumbering maps see \ref numbering.
4221  *  \param [in] newNbOfElem - the number of tuples in the result array.
4222  *  \return DataArrayInt * - the new instance of DataArrayInt.
4223  *          The caller is to delete this result array using decrRef() as it is no more
4224  *          needed.
4225  * 
4226  *  \if ENABLE_EXAMPLES
4227  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4228  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
4229  *  \endif
4230  */
4231 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4232 {
4233   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4234   ret->alloc(newNbOfElem,1);
4235   int nbOfOldNodes(this->getNumberOfTuples());
4236   const int *old2New(begin());
4237   int *pt(ret->getPointer());
4238   for(int i=0;i!=nbOfOldNodes;i++)
4239     {
4240       int newp(old2New[i]);
4241       if(newp!=-1)
4242         {
4243           if(newp>=0 && newp<newNbOfElem)
4244             pt[newp]=i;
4245           else
4246             {
4247               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4248               throw INTERP_KERNEL::Exception(oss.str().c_str());
4249             }
4250         }
4251     }
4252   return ret.retn();
4253 }
4254
4255 /*!
4256  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
4257  * 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]
4258  */
4259 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4260 {
4261   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4262   ret->alloc(newNbOfElem,1);
4263   int nbOfOldNodes=getNumberOfTuples();
4264   const int *old2New=getConstPointer();
4265   int *pt=ret->getPointer();
4266   for(int i=nbOfOldNodes-1;i>=0;i--)
4267     {
4268       int newp(old2New[i]);
4269       if(newp!=-1)
4270         {
4271           if(newp>=0 && newp<newNbOfElem)
4272             pt[newp]=i;
4273           else
4274             {
4275               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4276               throw INTERP_KERNEL::Exception(oss.str().c_str());
4277             }
4278         }
4279     }
4280   return ret.retn();
4281 }
4282
4283 /*!
4284  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4285  * from values of \a this array, which is supposed to contain a renumbering map in 
4286  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4287  * To know how to use the renumbering maps see \ref numbering.
4288  *  \param [in] newNbOfElem - the number of tuples in the result array.
4289  *  \return DataArrayInt * - the new instance of DataArrayInt.
4290  *          The caller is to delete this result array using decrRef() as it is no more
4291  *          needed.
4292  * 
4293  *  \if ENABLE_EXAMPLES
4294  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4295  *
4296  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4297  *  \sa invertArrayN2O2O2NOptimized
4298  *  \endif
4299  */
4300 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4301 {
4302   checkAllocated();
4303   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4304   ret->alloc(oldNbOfElem,1);
4305   const int *new2Old=getConstPointer();
4306   int *pt=ret->getPointer();
4307   std::fill(pt,pt+oldNbOfElem,-1);
4308   int nbOfNewElems=getNumberOfTuples();
4309   for(int i=0;i<nbOfNewElems;i++)
4310     {
4311       int v(new2Old[i]);
4312       if(v>=0 && v<oldNbOfElem)
4313         pt[v]=i;
4314       else
4315         {
4316           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4317           throw INTERP_KERNEL::Exception(oss.str().c_str());
4318         }
4319     }
4320   return ret.retn();
4321 }
4322
4323 /*!
4324  * Creates a map, whose contents are computed
4325  * from values of \a this array, which is supposed to contain a renumbering map in 
4326  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4327  * To know how to use the renumbering maps see \ref numbering.
4328  *  \param [in] newNbOfElem - the number of tuples in the result array.
4329  *  \return MapII  - the new instance of Map.
4330  * 
4331  *  \if ENABLE_EXAMPLES
4332  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4333  *
4334  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4335  *  \sa invertArrayN2O2O2N
4336  *  \endif
4337  */
4338 MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
4339 {
4340   checkAllocated();
4341   MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4342   std::map<int,int>& m(ret->data());
4343   const int *new2Old(begin());
4344   int nbOfNewElems(this->getNumberOfTuples());
4345   for(int i=0;i<nbOfNewElems;i++)
4346     {
4347       int v(new2Old[i]);
4348       m[v]=i;
4349     }
4350   return ret;
4351 }
4352
4353 /*!
4354  * Computes for each tuple the sum of number of components values in the tuple and return it.
4355  * 
4356  * \return DataArrayInt * - the new instance of DataArrayInt containing the
4357  *          same number of tuples as \a this array and one component.
4358  *          The caller is to delete this result array using decrRef() as it is no more
4359  *          needed.
4360  *  \throw If \a this is not allocated.
4361  */
4362 DataArrayInt *DataArrayInt::sumPerTuple() const
4363 {
4364   checkAllocated();
4365   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4366   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4367   ret->alloc(nbOfTuple,1);
4368   const int *src(getConstPointer());
4369   int *dest(ret->getPointer());
4370   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4371     *dest=std::accumulate(src,src+nbOfComp,0);
4372   return ret.retn();
4373 }
4374
4375 /*!
4376  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4377  * If not an exception is thrown.
4378  *  \param [in] increasing - if \a true, the array values should be increasing.
4379  *  \throw If sequence of values is not strictly monotonic in agreement with \a
4380  *         increasing arg.
4381  *  \throw If \a this->getNumberOfComponents() != 1.
4382  *  \throw If \a this is not allocated.
4383  */
4384 void DataArrayInt::checkMonotonic(bool increasing) const
4385 {
4386   if(!isMonotonic(increasing))
4387     {
4388       if (increasing)
4389         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
4390       else
4391         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
4392     }
4393 }
4394
4395 /*!
4396  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4397  *  \param [in] increasing - if \a true, array values should be increasing.
4398  *  \return bool - \a true if values change in accordance with \a increasing arg.
4399  *  \throw If \a this->getNumberOfComponents() != 1.
4400  *  \throw If \a this is not allocated.
4401  */
4402 bool DataArrayInt::isMonotonic(bool increasing) const
4403 {
4404   checkAllocated();
4405   if(getNumberOfComponents()!=1)
4406     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
4407   int nbOfElements=getNumberOfTuples();
4408   const int *ptr=getConstPointer();
4409   if(nbOfElements==0)
4410     return true;
4411   int ref=ptr[0];
4412   if(increasing)
4413     {
4414       for(int i=1;i<nbOfElements;i++)
4415         {
4416           if(ptr[i]>=ref)
4417             ref=ptr[i];
4418           else
4419             return false;
4420         }
4421     }
4422   else
4423     {
4424       for(int i=1;i<nbOfElements;i++)
4425         {
4426           if(ptr[i]<=ref)
4427             ref=ptr[i];
4428           else
4429             return false;
4430         }
4431     }
4432   return true;
4433 }
4434
4435 /*!
4436  * This method check that array consistently INCREASING or DECREASING in value.
4437  */
4438 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
4439 {
4440   checkAllocated();
4441   if(getNumberOfComponents()!=1)
4442     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
4443   int nbOfElements=getNumberOfTuples();
4444   const int *ptr=getConstPointer();
4445   if(nbOfElements==0)
4446     return true;
4447   int ref=ptr[0];
4448   if(increasing)
4449     {
4450       for(int i=1;i<nbOfElements;i++)
4451         {
4452           if(ptr[i]>ref)
4453             ref=ptr[i];
4454           else
4455             return false;
4456         }
4457     }
4458   else
4459     {
4460       for(int i=1;i<nbOfElements;i++)
4461         {
4462           if(ptr[i]<ref)
4463             ref=ptr[i];
4464           else
4465             return false;
4466         }
4467     }
4468   return true;
4469 }
4470
4471 /*!
4472  * This method check that array consistently INCREASING or DECREASING in value.
4473  */
4474 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
4475 {
4476   if(!isStrictlyMonotonic(increasing))
4477     {
4478       if (increasing)
4479         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
4480       else
4481         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
4482     }
4483 }
4484
4485 /*!
4486  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
4487  * one-dimensional arrays that must be of the same length. The result array describes
4488  * correspondence between \a this and \a other arrays, so that 
4489  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
4490  * not possible because some element in \a other is not in \a this, an exception is thrown.
4491  *  \param [in] other - an array to compute permutation to.
4492  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
4493  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
4494  * no more needed.
4495  *  \throw If \a this->getNumberOfComponents() != 1.
4496  *  \throw If \a other->getNumberOfComponents() != 1.
4497  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
4498  *  \throw If \a other includes a value which is not in \a this array.
4499  * 
4500  *  \if ENABLE_EXAMPLES
4501  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
4502  *
4503  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
4504  *  \endif
4505  */
4506 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
4507 {
4508   checkAllocated();
4509   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
4510     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
4511   int nbTuple=getNumberOfTuples();
4512   other.checkAllocated();
4513   if(nbTuple!=other.getNumberOfTuples())
4514     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
4515   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4516   ret->alloc(nbTuple,1);
4517   ret->fillWithValue(-1);
4518   const int *pt=getConstPointer();
4519   std::map<int,int> mm;
4520   for(int i=0;i<nbTuple;i++)
4521     mm[pt[i]]=i;
4522   pt=other.getConstPointer();
4523   int *retToFill=ret->getPointer();
4524   for(int i=0;i<nbTuple;i++)
4525     {
4526       std::map<int,int>::const_iterator it=mm.find(pt[i]);
4527       if(it==mm.end())
4528         {
4529           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
4530           throw INTERP_KERNEL::Exception(oss.str().c_str());
4531         }
4532       retToFill[i]=(*it).second;
4533     }
4534   return ret.retn();
4535 }
4536
4537 /*!
4538  * Elements of \a partOfThis are expected to be included in \a this.
4539  * The returned array \a ret is so that this[ret]==partOfThis
4540  *
4541  * For example, if \a this array contents are [9,10,0,6,4,11,3,8] and if \a partOfThis contains [6,0,11,8]
4542  * the return array will contain [3,2,5,7].
4543  *
4544  * \a this is expected to be a 1 compo allocated array.
4545  * \param [in] partOfThis - A 1 compo allocated array
4546  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
4547  * \throw if two same element is present twice in \a this
4548  * \throw if an element in \a partOfThis is \b NOT in \a this.
4549  */
4550 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
4551 {
4552   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
4553     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
4554   checkAllocated(); partOfThis.checkAllocated();
4555   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
4556   const int *thisPt(begin()),*pt(partOfThis.begin());
4557   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4558   ret->alloc(nbTuples,1);
4559   int *retPt(ret->getPointer());
4560   std::map<int,int> m;
4561   for(int i=0;i<thisNbTuples;i++,thisPt++)
4562     m[*thisPt]=i;
4563   if((int)m.size()!=thisNbTuples)
4564     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
4565   for(int i=0;i<nbTuples;i++,retPt++,pt++)
4566     {
4567       std::map<int,int>::const_iterator it(m.find(*pt));
4568       if(it!=m.end())
4569         *retPt=(*it).second;
4570       else
4571         {
4572           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
4573           throw INTERP_KERNEL::Exception(oss.str());
4574         }
4575     }
4576   return ret.retn();
4577 }
4578
4579 /*!
4580  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4581  * This map, if applied to \a this array, would make it sorted. For example, if
4582  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4583  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4584  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4585  * This method is useful for renumbering (in MED file for example). For more info
4586  * on renumbering see \ref numbering.
4587  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4588  *          array using decrRef() as it is no more needed.
4589  *  \throw If \a this is not allocated.
4590  *  \throw If \a this->getNumberOfComponents() != 1.
4591  *  \throw If there are equal values in \a this array.
4592  */
4593 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4594 {
4595   checkAllocated();
4596   if(getNumberOfComponents()!=1)
4597     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4598   int nbTuples=getNumberOfTuples();
4599   const int *pt=getConstPointer();
4600   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4601   DataArrayInt *ret=DataArrayInt::New();
4602   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4603   return ret;
4604 }
4605
4606 /*!
4607  * 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
4608  * input array \a ids2.
4609  * \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.
4610  * 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
4611  * inversely.
4612  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4613  *
4614  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4615  *          array using decrRef() as it is no more needed.
4616  * \throw If either ids1 or ids2 is null not allocated or not with one components.
4617  * 
4618  */
4619 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4620 {
4621   if(!ids1 || !ids2)
4622     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4623   if(!ids1->isAllocated() || !ids2->isAllocated())
4624     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4625   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4626     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4627   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4628     {
4629       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 !";
4630       throw INTERP_KERNEL::Exception(oss.str().c_str());
4631     }
4632   MCAuto<DataArrayInt> p1(ids1->deepCopy());
4633   MCAuto<DataArrayInt> p2(ids2->deepCopy());
4634   p1->sort(true); p2->sort(true);
4635   if(!p1->isEqualWithoutConsideringStr(*p2))
4636     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4637   p1=ids1->checkAndPreparePermutation();
4638   p2=ids2->checkAndPreparePermutation();
4639   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4640   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4641   return p2.retn();
4642 }
4643
4644 /*!
4645  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4646  * onto a set of values of size \a targetNb (\a B). The surjective function is 
4647  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4648  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4649  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4650  * The first of out arrays returns indices of elements of \a this array, grouped by their
4651  * place in the set \a B. The second out array is the index of the first one; it shows how
4652  * many elements of \a A are mapped into each element of \a B. <br>
4653  * For more info on
4654  * mapping and its usage in renumbering see \ref numbering. <br>
4655  * \b Example:
4656  * - \a this: [0,3,2,3,2,2,1,2]
4657  * - \a targetNb: 4
4658  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
4659  * - \a arrI: [0,1,2,6,8]
4660  *
4661  * This result means: <br>
4662  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4663  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4664  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4665  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
4666  * \a arrI[ 2+1 ]]); <br> etc.
4667  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4668  *         than the maximal value of \a A.
4669  *  \param [out] arr - a new instance of DataArrayInt returning indices of
4670  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
4671  *         this array using decrRef() as it is no more needed.
4672  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4673  *         elements of \a this. The caller is to delete this array using decrRef() as it
4674  *         is no more needed.
4675  *  \throw If \a this is not allocated.
4676  *  \throw If \a this->getNumberOfComponents() != 1.
4677  *  \throw If any value in \a this is more or equal to \a targetNb.
4678  */
4679 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4680 {
4681   checkAllocated();
4682   if(getNumberOfComponents()!=1)
4683     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4684   int nbOfTuples=getNumberOfTuples();
4685   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4686   MCAuto<DataArrayInt> retI(DataArrayInt::New());
4687   retI->alloc(targetNb+1,1);
4688   const int *input=getConstPointer();
4689   std::vector< std::vector<int> > tmp(targetNb);
4690   for(int i=0;i<nbOfTuples;i++)
4691     {
4692       int tmp2=input[i];
4693       if(tmp2>=0 && tmp2<targetNb)
4694         tmp[tmp2].push_back(i);
4695       else
4696         {
4697           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4698           throw INTERP_KERNEL::Exception(oss.str().c_str());
4699         }
4700     }
4701   int *retIPtr=retI->getPointer();
4702   *retIPtr=0;
4703   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4704     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4705   if(nbOfTuples!=retI->getIJ(targetNb,0))
4706     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4707   ret->alloc(nbOfTuples,1);
4708   int *retPtr=ret->getPointer();
4709   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4710     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4711   arr=ret.retn();
4712   arrI=retI.retn();
4713 }
4714
4715
4716 /*!
4717  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4718  * from a zip representation of a surjective format (returned e.g. by
4719  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4720  * for example). The result array minimizes the permutation. <br>
4721  * For more info on renumbering see \ref numbering. <br>
4722  * \b Example: <br>
4723  * - \a nbOfOldTuples: 10 
4724  * - \a arr          : [0,3, 5,7,9]
4725  * - \a arrIBg       : [0,2,5]
4726  * - \a newNbOfTuples: 7
4727  * - result array    : [0,1,2,0,3,4,5,4,6,4]
4728  *
4729  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4730  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4731  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4732  *         (indices of) equal values. Its every element (except the last one) points to
4733  *         the first element of a group of equal values.
4734  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4735  *          arrIBg is \a arrIEnd[ -1 ].
4736  *  \param [out] newNbOfTuples - number of tuples after surjection application.
4737  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4738  *          array using decrRef() as it is no more needed.
4739  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4740  */
4741 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4742 {
4743   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4744   ret->alloc(nbOfOldTuples,1);
4745   int *pt=ret->getPointer();
4746   std::fill(pt,pt+nbOfOldTuples,-1);
4747   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4748   const int *cIPtr=arrIBg;
4749   for(int i=0;i<nbOfGrps;i++)
4750     pt[arr[cIPtr[i]]]=-(i+2);
4751   int newNb=0;
4752   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4753     {
4754       if(pt[iNode]<0)
4755         {
4756           if(pt[iNode]==-1)
4757             pt[iNode]=newNb++;
4758           else
4759             {
4760               int grpId=-(pt[iNode]+2);
4761               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4762                 {
4763                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4764                     pt[arr[j]]=newNb;
4765                   else
4766                     {
4767                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4768                       throw INTERP_KERNEL::Exception(oss.str().c_str());
4769                     }
4770                 }
4771               newNb++;
4772             }
4773         }
4774     }
4775   newNbOfTuples=newNb;
4776   return ret.retn();
4777 }
4778
4779 /*!
4780  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4781  * which if applied to \a this array would make it sorted ascendingly.
4782  * For more info on renumbering see \ref numbering. <br>
4783  * \b Example: <br>
4784  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4785  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4786  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
4787  *
4788  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4789  *          array using decrRef() as it is no more needed.
4790  *  \throw If \a this is not allocated.
4791  *  \throw If \a this->getNumberOfComponents() != 1.
4792  */
4793 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4794 {
4795   checkAllocated();
4796   if(getNumberOfComponents()!=1)
4797     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4798   int nbOfTuples=getNumberOfTuples();
4799   const int *pt=getConstPointer();
4800   std::map<int,int> m;
4801   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4802   ret->alloc(nbOfTuples,1);
4803   int *opt=ret->getPointer();
4804   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4805     {
4806       int val=*pt;
4807       std::map<int,int>::iterator it=m.find(val);
4808       if(it!=m.end())
4809         {
4810           *opt=(*it).second;
4811           (*it).second++;
4812         }
4813       else
4814         {
4815           *opt=0;
4816           m.insert(std::pair<int,int>(val,1));
4817         }
4818     }
4819   int sum=0;
4820   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4821     {
4822       int vt=(*it).second;
4823       (*it).second=sum;
4824       sum+=vt;
4825     }
4826   pt=getConstPointer();
4827   opt=ret->getPointer();
4828   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4829     *opt+=m[*pt];
4830   //
4831   return ret.retn();
4832 }
4833
4834 /*!
4835  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4836  * iota(). This method is particularly useful for DataArrayInt instances that represent
4837  * a renumbering array, to check if there is a real need in renumbering.
4838  * This method checks than \a this can be considered as an identity mapping
4839  * of a set having \a sizeExpected elements into itself.
4840  *
4841  *  \param [in] sizeExpected - The number of elements expected.
4842  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4843  *  \throw If \a this is not allocated.
4844  *  \throw If \a this->getNumberOfComponents() != 1.
4845  */
4846 bool DataArrayInt::isIota(int sizeExpected) const
4847 {
4848   checkAllocated();
4849   if(getNumberOfComponents()!=1)
4850     return false;
4851   int nbOfTuples(getNumberOfTuples());
4852   if(nbOfTuples!=sizeExpected)
4853     return false;
4854   const int *pt=getConstPointer();
4855   for(int i=0;i<nbOfTuples;i++,pt++)
4856     if(*pt!=i)
4857       return false;
4858   return true;
4859 }
4860
4861 /*!
4862  * Checks if all values in \a this array are equal to \a val.
4863  *  \param [in] val - value to check equality of array values to.
4864  *  \return bool - \a true if all values are \a val.
4865  *  \throw If \a this is not allocated.
4866  *  \throw If \a this->getNumberOfComponents() != 1
4867  *  \sa DataArrayInt::checkUniformAndGuess
4868  */
4869 bool DataArrayInt::isUniform(int val) const
4870 {
4871   checkAllocated();
4872   if(getNumberOfComponents()!=1)
4873     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4874   const int *w(begin()),*end2(end());
4875   for(;w!=end2;w++)
4876     if(*w!=val)
4877       return false;
4878   return true;
4879 }
4880
4881 /*!
4882  * This method checks that \a this is uniform. If not and exception will be thrown.
4883  * In case of uniformity the corresponding value is returned.
4884  *
4885  * \return int - the unique value contained in this
4886  * \throw If \a this is not allocated.
4887  * \throw If \a this->getNumberOfComponents() != 1
4888  * \throw If \a this is not uniform.
4889  * \sa DataArrayInt::isUniform
4890  */
4891 int DataArrayInt::checkUniformAndGuess() const
4892 {
4893   checkAllocated();
4894   if(getNumberOfComponents()!=1)
4895     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4896   if(empty())
4897     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4898   const int *w(begin()),*end2(end());
4899   int ret(*w);
4900   for(;w!=end2;w++)
4901     if(*w!=ret)
4902       throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4903   return ret;
4904 }
4905
4906 /*!
4907  * Checks if all values in \a this array are unique.
4908  *  \return bool - \a true if condition above is true
4909  *  \throw If \a this is not allocated.
4910  *  \throw If \a this->getNumberOfComponents() != 1
4911  */
4912 bool DataArrayInt::hasUniqueValues() const
4913 {
4914   checkAllocated();
4915   if(getNumberOfComponents()!=1)
4916     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4917   int nbOfTuples(getNumberOfTuples());
4918   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
4919   if ((int)s.size() != nbOfTuples)
4920     return false;
4921   return true;
4922 }
4923
4924 /*!
4925  * Copy all components in a specified order from another DataArrayInt.
4926  * The specified components become the first ones in \a this array.
4927  * Both numerical and textual data is copied. The number of tuples in \a this and
4928  * the other array can be different.
4929  *  \param [in] a - the array to copy data from.
4930  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
4931  *              to be copied.
4932  *  \throw If \a a is NULL.
4933  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4934  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4935  *
4936  *  \if ENABLE_EXAMPLES
4937  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4938  *  \endif
4939  */
4940 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4941 {
4942   if(!a)
4943     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4944   checkAllocated();
4945   a->checkAllocated();
4946   copyPartOfStringInfoFrom2(compoIds,*a);
4947   std::size_t partOfCompoSz=compoIds.size();
4948   int nbOfCompo=getNumberOfComponents();
4949   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4950   const int *ac=a->getConstPointer();
4951   int *nc=getPointer();
4952   for(int i=0;i<nbOfTuples;i++)
4953     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4954       nc[nbOfCompo*i+compoIds[j]]=*ac;
4955 }
4956
4957 DataArrayIntIterator *DataArrayInt::iterator()
4958 {
4959   return new DataArrayIntIterator(this);
4960 }
4961
4962 /*!
4963  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4964  * given one. The ids are sorted in the ascending order.
4965  *  \param [in] val - the value to find within \a this.
4966  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4967  *          array using decrRef() as it is no more needed.
4968  *  \throw If \a this is not allocated.
4969  *  \throw If \a this->getNumberOfComponents() != 1.
4970  *  \sa DataArrayInt::findIdsEqualTuple
4971  */
4972 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4973 {
4974   checkAllocated();
4975   if(getNumberOfComponents()!=1)
4976     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4977   const int *cptr(getConstPointer());
4978   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4979   int nbOfTuples=getNumberOfTuples();
4980   for(int i=0;i<nbOfTuples;i++,cptr++)
4981     if(*cptr==val)
4982       ret->pushBackSilent(i);
4983   return ret.retn();
4984 }
4985
4986 /*!
4987  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4988  * equal to a given one. 
4989  *  \param [in] val - the value to ignore within \a this.
4990  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4991  *          array using decrRef() as it is no more needed.
4992  *  \throw If \a this is not allocated.
4993  *  \throw If \a this->getNumberOfComponents() != 1.
4994  */
4995 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4996 {
4997   checkAllocated();
4998   if(getNumberOfComponents()!=1)
4999     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
5000   const int *cptr(getConstPointer());
5001   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5002   int nbOfTuples=getNumberOfTuples();
5003   for(int i=0;i<nbOfTuples;i++,cptr++)
5004     if(*cptr!=val)
5005       ret->pushBackSilent(i);
5006   return ret.retn();
5007 }
5008
5009 /*!
5010  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
5011  * This method is an extension of  DataArrayInt::findIdsEqual method.
5012  *
5013  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
5014  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
5015  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5016  *          array using decrRef() as it is no more needed.
5017  *  \throw If \a this is not allocated.
5018  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
5019  * \throw If \a this->getNumberOfComponents() is equal to 0.
5020  * \sa DataArrayInt::findIdsEqual
5021  */
5022 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
5023 {
5024   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
5025   checkAllocated();
5026   if(getNumberOfComponents()!=nbOfCompoExp)
5027     {
5028       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
5029       throw INTERP_KERNEL::Exception(oss.str().c_str());
5030     }
5031   if(nbOfCompoExp==0)
5032     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
5033   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5034   const int *bg(begin()),*end2(end()),*work(begin());
5035   while(work!=end2)
5036     {
5037       work=std::search(work,end2,tupleBg,tupleEnd);
5038       if(work!=end2)
5039         {
5040           std::size_t pos(std::distance(bg,work));
5041           if(pos%nbOfCompoExp==0)
5042             ret->pushBackSilent(pos/nbOfCompoExp);
5043           work++;
5044         }
5045     }
5046   return ret.retn();
5047 }
5048
5049 /*!
5050  * Assigns \a newValue to all elements holding \a oldValue within \a this
5051  * one-dimensional array.
5052  *  \param [in] oldValue - the value to replace.
5053  *  \param [in] newValue - the value to assign.
5054  *  \return int - number of replacements performed.
5055  *  \throw If \a this is not allocated.
5056  *  \throw If \a this->getNumberOfComponents() != 1.
5057  */
5058 int DataArrayInt::changeValue(int oldValue, int newValue)
5059 {
5060   checkAllocated();
5061   if(getNumberOfComponents()!=1)
5062     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5063   if(oldValue==newValue)
5064     return 0;
5065   int *start(getPointer()),*end2(start+getNbOfElems());
5066   int ret(0);
5067   for(int *val=start;val!=end2;val++)
5068     {
5069       if(*val==oldValue)
5070         {
5071           *val=newValue;
5072           ret++;
5073         }
5074     }
5075   if(ret>0)
5076     declareAsNew();
5077   return ret;
5078 }
5079
5080 /*!
5081  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
5082  * one of given values.
5083  *  \param [in] valsBg - an array of values to find within \a this array.
5084  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5085  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5086  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5087  *          array using decrRef() as it is no more needed.
5088  *  \throw If \a this->getNumberOfComponents() != 1.
5089  */
5090 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
5091 {
5092   if(getNumberOfComponents()!=1)
5093     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
5094   std::set<int> vals2(valsBg,valsEnd);
5095   const int *cptr(getConstPointer());
5096   std::vector<int> res;
5097   int nbOfTuples(getNumberOfTuples());
5098   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5099   for(int i=0;i<nbOfTuples;i++,cptr++)
5100     if(vals2.find(*cptr)!=vals2.end())
5101       ret->pushBackSilent(i);
5102   return ret.retn();
5103 }
5104
5105 /*!
5106  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5107  * equal to any of given values.
5108  *  \param [in] valsBg - an array of values to ignore within \a this array.
5109  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5110  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5111  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5112  *          array using decrRef() as it is no more needed.
5113  *  \throw If \a this->getNumberOfComponents() != 1.
5114  */
5115 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
5116 {
5117   if(getNumberOfComponents()!=1)
5118     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5119   std::set<int> vals2(valsBg,valsEnd);
5120   const int *cptr=getConstPointer();
5121   std::vector<int> res;
5122   int nbOfTuples=getNumberOfTuples();
5123   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5124   for(int i=0;i<nbOfTuples;i++,cptr++)
5125     if(vals2.find(*cptr)==vals2.end())
5126       ret->pushBackSilent(i);
5127   return ret.retn();
5128 }
5129
5130 /*!
5131  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5132  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5133  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5134  * If any the tuple id is returned. If not -1 is returned.
5135  * 
5136  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5137  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5138  *
5139  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5140  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5141  */
5142 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
5143 {
5144   checkAllocated();
5145   int nbOfCompo=getNumberOfComponents();
5146   if(nbOfCompo==0)
5147     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5148   if(nbOfCompo!=(int)tupl.size())
5149     {
5150       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5151       throw INTERP_KERNEL::Exception(oss.str().c_str());
5152     }
5153   const int *cptr=getConstPointer();
5154   std::size_t nbOfVals=getNbOfElems();
5155   for(const int *work=cptr;work!=cptr+nbOfVals;)
5156     {
5157       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5158       if(work!=cptr+nbOfVals)
5159         {
5160           if(std::distance(cptr,work)%nbOfCompo!=0)
5161             work++;
5162           else
5163             return std::distance(cptr,work)/nbOfCompo;
5164         }
5165     }
5166   return -1;
5167 }
5168
5169 /*!
5170  * This method searches the sequence specified in input parameter \b vals in \b this.
5171  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5172  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5173  * \sa DataArrayInt::findIdFirstEqualTuple
5174  */
5175 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
5176 {
5177   checkAllocated();
5178   int nbOfCompo=getNumberOfComponents();
5179   if(nbOfCompo!=1)
5180     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5181   const int *cptr=getConstPointer();
5182   std::size_t nbOfVals=getNbOfElems();
5183   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5184   if(loc!=cptr+nbOfVals)
5185     return std::distance(cptr,loc);
5186   return -1;
5187 }
5188
5189 /*!
5190  * This method expects to be called when number of components of this is equal to one.
5191  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5192  * If not any tuple contains \b value -1 is returned.
5193  * \sa DataArrayInt::presenceOfValue
5194  */
5195 int DataArrayInt::findIdFirstEqual(int value) const
5196 {
5197   checkAllocated();
5198   if(getNumberOfComponents()!=1)
5199     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5200   const int *cptr=getConstPointer();
5201   int nbOfTuples=getNumberOfTuples();
5202   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
5203   if(ret!=cptr+nbOfTuples)
5204     return std::distance(cptr,ret);
5205   return -1;
5206 }
5207
5208 /*!
5209  * This method expects to be called when number of components of this is equal to one.
5210  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5211  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5212  * \sa DataArrayInt::presenceOfValue
5213  */
5214 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
5215 {
5216   checkAllocated();
5217   if(getNumberOfComponents()!=1)
5218     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5219   std::set<int> vals2(vals.begin(),vals.end());
5220   const int *cptr=getConstPointer();
5221   int nbOfTuples=getNumberOfTuples();
5222   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
5223     if(vals2.find(*w)!=vals2.end())
5224       return std::distance(cptr,w);
5225   return -1;
5226 }
5227
5228 /*!
5229  * This method returns the number of values in \a this that are equals to input parameter \a value.
5230  * This method only works for single component array.
5231  *
5232  * \return a value in [ 0, \c this->getNumberOfTuples() )
5233  *
5234  * \throw If \a this is not allocated
5235  *
5236  */
5237 int DataArrayInt::count(int value) const
5238 {
5239   int ret=0;
5240   checkAllocated();
5241   if(getNumberOfComponents()!=1)
5242     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5243   const int *vals=begin();
5244   int nbOfTuples=getNumberOfTuples();
5245   for(int i=0;i<nbOfTuples;i++,vals++)
5246     if(*vals==value)
5247       ret++;
5248   return ret;
5249 }
5250
5251 /*!
5252  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5253  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5254  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5255  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5256  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5257  * \sa DataArrayInt::findIdFirstEqualTuple
5258  */
5259 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5260 {
5261   return findIdFirstEqualTuple(tupl)!=-1;
5262 }
5263
5264
5265 /*!
5266  * Returns \a true if a given value is present within \a this one-dimensional array.
5267  *  \param [in] value - the value to find within \a this array.
5268  *  \return bool - \a true in case if \a value is present within \a this array.
5269  *  \throw If \a this is not allocated.
5270  *  \throw If \a this->getNumberOfComponents() != 1.
5271  *  \sa findIdFirstEqual()
5272  */
5273 bool DataArrayInt::presenceOfValue(int value) const
5274 {
5275   return findIdFirstEqual(value)!=-1;
5276 }
5277
5278 /*!
5279  * This method expects to be called when number of components of this is equal to one.
5280  * This method returns true if it exists a tuple so that the value is contained in \b vals.
5281  * If not any tuple contains one of the values contained in 'vals' false is returned.
5282  * \sa DataArrayInt::findIdFirstEqual
5283  */
5284 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5285 {
5286   return findIdFirstEqual(vals)!=-1;
5287 }
5288
5289 /*!
5290  * Accumulates values of each component of \a this array.
5291  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
5292  *         by the caller, that is filled by this method with sum value for each
5293  *         component.
5294  *  \throw If \a this is not allocated.
5295  */
5296 void DataArrayInt::accumulate(int *res) const
5297 {
5298   checkAllocated();
5299   const int *ptr=getConstPointer();
5300   int nbTuple=getNumberOfTuples();
5301   int nbComps=getNumberOfComponents();
5302   std::fill(res,res+nbComps,0);
5303   for(int i=0;i<nbTuple;i++)
5304     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5305 }
5306
5307 int DataArrayInt::accumulate(int compId) const
5308 {
5309   checkAllocated();
5310   const int *ptr=getConstPointer();
5311   int nbTuple=getNumberOfTuples();
5312   int nbComps=getNumberOfComponents();
5313   if(compId<0 || compId>=nbComps)
5314     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5315   int ret=0;
5316   for(int i=0;i<nbTuple;i++)
5317     ret+=ptr[i*nbComps+compId];
5318   return ret;
5319 }
5320
5321 /*!
5322  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5323  * The returned array will have same number of components than \a this and number of tuples equal to
5324  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5325  *
5326  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5327  *
5328  * \param [in] bgOfIndex - begin (included) of the input index array.
5329  * \param [in] endOfIndex - end (excluded) of the input index array.
5330  * \return DataArrayInt * - the new instance having the same number of components than \a this.
5331  * 
5332  * \throw If bgOfIndex or end is NULL.
5333  * \throw If input index array is not ascendingly sorted.
5334  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5335  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5336  */
5337 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5338 {
5339   if(!bgOfIndex || !endOfIndex)
5340     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5341   checkAllocated();
5342   int nbCompo=getNumberOfComponents();
5343   int nbOfTuples=getNumberOfTuples();
5344   int sz=(int)std::distance(bgOfIndex,endOfIndex);
5345   if(sz<1)
5346     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5347   sz--;
5348   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5349   const int *w=bgOfIndex;
5350   if(*w<0 || *w>=nbOfTuples)
5351     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5352   const int *srcPt=begin()+(*w)*nbCompo;
5353   int *tmp=ret->getPointer();
5354   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5355     {
5356       std::fill(tmp,tmp+nbCompo,0);
5357       if(w[1]>=w[0])
5358         {
5359           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5360             {
5361               if(j>=0 && j<nbOfTuples)
5362                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5363               else
5364                 {
5365                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5366                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5367                 }
5368             }
5369         }
5370       else
5371         {
5372           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5373           throw INTERP_KERNEL::Exception(oss.str().c_str());
5374         }
5375     }
5376   ret->copyStringInfoFrom(*this);
5377   return ret.retn();
5378 }
5379
5380 /*!
5381  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5382  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5383  * offsetA2</em> and (2)
5384  * the number of component in the result array is same as that of each of given arrays.
5385  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5386  * Info on components is copied from the first of the given arrays. Number of components
5387  * in the given arrays must be the same.
5388  *  \param [in] a1 - an array to include in the result array.
5389  *  \param [in] a2 - another array to include in the result array.
5390  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
5391  *  \return DataArrayInt * - the new instance of DataArrayInt.
5392  *          The caller is to delete this result array using decrRef() as it is no more
5393  *          needed.
5394  *  \throw If either \a a1 or \a a2 is NULL.
5395  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5396  */
5397 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5398 {
5399   if(!a1 || !a2)
5400     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5401   std::size_t nbOfComp(a1->getNumberOfComponents());
5402   if(nbOfComp!=a2->getNumberOfComponents())
5403     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5404   int nbOfTuple1=a1->getNumberOfTuples();
5405   int nbOfTuple2=a2->getNumberOfTuples();
5406   DataArrayInt *ret=DataArrayInt::New();
5407   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5408   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
5409   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5410   ret->copyStringInfoFrom(*a1);
5411   return ret;
5412 }
5413
5414 /*!
5415  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5416  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5417  * the number of component in the result array is same as that of each of given arrays.
5418  * Info on components is copied from the first of the given arrays. Number of components
5419  * in the given arrays must be  the same.
5420  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5421  * not the object itself.
5422  *  \param [in] arr - a sequence of arrays to include in the result array.
5423  *  \return DataArrayInt * - the new instance of DataArrayInt.
5424  *          The caller is to delete this result array using decrRef() as it is no more
5425  *          needed.
5426  *  \throw If all arrays within \a arr are NULL.
5427  *  \throw If getNumberOfComponents() of arrays within \a arr.
5428  */
5429 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5430 {
5431   std::vector<const DataArrayInt *> a;
5432   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5433     if(*it4)
5434       a.push_back(*it4);
5435   if(a.empty())
5436     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5437   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5438   std::size_t nbOfComp((*it)->getNumberOfComponents());
5439   int nbt=(*it++)->getNumberOfTuples();
5440   for(int i=1;it!=a.end();it++,i++)
5441     {
5442       if((*it)->getNumberOfComponents()!=nbOfComp)
5443         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5444       nbt+=(*it)->getNumberOfTuples();
5445     }
5446   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5447   ret->alloc(nbt,nbOfComp);
5448   int *pt=ret->getPointer();
5449   for(it=a.begin();it!=a.end();it++)
5450     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5451   ret->copyStringInfoFrom(*(a[0]));
5452   return ret.retn();
5453 }
5454
5455 /*!
5456  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5457  * A packed index array is an allocated array with one component, and at least one tuple. The first element
5458  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5459  * 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.
5460  * 
5461  * \return DataArrayInt * - a new object to be managed by the caller.
5462  */
5463 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5464 {
5465   int retSz=1;
5466   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5467     {
5468       if(*it4)
5469         {
5470           (*it4)->checkAllocated();
5471           if((*it4)->getNumberOfComponents()!=1)
5472             {
5473               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5474               throw INTERP_KERNEL::Exception(oss.str().c_str());
5475             }
5476           int nbTupl=(*it4)->getNumberOfTuples();
5477           if(nbTupl<1)
5478             {
5479               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5480               throw INTERP_KERNEL::Exception(oss.str().c_str());
5481             }
5482           if((*it4)->front()!=0)
5483             {
5484               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5485               throw INTERP_KERNEL::Exception(oss.str().c_str());
5486             }
5487           retSz+=nbTupl-1;
5488         }
5489       else
5490         {
5491           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5492           throw INTERP_KERNEL::Exception(oss.str().c_str());
5493         }
5494     }
5495   if(arrs.empty())
5496     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5497   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5498   ret->alloc(retSz,1);
5499   int *pt=ret->getPointer(); *pt++=0;
5500   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5501     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5502   ret->copyStringInfoFrom(*(arrs[0]));
5503   return ret.retn();
5504 }
5505
5506 /*!
5507  * Returns in a single walk in \a this the min value and the max value in \a this.
5508  * \a this is expected to be single component array.
5509  *
5510  * \param [out] minValue - the min value in \a this.
5511  * \param [out] maxValue - the max value in \a this.
5512  *
5513  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5514  */
5515 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5516 {
5517   checkAllocated();
5518   if(getNumberOfComponents()!=1)
5519     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5520   int nbTuples(getNumberOfTuples());
5521   const int *pt(begin());
5522   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5523   for(int i=0;i<nbTuples;i++,pt++)
5524     {
5525       if(*pt<minValue)
5526         minValue=*pt;
5527       if(*pt>maxValue)
5528         maxValue=*pt;
5529     }
5530 }
5531
5532 /*!
5533  * Modify all elements of \a this array, so that
5534  * an element _x_ becomes \f$ numerator / x \f$.
5535  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5536  *           array, all elements processed before detection of the zero element remain
5537  *           modified.
5538  *  \param [in] numerator - the numerator used to modify array elements.
5539  *  \throw If \a this is not allocated.
5540  *  \throw If there is an element equal to 0 in \a this array.
5541  */
5542 void DataArrayInt::applyInv(int numerator)
5543 {
5544   checkAllocated();
5545   int *ptr=getPointer();
5546   std::size_t nbOfElems=getNbOfElems();
5547   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5548     {
5549       if(*ptr!=0)
5550         {
5551           *ptr=numerator/(*ptr);
5552         }
5553       else
5554         {
5555           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5556           oss << " !";
5557           throw INTERP_KERNEL::Exception(oss.str().c_str());
5558         }
5559     }
5560   declareAsNew();
5561 }
5562
5563 /*!
5564  * Modify all elements of \a this array, so that
5565  * an element _x_ becomes \f$ x / val \f$.
5566  *  \param [in] val - the denominator used to modify array elements.
5567  *  \throw If \a this is not allocated.
5568  *  \throw If \a val == 0.
5569  */
5570 void DataArrayInt::applyDivideBy(int val)
5571 {
5572   if(val==0)
5573     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5574   checkAllocated();
5575   int *ptr=getPointer();
5576   std::size_t nbOfElems=getNbOfElems();
5577   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5578   declareAsNew();
5579 }
5580
5581 /*!
5582  * Modify all elements of \a this array, so that
5583  * an element _x_ becomes  <em> x % val </em>.
5584  *  \param [in] val - the divisor used to modify array elements.
5585  *  \throw If \a this is not allocated.
5586  *  \throw If \a val <= 0.
5587  */
5588 void DataArrayInt::applyModulus(int val)
5589 {
5590   if(val<=0)
5591     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5592   checkAllocated();
5593   int *ptr=getPointer();
5594   std::size_t nbOfElems=getNbOfElems();
5595   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5596   declareAsNew();
5597 }
5598
5599 /*!
5600  * This method works only on data array with one component.
5601  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5602  * this[*id] in [\b vmin,\b vmax)
5603  * 
5604  * \param [in] vmin begin of range. This value is included in range (included).
5605  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5606  * \return a newly allocated data array that the caller should deal with.
5607  *
5608  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5609  */
5610 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5611 {
5612   InRange<int> ir(vmin,vmax);
5613   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5614   return ret.retn();
5615 }
5616
5617 /*!
5618  * This method works only on data array with one component.
5619  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5620  * this[*id] \b not in [\b vmin,\b vmax)
5621  * 
5622  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5623  * \param [in] vmax end of range. This value is included in range (included).
5624  * \return a newly allocated data array that the caller should deal with.
5625  * 
5626  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5627  */
5628 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5629 {
5630   NotInRange<int> nir(vmin,vmax);
5631   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5632   return ret.retn();
5633 }
5634
5635 /*!
5636  * This method works only on data array with one component.
5637  * 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.
5638  * 
5639  * \param [in] vmin begin of range. This value is included in range (included).
5640  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5641  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5642 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5643 {
5644   checkAllocated();
5645   if(getNumberOfComponents()!=1)
5646     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5647   int nbOfTuples=getNumberOfTuples();
5648   bool ret=true;
5649   const int *cptr=getConstPointer();
5650   for(int i=0;i<nbOfTuples;i++,cptr++)
5651     {
5652       if(*cptr>=vmin && *cptr<vmax)
5653         { ret=ret && *cptr==i; }
5654       else
5655         {
5656           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5657           throw INTERP_KERNEL::Exception(oss.str().c_str());
5658         }
5659     }
5660   return ret;
5661 }
5662
5663 /*!
5664  * Modify all elements of \a this array, so that
5665  * an element _x_ becomes <em> val % x </em>.
5666  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
5667  *           array, all elements processed before detection of the zero element remain
5668  *           modified.
5669  *  \param [in] val - the divident used to modify array elements.
5670  *  \throw If \a this is not allocated.
5671  *  \throw If there is an element equal to or less than 0 in \a this array.
5672  */
5673 void DataArrayInt::applyRModulus(int val)
5674 {
5675   checkAllocated();
5676   int *ptr=getPointer();
5677   std::size_t nbOfElems=getNbOfElems();
5678   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5679     {
5680       if(*ptr>0)
5681         {
5682           *ptr=val%(*ptr);
5683         }
5684       else
5685         {
5686           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5687           oss << " !";
5688           throw INTERP_KERNEL::Exception(oss.str().c_str());
5689         }
5690     }
5691   declareAsNew();
5692 }
5693
5694 /*!
5695  * Modify all elements of \a this array, so that
5696  * an element _x_ becomes <em> val ^ x </em>.
5697  *  \param [in] val - the value used to apply pow on all array elements.
5698  *  \throw If \a this is not allocated.
5699  *  \throw If \a val < 0.
5700  */
5701 void DataArrayInt::applyPow(int val)
5702 {
5703   checkAllocated();
5704   if(val<0)
5705     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5706   int *ptr=getPointer();
5707   std::size_t nbOfElems=getNbOfElems();
5708   if(val==0)
5709     {
5710       std::fill(ptr,ptr+nbOfElems,1);
5711       return ;
5712     }
5713   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5714     {
5715       int tmp=1;
5716       for(int j=0;j<val;j++)
5717         tmp*=*ptr;
5718       *ptr=tmp;
5719     }
5720   declareAsNew();
5721 }
5722
5723 /*!
5724  * Modify all elements of \a this array, so that
5725  * an element _x_ becomes \f$ val ^ x \f$.
5726  *  \param [in] val - the value used to apply pow on all array elements.
5727  *  \throw If \a this is not allocated.
5728  *  \throw If there is an element < 0 in \a this array.
5729  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5730  *           array, all elements processed before detection of the zero element remain
5731  *           modified.
5732  */
5733 void DataArrayInt::applyRPow(int val)
5734 {
5735   checkAllocated();
5736   int *ptr=getPointer();
5737   std::size_t nbOfElems=getNbOfElems();
5738   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5739     {
5740       if(*ptr>=0)
5741         {
5742           int tmp=1;
5743           for(int j=0;j<*ptr;j++)
5744             tmp*=val;
5745           *ptr=tmp;
5746         }
5747       else
5748         {
5749           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5750           oss << " !";
5751           throw INTERP_KERNEL::Exception(oss.str().c_str());
5752         }
5753     }
5754   declareAsNew();
5755 }
5756
5757 /*!
5758  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5759  * The i-th item of the result array is an ID of a set of elements belonging to a
5760  * unique set of groups, which the i-th element is a part of. This set of elements
5761  * belonging to a unique set of groups is called \a family, so the result array contains
5762  * IDs of families each element belongs to.
5763  *
5764  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5765  * then there are 3 families:
5766  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5767  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5768  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5769  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5770  * stands for the element #3 which is in none of groups.
5771  *
5772  *  \param [in] groups - sequence of groups of element IDs.
5773  *  \param [in] newNb - total number of elements; it must be more than max ID of element
5774  *         in \a groups.
5775  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5776  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5777  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
5778  *         delete this array using decrRef() as it is no more needed.
5779  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5780  */
5781 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5782 {
5783   std::vector<const DataArrayInt *> groups2;
5784   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5785     if(*it4)
5786       groups2.push_back(*it4);
5787   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5788   ret->alloc(newNb,1);
5789   int *retPtr=ret->getPointer();
5790   std::fill(retPtr,retPtr+newNb,0);
5791   int fid=1;
5792   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5793     {
5794       const int *ptr=(*iter)->getConstPointer();
5795       std::size_t nbOfElem=(*iter)->getNbOfElems();
5796       int sfid=fid;
5797       for(int j=0;j<sfid;j++)
5798         {
5799           bool found=false;
5800           for(std::size_t i=0;i<nbOfElem;i++)
5801             {
5802               if(ptr[i]>=0 && ptr[i]<newNb)
5803                 {
5804                   if(retPtr[ptr[i]]==j)
5805                     {
5806                       retPtr[ptr[i]]=fid;
5807                       found=true;
5808                     }
5809                 }
5810               else
5811                 {
5812                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5813                   oss << ") !";
5814                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5815                 }
5816             }
5817           if(found)
5818             fid++;
5819         }
5820     }
5821   fidsOfGroups.clear();
5822   fidsOfGroups.resize(groups2.size());
5823   int grId=0;
5824   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5825     {
5826       std::set<int> tmp;
5827       const int *ptr=(*iter)->getConstPointer();
5828       std::size_t nbOfElem=(*iter)->getNbOfElems();
5829       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5830         tmp.insert(retPtr[*p]);
5831       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5832     }
5833   return ret.retn();
5834 }
5835
5836 /*!
5837  * Returns a new DataArrayInt which contains all elements of given one-dimensional
5838  * arrays. The result array does not contain any duplicates and its values
5839  * are sorted in ascending order.
5840  *  \param [in] arr - sequence of DataArrayInt's to unite.
5841  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5842  *         array using decrRef() as it is no more needed.
5843  *  \throw If any \a arr[i] is not allocated.
5844  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5845  */
5846 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5847 {
5848   std::vector<const DataArrayInt *> a;
5849   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5850     if(*it4)
5851       a.push_back(*it4);
5852   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5853     {
5854       (*it)->checkAllocated();
5855       if((*it)->getNumberOfComponents()!=1)
5856         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5857     }
5858   //
5859   std::set<int> r;
5860   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5861     {
5862       const int *pt=(*it)->getConstPointer();
5863       int nbOfTuples=(*it)->getNumberOfTuples();
5864       r.insert(pt,pt+nbOfTuples);
5865     }
5866   DataArrayInt *ret=DataArrayInt::New();
5867   ret->alloc((int)r.size(),1);
5868   std::copy(r.begin(),r.end(),ret->getPointer());
5869   return ret;
5870 }
5871
5872 /*!
5873  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5874  * arrays. The result array does not contain any duplicates and its values
5875  * are sorted in ascending order.
5876  *  \param [in] arr - sequence of DataArrayInt's to intersect.
5877  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5878  *         array using decrRef() as it is no more needed.
5879  *  \throw If any \a arr[i] is not allocated.
5880  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5881  */
5882 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5883 {
5884   std::vector<const DataArrayInt *> a;
5885   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5886     if(*it4)
5887       a.push_back(*it4);
5888   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5889     {
5890       (*it)->checkAllocated();
5891       if((*it)->getNumberOfComponents()!=1)
5892         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5893     }
5894   //
5895   std::set<int> r;
5896   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5897     {
5898       const int *pt=(*it)->getConstPointer();
5899       int nbOfTuples=(*it)->getNumberOfTuples();
5900       std::set<int> s1(pt,pt+nbOfTuples);
5901       if(it!=a.begin())
5902         {
5903           std::set<int> r2;
5904           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5905           r=r2;
5906         }
5907       else
5908         r=s1;
5909     }
5910   DataArrayInt *ret(DataArrayInt::New());
5911   ret->alloc((int)r.size(),1);
5912   std::copy(r.begin(),r.end(),ret->getPointer());
5913   return ret;
5914 }
5915
5916 /// @cond INTERNAL
5917 namespace MEDCouplingImpl
5918 {
5919   class OpSwitchedOn
5920   {
5921   public:
5922     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5923     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5924   private:
5925     int *_pt;
5926     int _cnt;
5927   };
5928
5929   class OpSwitchedOff
5930   {
5931   public:
5932     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5933     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5934   private:
5935     int *_pt;
5936     int _cnt;
5937   };
5938 }
5939 /// @endcond
5940
5941 /*!
5942  * This method returns the list of ids in ascending mode so that v[id]==true.
5943  */
5944 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5945 {
5946   int sz((int)std::count(v.begin(),v.end(),true));
5947   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5948   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5949   return ret.retn();
5950 }
5951
5952 /*!
5953  * This method returns the list of ids in ascending mode so that v[id]==false.
5954  */
5955 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5956 {
5957   int sz((int)std::count(v.begin(),v.end(),false));
5958   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5959   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5960   return ret.retn();
5961 }
5962
5963 /*!
5964  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
5965  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5966  *
5967  * \param [in] v the input data structure to be translate into skyline format.
5968  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5969  * \param [out] dataIndex the second element of the skyline format.
5970  */
5971 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5972 {
5973   int sz((int)v.size());
5974   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5975   ret1->alloc(sz+1,1);
5976   int *pt(ret1->getPointer()); *pt=0;
5977   for(int i=0;i<sz;i++,pt++)
5978     pt[1]=pt[0]+(int)v[i].size();
5979   ret0->alloc(ret1->back(),1);
5980   pt=ret0->getPointer();
5981   for(int i=0;i<sz;i++)
5982     pt=std::copy(v[i].begin(),v[i].end(),pt);
5983   data=ret0.retn(); dataIndex=ret1.retn();
5984 }
5985
5986 /*!
5987  * Returns a new DataArrayInt which contains a complement of elements of \a this
5988  * one-dimensional array. I.e. the result array contains all elements from the range [0,
5989  * \a nbOfElement) not present in \a this array.
5990  *  \param [in] nbOfElement - maximal size of the result array.
5991  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5992  *         array using decrRef() as it is no more needed.
5993  *  \throw If \a this is not allocated.
5994  *  \throw If \a this->getNumberOfComponents() != 1.
5995  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5996  *         nbOfElement ).
5997  */
5998 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5999 {
6000   checkAllocated();
6001   if(getNumberOfComponents()!=1)
6002     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
6003   std::vector<bool> tmp(nbOfElement);
6004   const int *pt=getConstPointer();
6005   int nbOfTuples=getNumberOfTuples();
6006   for(const int *w=pt;w!=pt+nbOfTuples;w++)
6007     if(*w>=0 && *w<nbOfElement)
6008       tmp[*w]=true;
6009     else
6010       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
6011   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
6012   DataArrayInt *ret=DataArrayInt::New();
6013   ret->alloc(nbOfRetVal,1);
6014   int j=0;
6015   int *retPtr=ret->getPointer();
6016   for(int i=0;i<nbOfElement;i++)
6017     if(!tmp[i])
6018       retPtr[j++]=i;
6019   return ret;
6020 }
6021
6022 /*!
6023  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
6024  * from an \a other one-dimensional array.
6025  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
6026  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
6027  *         caller is to delete this array using decrRef() as it is no more needed.
6028  *  \throw If \a other is NULL.
6029  *  \throw If \a other is not allocated.
6030  *  \throw If \a other->getNumberOfComponents() != 1.
6031  *  \throw If \a this is not allocated.
6032  *  \throw If \a this->getNumberOfComponents() != 1.
6033  *  \sa DataArrayInt::buildSubstractionOptimized()
6034  */
6035 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
6036 {
6037   if(!other)
6038     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
6039   checkAllocated();
6040   other->checkAllocated();
6041   if(getNumberOfComponents()!=1)
6042     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
6043   if(other->getNumberOfComponents()!=1)
6044     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
6045   const int *pt=getConstPointer();
6046   int nbOfTuples=getNumberOfTuples();
6047   std::set<int> s1(pt,pt+nbOfTuples);
6048   pt=other->getConstPointer();
6049   nbOfTuples=other->getNumberOfTuples();
6050   std::set<int> s2(pt,pt+nbOfTuples);
6051   std::vector<int> r;
6052   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
6053   DataArrayInt *ret=DataArrayInt::New();
6054   ret->alloc((int)r.size(),1);
6055   std::copy(r.begin(),r.end(),ret->getPointer());
6056   return ret;
6057 }
6058
6059 /*!
6060  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
6061  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
6062  * 
6063  * \param [in] other an array with one component and expected to be sorted ascendingly.
6064  * \ret list of ids in \a this but not in \a other.
6065  * \sa DataArrayInt::buildSubstraction
6066  */
6067 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
6068 {
6069   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
6070   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
6071   checkAllocated(); other->checkAllocated();
6072   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6073   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6074   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
6075   const int *work1(pt1Bg),*work2(pt2Bg);
6076   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6077   for(;work1!=pt1End;work1++)
6078     {
6079       if(work2!=pt2End && *work1==*work2)
6080         work2++;
6081       else
6082         ret->pushBackSilent(*work1);
6083     }
6084   return ret.retn();
6085 }
6086
6087
6088 /*!
6089  * Returns a new DataArrayInt which contains all elements of \a this and a given
6090  * one-dimensional arrays. The result array does not contain any duplicates
6091  * and its values are sorted in ascending order.
6092  *  \param [in] other - an array to unite with \a this one.
6093  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6094  *         array using decrRef() as it is no more needed.
6095  *  \throw If \a this or \a other is not allocated.
6096  *  \throw If \a this->getNumberOfComponents() != 1.
6097  *  \throw If \a other->getNumberOfComponents() != 1.
6098  */
6099 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
6100 {
6101   std::vector<const DataArrayInt *>arrs(2);
6102   arrs[0]=this; arrs[1]=other;
6103   return BuildUnion(arrs);
6104 }
6105
6106
6107 /*!
6108  * Returns a new DataArrayInt which contains elements present in both \a this and a given
6109  * one-dimensional arrays. The result array does not contain any duplicates
6110  * and its values are sorted in ascending order.
6111  *  \param [in] other - an array to intersect with \a this one.
6112  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6113  *         array using decrRef() as it is no more needed.
6114  *  \throw If \a this or \a other is not allocated.
6115  *  \throw If \a this->getNumberOfComponents() != 1.
6116  *  \throw If \a other->getNumberOfComponents() != 1.
6117  */
6118 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
6119 {
6120   std::vector<const DataArrayInt *>arrs(2);
6121   arrs[0]=this; arrs[1]=other;
6122   return BuildIntersection(arrs);
6123 }
6124
6125 /*!
6126  * This method can be applied on allocated with one component DataArrayInt instance.
6127  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
6128  * 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]
6129  * 
6130  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
6131  * \throw if \a this is not allocated or if \a this has not exactly one component.
6132  * \sa DataArrayInt::buildUniqueNotSorted
6133  */
6134 DataArrayInt *DataArrayInt::buildUnique() const
6135 {
6136   checkAllocated();
6137   if(getNumberOfComponents()!=1)
6138     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
6139   int nbOfTuples=getNumberOfTuples();
6140   MCAuto<DataArrayInt> tmp=deepCopy();
6141   int *data=tmp->getPointer();
6142   int *last=std::unique(data,data+nbOfTuples);
6143   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6144   ret->alloc(std::distance(data,last),1);
6145   std::copy(data,last,ret->getPointer());
6146   return ret.retn();
6147 }
6148
6149 /*!
6150  * This method can be applied on allocated with one component DataArrayInt instance.
6151  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
6152  *
6153  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
6154  *
6155  * \throw if \a this is not allocated or if \a this has not exactly one component.
6156  *
6157  * \sa DataArrayInt::buildUnique
6158  */
6159 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
6160 {
6161   checkAllocated();
6162     if(getNumberOfComponents()!=1)
6163       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
6164   int minVal,maxVal;
6165   getMinMaxValues(minVal,maxVal);
6166   std::vector<bool> b(maxVal-minVal+1,false);
6167   const int *ptBg(begin()),*endBg(end());
6168   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6169   for(const int *pt=ptBg;pt!=endBg;pt++)
6170     {
6171       if(!b[*pt-minVal])
6172         {
6173           ret->pushBackSilent(*pt);
6174           b[*pt-minVal]=true;
6175         }
6176     }
6177   ret->copyStringInfoFrom(*this);
6178   return ret.retn();
6179 }
6180
6181 /*!
6182  * Returns a new DataArrayInt which contains size of every of groups described by \a this
6183  * "index" array. Such "index" array is returned for example by 
6184  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
6185  * "MEDCouplingUMesh::buildDescendingConnectivity" and
6186  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
6187  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
6188  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
6189  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
6190  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
6191  *          The caller is to delete this array using decrRef() as it is no more needed. 
6192  *  \throw If \a this is not allocated.
6193  *  \throw If \a this->getNumberOfComponents() != 1.
6194  *  \throw If \a this->getNumberOfTuples() < 2.
6195  *
6196  *  \b Example: <br> 
6197  *         - this contains [1,3,6,7,7,9,15]
6198  *         - result array contains [2,3,1,0,2,6],
6199  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
6200  *
6201  * \sa DataArrayInt::computeOffsetsFull
6202  */
6203 DataArrayInt *DataArrayInt::deltaShiftIndex() const
6204 {
6205   checkAllocated();
6206   if(getNumberOfComponents()!=1)
6207     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
6208   int nbOfTuples=getNumberOfTuples();
6209   if(nbOfTuples<2)
6210     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
6211   const int *ptr=getConstPointer();
6212   DataArrayInt *ret=DataArrayInt::New();
6213   ret->alloc(nbOfTuples-1,1);
6214   int *out=ret->getPointer();
6215   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
6216   return ret;
6217 }
6218
6219 /*!
6220  * Modifies \a this one-dimensional array so that value of each element \a x
6221  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6222  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
6223  * and components remains the same.<br>
6224  * This method is useful for allToAllV in MPI with contiguous policy. This method
6225  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
6226  * this one.
6227  *  \throw If \a this is not allocated.
6228  *  \throw If \a this->getNumberOfComponents() != 1.
6229  *
6230  *  \b Example: <br>
6231  *          - Before \a this contains [3,5,1,2,0,8]
6232  *          - After \a this contains  [0,3,8,9,11,11]<br>
6233  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
6234  *          array is retained and thus there is no space to store the last element.
6235  */
6236 void DataArrayInt::computeOffsets()
6237 {
6238   checkAllocated();
6239   if(getNumberOfComponents()!=1)
6240     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
6241   int nbOfTuples=getNumberOfTuples();
6242   if(nbOfTuples==0)
6243     return ;
6244   int *work=getPointer();
6245   int tmp=work[0];
6246   work[0]=0;
6247   for(int i=1;i<nbOfTuples;i++)
6248     {
6249       int tmp2=work[i];
6250       work[i]=work[i-1]+tmp;
6251       tmp=tmp2;
6252     }
6253   declareAsNew();
6254 }
6255
6256
6257 /*!
6258  * Modifies \a this one-dimensional array so that value of each element \a x
6259  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6260  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6261  * components remains the same and number of tuples is inceamented by one.<br>
6262  * This method is useful for allToAllV in MPI with contiguous policy. This method
6263  * differs from computeOffsets() in that the number of tuples is changed by this one.
6264  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
6265  *  \throw If \a this is not allocated.
6266  *  \throw If \a this->getNumberOfComponents() != 1.
6267  *
6268  *  \b Example: <br>
6269  *          - Before \a this contains [3,5,1,2,0,8]
6270  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
6271  * \sa DataArrayInt::deltaShiftIndex
6272  */
6273 void DataArrayInt::computeOffsetsFull()
6274 {
6275   checkAllocated();
6276   if(getNumberOfComponents()!=1)
6277     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6278   int nbOfTuples=getNumberOfTuples();
6279   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6280   const int *work=getConstPointer();
6281   ret[0]=0;
6282   for(int i=0;i<nbOfTuples;i++)
6283     ret[i+1]=work[i]+ret[i];
6284   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6285   declareAsNew();
6286 }
6287
6288 /*!
6289  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6290  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6291  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6292  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6293  * filling completely one of the ranges in \a this.
6294  *
6295  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6296  * \param [out] rangeIdsFetched the range ids fetched
6297  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6298  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
6299  *
6300  * \sa DataArrayInt::computeOffsetsFull
6301  *
6302  *  \b Example: <br>
6303  *          - \a this : [0,3,7,9,15,18]
6304  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
6305  *          - \a rangeIdsFetched result array: [0,2,4]
6306  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6307  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6308  * <br>
6309  */
6310 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6311 {
6312   if(!listOfIds)
6313     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6314   listOfIds->checkAllocated(); checkAllocated();
6315   if(listOfIds->getNumberOfComponents()!=1)
6316     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6317   if(getNumberOfComponents()!=1)
6318     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6319   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6320   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6321   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6322   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6323   while(tupPtr!=tupEnd && offPtr!=offEnd)
6324     {
6325       if(*tupPtr==*offPtr)
6326         {
6327           int i=offPtr[0];
6328           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6329           if(i==offPtr[1])
6330             {
6331               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6332               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6333               offPtr++;
6334             }
6335         }
6336       else
6337         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6338     }
6339   rangeIdsFetched=ret0.retn();
6340   idsInInputListThatFetch=ret1.retn();
6341 }
6342
6343 /*!
6344  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6345  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6346  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6347  * beginning within the "iota" array. And \a this is a one-dimensional array
6348  * considered as a selector of groups described by \a offsets to include into the result array.
6349  *  \throw If \a offsets is NULL.
6350  *  \throw If \a offsets is not allocated.
6351  *  \throw If \a offsets->getNumberOfComponents() != 1.
6352  *  \throw If \a offsets is not monotonically increasing.
6353  *  \throw If \a this is not allocated.
6354  *  \throw If \a this->getNumberOfComponents() != 1.
6355  *  \throw If any element of \a this is not a valid index for \a offsets array.
6356  *
6357  *  \b Example: <br>
6358  *          - \a this: [0,2,3]
6359  *          - \a offsets: [0,3,6,10,14,20]
6360  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6361  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6362  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
6363  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
6364  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6365  */
6366 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6367 {
6368   if(!offsets)
6369     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6370   checkAllocated();
6371   if(getNumberOfComponents()!=1)
6372     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6373   offsets->checkAllocated();
6374   if(offsets->getNumberOfComponents()!=1)
6375     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6376   int othNbTuples=offsets->getNumberOfTuples()-1;
6377   int nbOfTuples=getNumberOfTuples();
6378   int retNbOftuples=0;
6379   const int *work=getConstPointer();
6380   const int *offPtr=offsets->getConstPointer();
6381   for(int i=0;i<nbOfTuples;i++)
6382     {
6383       int val=work[i];
6384       if(val>=0 && val<othNbTuples)
6385         {
6386           int delta=offPtr[val+1]-offPtr[val];
6387           if(delta>=0)
6388             retNbOftuples+=delta;
6389           else
6390             {
6391               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6392               throw INTERP_KERNEL::Exception(oss.str().c_str());
6393             }
6394         }
6395       else
6396         {
6397           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6398           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6399           throw INTERP_KERNEL::Exception(oss.str().c_str());
6400         }
6401     }
6402   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6403   ret->alloc(retNbOftuples,1);
6404   int *retPtr=ret->getPointer();
6405   for(int i=0;i<nbOfTuples;i++)
6406     {
6407       int val=work[i];
6408       int start=offPtr[val];
6409       int off=offPtr[val+1]-start;
6410       for(int j=0;j<off;j++,retPtr++)
6411         *retPtr=start+j;
6412     }
6413   return ret.retn();
6414 }
6415
6416 /*!
6417  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
6418  * scaled array (monotonically increasing).
6419 from that of \a this and \a
6420  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6421  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6422  * beginning within the "iota" array. And \a this is a one-dimensional array
6423  * considered as a selector of groups described by \a offsets to include into the result array.
6424  *  \throw If \a  is NULL.
6425  *  \throw If \a this is not allocated.
6426  *  \throw If \a this->getNumberOfComponents() != 1.
6427  *  \throw If \a this->getNumberOfTuples() == 0.
6428  *  \throw If \a this is not monotonically increasing.
6429  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6430  *
6431  *  \b Example: <br>
6432  *          - \a bg , \a stop and \a step : (0,5,2)
6433  *          - \a this: [0,3,6,10,14,20]
6434  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6435  */
6436 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6437 {
6438   if(!isAllocated())
6439     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6440   if(getNumberOfComponents()!=1)
6441     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6442   int nbOfTuples(getNumberOfTuples());
6443   if(nbOfTuples==0)
6444     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6445   const int *ids(begin());
6446   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6447   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6448     {
6449       if(pos>=0 && pos<nbOfTuples-1)
6450         {
6451           int delta(ids[pos+1]-ids[pos]);
6452           sz+=delta;
6453           if(delta<0)
6454             {
6455               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6456               throw INTERP_KERNEL::Exception(oss.str().c_str());
6457             }          
6458         }
6459       else
6460         {
6461           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
6462           throw INTERP_KERNEL::Exception(oss.str().c_str());
6463         }
6464     }
6465   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6466   int *retPtr(ret->getPointer());
6467   pos=bg;
6468   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6469     {
6470       int delta(ids[pos+1]-ids[pos]);
6471       for(int j=0;j<delta;j++,retPtr++)
6472         *retPtr=pos;
6473     }
6474   return ret.retn();
6475 }
6476
6477 /*!
6478  * 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.
6479  * 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
6480  * in tuple **i** of returned DataArrayInt.
6481  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6482  *
6483  * 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)]
6484  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6485  * 
6486  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6487  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6488  * \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
6489  *        is thrown if no ranges in \a ranges contains value in \a this.
6490  * 
6491  * \sa DataArrayInt::findIdInRangeForEachTuple
6492  */
6493 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6494 {
6495   if(!ranges)
6496     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6497   if(ranges->getNumberOfComponents()!=2)
6498     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6499   checkAllocated();
6500   if(getNumberOfComponents()!=1)
6501     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6502   int nbTuples=getNumberOfTuples();
6503   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6504   int nbOfRanges=ranges->getNumberOfTuples();
6505   const int *rangesPtr=ranges->getConstPointer();
6506   int *retPtr=ret->getPointer();
6507   const int *inPtr=getConstPointer();
6508   for(int i=0;i<nbTuples;i++,retPtr++)
6509     {
6510       int val=inPtr[i];
6511       bool found=false;
6512       for(int j=0;j<nbOfRanges && !found;j++)
6513         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6514           { *retPtr=j; found=true; }
6515       if(found)
6516         continue;
6517       else
6518         {
6519           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6520           throw INTERP_KERNEL::Exception(oss.str().c_str());
6521         }
6522     }
6523   return ret.retn();
6524 }
6525
6526 /*!
6527  * 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.
6528  * 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
6529  * in tuple **i** of returned DataArrayInt.
6530  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6531  *
6532  * 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)]
6533  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6534  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6535  * 
6536  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6537  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6538  * \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
6539  *        is thrown if no ranges in \a ranges contains value in \a this.
6540  * \sa DataArrayInt::findRangeIdForEachTuple
6541  */
6542 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6543 {
6544   if(!ranges)
6545     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6546   if(ranges->getNumberOfComponents()!=2)
6547     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6548   checkAllocated();
6549   if(getNumberOfComponents()!=1)
6550     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6551   int nbTuples=getNumberOfTuples();
6552   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6553   int nbOfRanges=ranges->getNumberOfTuples();
6554   const int *rangesPtr=ranges->getConstPointer();
6555   int *retPtr=ret->getPointer();
6556   const int *inPtr=getConstPointer();
6557   for(int i=0;i<nbTuples;i++,retPtr++)
6558     {
6559       int val=inPtr[i];
6560       bool found=false;
6561       for(int j=0;j<nbOfRanges && !found;j++)
6562         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6563           { *retPtr=val-rangesPtr[2*j]; found=true; }
6564       if(found)
6565         continue;
6566       else
6567         {
6568           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6569           throw INTERP_KERNEL::Exception(oss.str().c_str());
6570         }
6571     }
6572   return ret.retn();
6573 }
6574
6575 /*!
6576  * \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).
6577  * 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).
6578  * 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 !
6579  * If this method has correctly worked, \a this will be able to be considered as a linked list.
6580  * This method does nothing if number of tuples is lower of equal to 1.
6581  *
6582  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6583  *
6584  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6585  */
6586 void DataArrayInt::sortEachPairToMakeALinkedList()
6587 {
6588   checkAllocated();
6589   if(getNumberOfComponents()!=2)
6590     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6591   int nbOfTuples(getNumberOfTuples());
6592   if(nbOfTuples<=1)
6593     return ;
6594   int *conn(getPointer());
6595   for(int i=1;i<nbOfTuples;i++,conn+=2)
6596     {
6597       if(i>1)
6598         {
6599           if(conn[2]==conn[3])
6600             {
6601               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6602               throw INTERP_KERNEL::Exception(oss.str().c_str());
6603             }
6604           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6605             std::swap(conn[2],conn[3]);
6606           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6607           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6608             {
6609               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6610               throw INTERP_KERNEL::Exception(oss.str().c_str());
6611             }
6612         }
6613       else
6614         {
6615           if(conn[0]==conn[1] || conn[2]==conn[3])
6616             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6617           int tmp[4];
6618           std::set<int> s;
6619           s.insert(conn,conn+4);
6620           if(s.size()!=3)
6621             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6622           if(std::count(conn,conn+4,conn[0])==2)
6623             {
6624               tmp[0]=conn[1];
6625               tmp[1]=conn[0];
6626               tmp[2]=conn[0];
6627               if(conn[2]==conn[0])
6628                 { tmp[3]=conn[3]; }
6629               else
6630                 { tmp[3]=conn[2];}
6631               std::copy(tmp,tmp+4,conn);
6632             }
6633           else
6634             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6635               if(conn[1]==conn[3])
6636                 std::swap(conn[2],conn[3]);
6637             }
6638         }
6639     }
6640 }
6641
6642 /*!
6643  * \a this is expected to be a correctly linked list of pairs.
6644  * 
6645  * \sa DataArrayInt::sortEachPairToMakeALinkedList
6646  */
6647 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6648 {
6649   checkAllocated();
6650   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6651   int nbTuples(getNumberOfTuples());
6652   if(nbTuples<1)
6653     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6654   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6655   const int *thisPtr(begin());
6656   int *retPtr(ret->getPointer());
6657   retPtr[0]=thisPtr[0];
6658   for(int i=0;i<nbTuples;i++)
6659     {
6660       retPtr[i+1]=thisPtr[2*i+1];
6661       if(i<nbTuples-1)
6662         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6663           {
6664             std::ostringstream oss; oss << "DataArrayInt::fromLinkedListOfPairToList : this is not a proper linked list of pair. The link is broken between tuple #" << i << " and tuple #" << i+1 << " ! Call sortEachPairToMakeALinkedList ?";
6665             throw INTERP_KERNEL::Exception(oss.str());
6666           }
6667     }
6668   return ret;
6669 }
6670
6671 /*!
6672  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6673  * But the number of components can be different from one.
6674  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6675  */
6676 DataArrayInt *DataArrayInt::getDifferentValues() const
6677 {
6678   checkAllocated();
6679   std::set<int> ret;
6680   ret.insert(begin(),end());
6681   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6682   std::copy(ret.begin(),ret.end(),ret2->getPointer());
6683   return ret2.retn();
6684 }
6685
6686 /*!
6687  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6688  * them it tells which tuple id have this id.
6689  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6690  * This method returns two arrays having same size.
6691  * 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.
6692  * 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]]
6693  */
6694 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6695 {
6696   checkAllocated();
6697   if(getNumberOfComponents()!=1)
6698     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6699   int id=0;
6700   std::map<int,int> m,m2,m3;
6701   for(const int *w=begin();w!=end();w++)
6702     m[*w]++;
6703   differentIds.resize(m.size());
6704   std::vector<DataArrayInt *> ret(m.size());
6705   std::vector<int *> retPtr(m.size());
6706   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6707     {
6708       m2[(*it).first]=id;
6709       ret[id]=DataArrayInt::New();
6710       ret[id]->alloc((*it).second,1);
6711       retPtr[id]=ret[id]->getPointer();
6712       differentIds[id]=(*it).first;
6713     }
6714   id=0;
6715   for(const int *w=begin();w!=end();w++,id++)
6716     {
6717       retPtr[m2[*w]][m3[*w]++]=id;
6718     }
6719   return ret;
6720 }
6721
6722 /*!
6723  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6724  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6725  *
6726  * \param [in] nbOfSlices - number of slices expected.
6727  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6728  * 
6729  * \sa DataArray::GetSlice
6730  * \throw If \a this is not allocated or not with exactly one component.
6731  * \throw If an element in \a this if < 0.
6732  */
6733 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6734 {
6735   if(!isAllocated() || getNumberOfComponents()!=1)
6736     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6737   if(nbOfSlices<=0)
6738     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6739   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6740   int sumPerSlc(sum/nbOfSlices),pos(0);
6741   const int *w(begin());
6742   std::vector< std::pair<int,int> > ret(nbOfSlices);
6743   for(int i=0;i<nbOfSlices;i++)
6744     {
6745       std::pair<int,int> p(pos,-1);
6746       int locSum(0);
6747       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6748       if(i!=nbOfSlices-1)
6749         p.second=pos;
6750       else
6751         p.second=nbOfTuples;
6752       ret[i]=p;
6753     }
6754   return ret;
6755 }
6756
6757 /*!
6758  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6759  * valid cases.
6760  * 1.  The arrays have same number of tuples and components. Then each value of
6761  *   the result array (_a_) is a division of the corresponding values of \a a1 and
6762  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6763  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
6764  *   component. Then
6765  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6766  * 3.  The arrays have same number of components and one array, say _a2_, has one
6767  *   tuple. Then
6768  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6769  *
6770  * Info on components is copied either from the first array (in the first case) or from
6771  * the array with maximal number of elements (getNbOfElems()).
6772  *  \warning No check of division by zero is performed!
6773  *  \param [in] a1 - a dividend array.
6774  *  \param [in] a2 - a divisor array.
6775  *  \return DataArrayInt * - the new instance of DataArrayInt.
6776  *          The caller is to delete this result array using decrRef() as it is no more
6777  *          needed.
6778  *  \throw If either \a a1 or \a a2 is NULL.
6779  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6780  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6781  *         none of them has number of tuples or components equal to 1.
6782  */
6783 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6784 {
6785   if(!a1 || !a2)
6786     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6787   int nbOfTuple1=a1->getNumberOfTuples();
6788   int nbOfTuple2=a2->getNumberOfTuples();
6789   int nbOfComp1=a1->getNumberOfComponents();
6790   int nbOfComp2=a2->getNumberOfComponents();
6791   if(nbOfTuple2==nbOfTuple1)
6792     {
6793       if(nbOfComp1==nbOfComp2)
6794         {
6795           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6796           ret->alloc(nbOfTuple2,nbOfComp1);
6797           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6798           ret->copyStringInfoFrom(*a1);
6799           return ret.retn();
6800         }
6801       else if(nbOfComp2==1)
6802         {
6803           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6804           ret->alloc(nbOfTuple1,nbOfComp1);
6805           const int *a2Ptr=a2->getConstPointer();
6806           const int *a1Ptr=a1->getConstPointer();
6807           int *res=ret->getPointer();
6808           for(int i=0;i<nbOfTuple1;i++)
6809             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6810           ret->copyStringInfoFrom(*a1);
6811           return ret.retn();
6812         }
6813       else
6814         {
6815           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6816           return 0;
6817         }
6818     }
6819   else if(nbOfTuple2==1)
6820     {
6821       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6822       MCAuto<DataArrayInt> ret=DataArrayInt::New();
6823       ret->alloc(nbOfTuple1,nbOfComp1);
6824       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6825       int *pt=ret->getPointer();
6826       for(int i=0;i<nbOfTuple1;i++)
6827         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6828       ret->copyStringInfoFrom(*a1);
6829       return ret.retn();
6830     }
6831   else
6832     {
6833       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6834       return 0;
6835     }
6836 }
6837
6838 /*!
6839  * Modify \a this array so that each value becomes a modulus of division of this value by
6840  * a value of another DataArrayInt. There are 3 valid cases.
6841  * 1.  The arrays have same number of tuples and components. Then each value of
6842  *    \a this array is divided by the corresponding value of \a other one, i.e.:
6843  *   _a_ [ i, j ] %= _other_ [ i, j ].
6844  * 2.  The arrays have same number of tuples and \a other array has one component. Then
6845  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
6846  * 3.  The arrays have same number of components and \a other array has one tuple. Then
6847  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
6848  *
6849  *  \warning No check of division by zero is performed!
6850  *  \param [in] other - a divisor array.
6851  *  \throw If \a other is NULL.
6852  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6853  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6854  *         \a other has number of both tuples and components not equal to 1.
6855  */
6856 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6857 {
6858   if(!other)
6859     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6860   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6861   checkAllocated(); other->checkAllocated();
6862   int nbOfTuple=getNumberOfTuples();
6863   int nbOfTuple2=other->getNumberOfTuples();
6864   int nbOfComp=getNumberOfComponents();
6865   int nbOfComp2=other->getNumberOfComponents();
6866   if(nbOfTuple==nbOfTuple2)
6867     {
6868       if(nbOfComp==nbOfComp2)
6869         {
6870           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6871         }
6872       else if(nbOfComp2==1)
6873         {
6874           if(nbOfComp2==nbOfComp)
6875             {
6876               int *ptr=getPointer();
6877               const int *ptrc=other->getConstPointer();
6878               for(int i=0;i<nbOfTuple;i++)
6879                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6880             }
6881           else
6882             throw INTERP_KERNEL::Exception(msg);
6883         }
6884       else
6885         throw INTERP_KERNEL::Exception(msg);
6886     }
6887   else if(nbOfTuple2==1)
6888     {
6889       int *ptr=getPointer();
6890       const int *ptrc=other->getConstPointer();
6891       for(int i=0;i<nbOfTuple;i++)
6892         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6893     }
6894   else
6895     throw INTERP_KERNEL::Exception(msg);
6896   declareAsNew();
6897 }
6898
6899 /*!
6900  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6901  * valid cases.
6902  *
6903  *  \param [in] a1 - an array to pow up.
6904  *  \param [in] a2 - another array to sum up.
6905  *  \return DataArrayInt * - the new instance of DataArrayInt.
6906  *          The caller is to delete this result array using decrRef() as it is no more
6907  *          needed.
6908  *  \throw If either \a a1 or \a a2 is NULL.
6909  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6910  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6911  *  \throw If there is a negative value in \a a2.
6912  */
6913 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6914 {
6915   if(!a1 || !a2)
6916     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6917   int nbOfTuple=a1->getNumberOfTuples();
6918   int nbOfTuple2=a2->getNumberOfTuples();
6919   int nbOfComp=a1->getNumberOfComponents();
6920   int nbOfComp2=a2->getNumberOfComponents();
6921   if(nbOfTuple!=nbOfTuple2)
6922     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6923   if(nbOfComp!=1 || nbOfComp2!=1)
6924     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6925   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6926   const int *ptr1(a1->begin()),*ptr2(a2->begin());
6927   int *ptr=ret->getPointer();
6928   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6929     {
6930       if(*ptr2>=0)
6931         {
6932           int tmp=1;
6933           for(int j=0;j<*ptr2;j++)
6934             tmp*=*ptr1;
6935           *ptr=tmp;
6936         }
6937       else
6938         {
6939           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6940           throw INTERP_KERNEL::Exception(oss.str().c_str());
6941         }
6942     }
6943   return ret.retn();
6944 }
6945
6946 /*!
6947  * Apply pow on values of another DataArrayInt to values of \a this one.
6948  *
6949  *  \param [in] other - an array to pow to \a this one.
6950  *  \throw If \a other is NULL.
6951  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6952  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6953  *  \throw If there is a negative value in \a other.
6954  */
6955 void DataArrayInt::powEqual(const DataArrayInt *other)
6956 {
6957   if(!other)
6958     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6959   int nbOfTuple=getNumberOfTuples();
6960   int nbOfTuple2=other->getNumberOfTuples();
6961   int nbOfComp=getNumberOfComponents();
6962   int nbOfComp2=other->getNumberOfComponents();
6963   if(nbOfTuple!=nbOfTuple2)
6964     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6965   if(nbOfComp!=1 || nbOfComp2!=1)
6966     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6967   int *ptr=getPointer();
6968   const int *ptrc=other->begin();
6969   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6970     {
6971       if(*ptrc>=0)
6972         {
6973           int tmp=1;
6974           for(int j=0;j<*ptrc;j++)
6975             tmp*=*ptr;
6976           *ptr=tmp;
6977         }
6978       else
6979         {
6980           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6981           throw INTERP_KERNEL::Exception(oss.str().c_str());
6982         }
6983     }
6984   declareAsNew();
6985 }
6986
6987 /*!
6988  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6989  * This map, if applied to \a start array, would make it sorted. For example, if
6990  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6991  * [5,6,0,3,2,7,1,4].
6992  *  \param [in] start - pointer to the first element of the array for which the
6993  *         permutation map is computed.
6994  *  \param [in] end - pointer specifying the end of the array \a start, so that
6995  *         the last value of \a start is \a end[ -1 ].
6996  *  \return int * - the result permutation array that the caller is to delete as it is no
6997  *         more needed.
6998  *  \throw If there are equal values in the input array.
6999  */
7000 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
7001 {
7002   std::size_t sz=std::distance(start,end);
7003   int *ret=(int *)malloc(sz*sizeof(int));
7004   int *work=new int[sz];
7005   std::copy(start,end,work);
7006   std::sort(work,work+sz);
7007   if(std::unique(work,work+sz)!=work+sz)
7008     {
7009       delete [] work;
7010       free(ret);
7011       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
7012     }
7013   std::map<int,int> m;
7014   for(int *workPt=work;workPt!=work+sz;workPt++)
7015     m[*workPt]=(int)std::distance(work,workPt);
7016   int *iter2=ret;
7017   for(const int *iter=start;iter!=end;iter++,iter2++)
7018     *iter2=m[*iter];
7019   delete [] work;
7020   return ret;
7021 }
7022
7023 /*!
7024  * Returns a new DataArrayInt containing an arithmetic progression
7025  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
7026  * function.
7027  *  \param [in] begin - the start value of the result sequence.
7028  *  \param [in] end - limiting value, so that every value of the result array is less than
7029  *              \a end.
7030  *  \param [in] step - specifies the increment or decrement.
7031  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7032  *          array using decrRef() as it is no more needed.
7033  *  \throw If \a step == 0.
7034  *  \throw If \a end < \a begin && \a step > 0.
7035  *  \throw If \a end > \a begin && \a step < 0.
7036  */
7037 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
7038 {
7039   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7040   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7041   ret->alloc(nbOfTuples,1);
7042   int *ptr=ret->getPointer();
7043   if(step>0)
7044     {
7045       for(int i=begin;i<end;i+=step,ptr++)
7046         *ptr=i;
7047     }
7048   else
7049     {
7050       for(int i=begin;i>end;i+=step,ptr++)
7051         *ptr=i;
7052     }
7053   return ret.retn();
7054 }
7055
7056 /*!
7057  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7058  * Server side.
7059  */
7060 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
7061 {
7062   tinyInfo.resize(2);
7063   if(isAllocated())
7064     {
7065       tinyInfo[0]=getNumberOfTuples();
7066       tinyInfo[1]=getNumberOfComponents();
7067     }
7068   else
7069     {
7070       tinyInfo[0]=-1;
7071       tinyInfo[1]=-1;
7072     }
7073 }
7074
7075 /*!
7076  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7077  * Server side.
7078  */
7079 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
7080 {
7081   if(isAllocated())
7082     {
7083       int nbOfCompo=getNumberOfComponents();
7084       tinyInfo.resize(nbOfCompo+1);
7085       tinyInfo[0]=getName();
7086       for(int i=0;i<nbOfCompo;i++)
7087         tinyInfo[i+1]=getInfoOnComponent(i);
7088     }
7089   else
7090     {
7091       tinyInfo.resize(1);
7092       tinyInfo[0]=getName();
7093     }
7094 }
7095
7096 /*!
7097  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7098  * This method returns if a feeding is needed.
7099  */
7100 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
7101 {
7102   int nbOfTuple=tinyInfoI[0];
7103   int nbOfComp=tinyInfoI[1];
7104   if(nbOfTuple!=-1 || nbOfComp!=-1)
7105     {
7106       alloc(nbOfTuple,nbOfComp);
7107       return true;
7108     }
7109   return false;
7110 }
7111
7112 /*!
7113  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7114  * This method returns if a feeding is needed.
7115  */
7116 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
7117 {
7118   setName(tinyInfoS[0]);
7119   if(isAllocated())
7120     {
7121       int nbOfCompo=tinyInfoI[1];
7122       for(int i=0;i<nbOfCompo;i++)
7123         setInfoOnComponent(i,tinyInfoS[i+1]);
7124     }
7125 }
7126
7127 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
7128 {
7129 }
7130
7131 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
7132 {
7133 }
7134
7135 std::string DataArrayIntTuple::repr() const
7136 {
7137   std::ostringstream oss; oss << "(";
7138   for(int i=0;i<_nb_of_compo-1;i++)
7139     oss << _pt[i] << ", ";
7140   oss << _pt[_nb_of_compo-1] << ")";
7141   return oss.str();
7142 }
7143
7144 int DataArrayIntTuple::intValue() const
7145 {
7146   return this->zeValue();
7147 }
7148
7149 /*!
7150  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
7151  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
7152  * 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
7153  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
7154  */
7155 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
7156 {
7157   return this->buildDA(nbOfTuples,nbOfCompo);
7158 }