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