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