Salome HOME
4d4fed46d4d31e4f7bfb79a9b02beaff89b075f1
[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 split into slices.
675  * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
676  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split 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 containing 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 containing 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 containing 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 containing 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, findIdForEach
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());
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());
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> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4211 {
4212   checkAllocated();
4213   if(getNumberOfComponents()!=1)
4214     throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4215   MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4216   std::map<int,int>& m(ret->data());
4217   const int *new2Old(begin());
4218   std::size_t nbOfNewElems(this->getNumberOfTuples());
4219   for(std::size_t i=0;i<nbOfNewElems;i++)
4220     {
4221       int v(new2Old[i]);
4222       m[v]=i;
4223     }
4224   return ret;
4225 }
4226
4227 /*!
4228  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4229  * This map, if applied to \a this array, would make it sorted. For example, if
4230  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4231  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4232  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4233  * This method is useful for renumbering (in MED file for example). For more info
4234  * on renumbering see \ref numbering.
4235  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4236  *          array using decrRef() as it is no more needed.
4237  *  \throw If \a this is not allocated.
4238  *  \throw If \a this->getNumberOfComponents() != 1.
4239  *  \throw If there are equal values in \a this array.
4240  */
4241 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4242 {
4243   checkAllocated();
4244   if(getNumberOfComponents()!=1)
4245     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4246   int nbTuples=getNumberOfTuples();
4247   const int *pt=getConstPointer();
4248   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4249   DataArrayInt *ret=DataArrayInt::New();
4250   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4251   return ret;
4252 }
4253
4254 /*!
4255  * 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
4256  * input array \a ids2.
4257  * \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.
4258  * 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
4259  * inversely.
4260  * In case of success both assertion will be true (no throw) :
4261  * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4262  * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4263  *
4264  * \b Example:
4265  * - \a ids1 : [3,1,103,4,6,10,-7,205]
4266  * - \a ids2 : [-7,1,205,10,6,3,103,4]
4267  * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4268  *
4269  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4270  *          array using decrRef() as it is no more needed.
4271  * \throw If either ids1 or ids2 is null not allocated or not with one components.
4272  * 
4273  * \sa DataArrayInt32::findIdForEach
4274  */
4275 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4276 {
4277   if(!ids1 || !ids2)
4278     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4279   if(!ids1->isAllocated() || !ids2->isAllocated())
4280     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4281   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4282     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4283   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4284     {
4285       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 !";
4286       throw INTERP_KERNEL::Exception(oss.str().c_str());
4287     }
4288   MCAuto<DataArrayInt> p1(ids1->deepCopy());
4289   MCAuto<DataArrayInt> p2(ids2->deepCopy());
4290   p1->sort(true); p2->sort(true);
4291   if(!p1->isEqualWithoutConsideringStr(*p2))
4292     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4293   p1=ids1->checkAndPreparePermutation();
4294   p2=ids2->checkAndPreparePermutation();
4295   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4296   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4297   return p2.retn();
4298 }
4299
4300 /*!
4301  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4302  * onto a set of values of size \a targetNb (\a B). The surjective function is 
4303  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4304  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4305  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4306  * The first of out arrays returns indices of elements of \a this array, grouped by their
4307  * place in the set \a B. The second out array is the index of the first one; it shows how
4308  * many elements of \a A are mapped into each element of \a B. <br>
4309  * For more info on
4310  * mapping and its usage in renumbering see \ref numbering. <br>
4311  * \b Example:
4312  * - \a this: [0,3,2,3,2,2,1,2]
4313  * - \a targetNb: 4
4314  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
4315  * - \a arrI: [0,1,2,6,8]
4316  *
4317  * This result means: <br>
4318  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4319  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4320  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4321  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
4322  * \a arrI[ 2+1 ]]); <br> etc.
4323  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4324  *         than the maximal value of \a A.
4325  *  \param [out] arr - a new instance of DataArrayInt returning indices of
4326  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
4327  *         this array using decrRef() as it is no more needed.
4328  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4329  *         elements of \a this. The caller is to delete this array using decrRef() as it
4330  *         is no more needed.
4331  *  \throw If \a this is not allocated.
4332  *  \throw If \a this->getNumberOfComponents() != 1.
4333  *  \throw If any value in \a this is more or equal to \a targetNb.
4334  */
4335 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4336 {
4337   checkAllocated();
4338   if(getNumberOfComponents()!=1)
4339     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4340   int nbOfTuples=getNumberOfTuples();
4341   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4342   MCAuto<DataArrayInt> retI(DataArrayInt::New());
4343   retI->alloc(targetNb+1,1);
4344   const int *input=getConstPointer();
4345   std::vector< std::vector<int> > tmp(targetNb);
4346   for(int i=0;i<nbOfTuples;i++)
4347     {
4348       int tmp2=input[i];
4349       if(tmp2>=0 && tmp2<targetNb)
4350         tmp[tmp2].push_back(i);
4351       else
4352         {
4353           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4354           throw INTERP_KERNEL::Exception(oss.str().c_str());
4355         }
4356     }
4357   int *retIPtr=retI->getPointer();
4358   *retIPtr=0;
4359   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4360     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4361   if(nbOfTuples!=retI->getIJ(targetNb,0))
4362     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4363   ret->alloc(nbOfTuples,1);
4364   int *retPtr=ret->getPointer();
4365   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4366     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4367   arr=ret.retn();
4368   arrI=retI.retn();
4369 }
4370
4371
4372 /*!
4373  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4374  * from a zip representation of a surjective format (returned e.g. by
4375  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4376  * for example). The result array minimizes the permutation. <br>
4377  * For more info on renumbering see \ref numbering. <br>
4378  * \b Example: <br>
4379  * - \a nbOfOldTuples: 10 
4380  * - \a arr          : [0,3, 5,7,9]
4381  * - \a arrIBg       : [0,2,5]
4382  * - \a newNbOfTuples: 7
4383  * - result array    : [0,1,2,0,3,4,5,4,6,4]
4384  *
4385  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4386  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4387  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4388  *         (indices of) equal values. Its every element (except the last one) points to
4389  *         the first element of a group of equal values.
4390  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4391  *          arrIBg is \a arrIEnd[ -1 ].
4392  *  \param [out] newNbOfTuples - number of tuples after surjection application.
4393  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4394  *          array using decrRef() as it is no more needed.
4395  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4396  */
4397 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4398 {
4399   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4400   ret->alloc(nbOfOldTuples,1);
4401   int *pt=ret->getPointer();
4402   std::fill(pt,pt+nbOfOldTuples,-1);
4403   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4404   const int *cIPtr=arrIBg;
4405   for(int i=0;i<nbOfGrps;i++)
4406     pt[arr[cIPtr[i]]]=-(i+2);
4407   int newNb=0;
4408   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4409     {
4410       if(pt[iNode]<0)
4411         {
4412           if(pt[iNode]==-1)
4413             pt[iNode]=newNb++;
4414           else
4415             {
4416               int grpId=-(pt[iNode]+2);
4417               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4418                 {
4419                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4420                     pt[arr[j]]=newNb;
4421                   else
4422                     {
4423                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4424                       throw INTERP_KERNEL::Exception(oss.str().c_str());
4425                     }
4426                 }
4427               newNb++;
4428             }
4429         }
4430     }
4431   newNbOfTuples=newNb;
4432   return ret.retn();
4433 }
4434
4435 /*!
4436  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4437  * which if applied to \a this array would make it sorted ascendingly.
4438  * For more info on renumbering see \ref numbering. <br>
4439  * \b Example: <br>
4440  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4441  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4442  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
4443  *
4444  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4445  *          array using decrRef() as it is no more needed.
4446  *  \throw If \a this is not allocated.
4447  *  \throw If \a this->getNumberOfComponents() != 1.
4448  */
4449 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4450 {
4451   checkAllocated();
4452   if(getNumberOfComponents()!=1)
4453     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4454   int nbOfTuples=getNumberOfTuples();
4455   const int *pt=getConstPointer();
4456   std::map<int,int> m;
4457   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4458   ret->alloc(nbOfTuples,1);
4459   int *opt=ret->getPointer();
4460   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4461     {
4462       int val=*pt;
4463       std::map<int,int>::iterator it=m.find(val);
4464       if(it!=m.end())
4465         {
4466           *opt=(*it).second;
4467           (*it).second++;
4468         }
4469       else
4470         {
4471           *opt=0;
4472           m.insert(std::pair<int,int>(val,1));
4473         }
4474     }
4475   int sum=0;
4476   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4477     {
4478       int vt=(*it).second;
4479       (*it).second=sum;
4480       sum+=vt;
4481     }
4482   pt=getConstPointer();
4483   opt=ret->getPointer();
4484   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4485     *opt+=m[*pt];
4486   //
4487   return ret.retn();
4488 }
4489
4490 /*!
4491  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4492  * iota(). This method is particularly useful for DataArrayInt instances that represent
4493  * a renumbering array, to check if there is a real need in renumbering.
4494  * This method checks than \a this can be considered as an identity mapping
4495  * of a set having \a sizeExpected elements into itself.
4496  *
4497  *  \param [in] sizeExpected - The number of elements expected.
4498  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4499  *  \throw If \a this is not allocated.
4500  *  \throw If \a this->getNumberOfComponents() != 1.
4501  */
4502 bool DataArrayInt::isIota(int sizeExpected) const
4503 {
4504   checkAllocated();
4505   if(getNumberOfComponents()!=1)
4506     return false;
4507   int nbOfTuples(getNumberOfTuples());
4508   if(nbOfTuples!=sizeExpected)
4509     return false;
4510   const int *pt=getConstPointer();
4511   for(int i=0;i<nbOfTuples;i++,pt++)
4512     if(*pt!=i)
4513       return false;
4514   return true;
4515 }
4516
4517 /*!
4518  * Checks if all values in \a this array are equal to \a val.
4519  *  \param [in] val - value to check equality of array values to.
4520  *  \return bool - \a true if all values are \a val.
4521  *  \throw If \a this is not allocated.
4522  *  \throw If \a this->getNumberOfComponents() != 1
4523  *  \sa DataArrayInt::checkUniformAndGuess
4524  */
4525 bool DataArrayInt::isUniform(int val) const
4526 {
4527   checkAllocated();
4528   if(getNumberOfComponents()!=1)
4529     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4530   const int *w(begin()),*end2(end());
4531   for(;w!=end2;w++)
4532     if(*w!=val)
4533       return false;
4534   return true;
4535 }
4536
4537 /*!
4538  * This method checks that \a this is uniform. If not and exception will be thrown.
4539  * In case of uniformity the corresponding value is returned.
4540  *
4541  * \return int - the unique value contained in this
4542  * \throw If \a this is not allocated.
4543  * \throw If \a this->getNumberOfComponents() != 1
4544  * \throw If \a this is not uniform.
4545  * \sa DataArrayInt::isUniform
4546  */
4547 int DataArrayInt::checkUniformAndGuess() const
4548 {
4549   checkAllocated();
4550   if(getNumberOfComponents()!=1)
4551     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4552   if(empty())
4553     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4554   const int *w(begin()),*end2(end());
4555   int ret(*w);
4556   for(;w!=end2;w++)
4557     if(*w!=ret)
4558       throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4559   return ret;
4560 }
4561
4562 /*!
4563  * Checks if all values in \a this array are unique.
4564  *  \return bool - \a true if condition above is true
4565  *  \throw If \a this is not allocated.
4566  *  \throw If \a this->getNumberOfComponents() != 1
4567  */
4568 bool DataArrayInt::hasUniqueValues() const
4569 {
4570   checkAllocated();
4571   if(getNumberOfComponents()!=1)
4572     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4573   std::size_t nbOfTuples(getNumberOfTuples());
4574   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
4575   if (s.size() != nbOfTuples)
4576     return false;
4577   return true;
4578 }
4579
4580 /*!
4581  * Copy all components in a specified order from another DataArrayInt.
4582  * The specified components become the first ones in \a this array.
4583  * Both numerical and textual data is copied. The number of tuples in \a this and
4584  * the other array can be different.
4585  *  \param [in] a - the array to copy data from.
4586  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
4587  *              to be copied.
4588  *  \throw If \a a is NULL.
4589  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4590  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4591  *
4592  *  \if ENABLE_EXAMPLES
4593  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4594  *  \endif
4595  */
4596 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4597 {
4598   if(!a)
4599     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4600   checkAllocated();
4601   a->checkAllocated();
4602   copyPartOfStringInfoFrom2(compoIds,*a);
4603   std::size_t partOfCompoSz=compoIds.size();
4604   int nbOfCompo=getNumberOfComponents();
4605   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4606   const int *ac=a->getConstPointer();
4607   int *nc=getPointer();
4608   for(int i=0;i<nbOfTuples;i++)
4609     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4610       nc[nbOfCompo*i+compoIds[j]]=*ac;
4611 }
4612
4613 DataArrayIntIterator *DataArrayInt::iterator()
4614 {
4615   return new DataArrayIntIterator(this);
4616 }
4617
4618 /*!
4619  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4620  * given one. The ids are sorted in the ascending order.
4621  *  \param [in] val - the value to find within \a this.
4622  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4623  *          array using decrRef() as it is no more needed.
4624  *  \throw If \a this is not allocated.
4625  *  \throw If \a this->getNumberOfComponents() != 1.
4626  *  \sa DataArrayInt::findIdsEqualTuple
4627  */
4628 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4629 {
4630   checkAllocated();
4631   if(getNumberOfComponents()!=1)
4632     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4633   const int *cptr(getConstPointer());
4634   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4635   int nbOfTuples=getNumberOfTuples();
4636   for(int i=0;i<nbOfTuples;i++,cptr++)
4637     if(*cptr==val)
4638       ret->pushBackSilent(i);
4639   return ret.retn();
4640 }
4641
4642 /*!
4643  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4644  * equal to a given one. 
4645  *  \param [in] val - the value to ignore within \a this.
4646  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4647  *          array using decrRef() as it is no more needed.
4648  *  \throw If \a this is not allocated.
4649  *  \throw If \a this->getNumberOfComponents() != 1.
4650  */
4651 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4652 {
4653   checkAllocated();
4654   if(getNumberOfComponents()!=1)
4655     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4656   const int *cptr(getConstPointer());
4657   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4658   int nbOfTuples=getNumberOfTuples();
4659   for(int i=0;i<nbOfTuples;i++,cptr++)
4660     if(*cptr!=val)
4661       ret->pushBackSilent(i);
4662   return ret.retn();
4663 }
4664
4665 /*!
4666  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4667  * This method is an extension of  DataArrayInt::findIdsEqual method.
4668  *
4669  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4670  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4671  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4672  *          array using decrRef() as it is no more needed.
4673  *  \throw If \a this is not allocated.
4674  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4675  * \throw If \a this->getNumberOfComponents() is equal to 0.
4676  * \sa DataArrayInt::findIdsEqual
4677  */
4678 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4679 {
4680   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4681   checkAllocated();
4682   if(getNumberOfComponents()!=nbOfCompoExp)
4683     {
4684       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4685       throw INTERP_KERNEL::Exception(oss.str().c_str());
4686     }
4687   if(nbOfCompoExp==0)
4688     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4689   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4690   const int *bg(begin()),*end2(end()),*work(begin());
4691   while(work!=end2)
4692     {
4693       work=std::search(work,end2,tupleBg,tupleEnd);
4694       if(work!=end2)
4695         {
4696           std::size_t pos(std::distance(bg,work));
4697           if(pos%nbOfCompoExp==0)
4698             ret->pushBackSilent(pos/nbOfCompoExp);
4699           work++;
4700         }
4701     }
4702   return ret.retn();
4703 }
4704
4705 /*!
4706  * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4707  * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4708  * an exception will be thrown.
4709  *
4710  * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4711  * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4712  * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4713  * <br>
4714  * \b Example: <br>
4715  * - \a this: [17,27,2,10,-4,3,12,27,16]
4716  * - \a val : [3,16,-4,27,17]
4717  * - result: [5,8,4,7,0]
4718  *
4719  * \return - An array of size std::distance(valsBg,valsEnd)
4720  *
4721  * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4722  */
4723 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4724 {
4725   MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4726   std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4727   ret->alloc(nbOfTuplesOut,1);
4728   MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4729   const std::map<int,int>& dat(zeMap->data());
4730   int *ptToFeed(ret->getPointer());
4731   for(const int *pt=valsBg;pt!=valsEnd;pt++)
4732     {
4733       std::map<int,int>::const_iterator it(dat.find(*pt));
4734       if(it!=dat.end())
4735         *ptToFeed++=(*it).second;
4736       else
4737         {
4738           std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4739           oss << " of input array value is " << *pt << " which is not in this !";
4740           throw INTERP_KERNEL::Exception(oss.str());
4741         }
4742     }
4743   return ret;
4744 }
4745
4746 /*!
4747  * Assigns \a newValue to all elements holding \a oldValue within \a this
4748  * one-dimensional array.
4749  *  \param [in] oldValue - the value to replace.
4750  *  \param [in] newValue - the value to assign.
4751  *  \return int - number of replacements performed.
4752  *  \throw If \a this is not allocated.
4753  *  \throw If \a this->getNumberOfComponents() != 1.
4754  */
4755 int DataArrayInt::changeValue(int oldValue, int newValue)
4756 {
4757   checkAllocated();
4758   if(getNumberOfComponents()!=1)
4759     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4760   if(oldValue==newValue)
4761     return 0;
4762   int *start(getPointer()),*end2(start+getNbOfElems());
4763   int ret(0);
4764   for(int *val=start;val!=end2;val++)
4765     {
4766       if(*val==oldValue)
4767         {
4768           *val=newValue;
4769           ret++;
4770         }
4771     }
4772   if(ret>0)
4773     declareAsNew();
4774   return ret;
4775 }
4776
4777 /*!
4778  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4779  * one of given values.
4780  *  \param [in] valsBg - an array of values to find within \a this array.
4781  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4782  *              the last value of \a valsBg is \a valsEnd[ -1 ].
4783  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4784  *          array using decrRef() as it is no more needed.
4785  *  \throw If \a this->getNumberOfComponents() != 1.
4786  */
4787 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4788 {
4789   if(getNumberOfComponents()!=1)
4790     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4791   std::set<int> vals2(valsBg,valsEnd);
4792   const int *cptr(getConstPointer());
4793   std::vector<int> res;
4794   int nbOfTuples(getNumberOfTuples());
4795   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4796   for(int i=0;i<nbOfTuples;i++,cptr++)
4797     if(vals2.find(*cptr)!=vals2.end())
4798       ret->pushBackSilent(i);
4799   return ret.retn();
4800 }
4801
4802 /*!
4803  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4804  * equal to any of given values.
4805  *  \param [in] valsBg - an array of values to ignore within \a this array.
4806  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4807  *              the last value of \a valsBg is \a valsEnd[ -1 ].
4808  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4809  *          array using decrRef() as it is no more needed.
4810  *  \throw If \a this->getNumberOfComponents() != 1.
4811  */
4812 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4813 {
4814   if(getNumberOfComponents()!=1)
4815     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4816   std::set<int> vals2(valsBg,valsEnd);
4817   const int *cptr=getConstPointer();
4818   std::vector<int> res;
4819   int nbOfTuples=getNumberOfTuples();
4820   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4821   for(int i=0;i<nbOfTuples;i++,cptr++)
4822     if(vals2.find(*cptr)==vals2.end())
4823       ret->pushBackSilent(i);
4824   return ret.retn();
4825 }
4826
4827 /*!
4828  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4829  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4830  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4831  * If any the tuple id is returned. If not -1 is returned.
4832  * 
4833  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4834  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4835  *
4836  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4837  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4838  */
4839 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4840 {
4841   checkAllocated();
4842   int nbOfCompo=getNumberOfComponents();
4843   if(nbOfCompo==0)
4844     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4845   if(nbOfCompo!=(int)tupl.size())
4846     {
4847       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4848       throw INTERP_KERNEL::Exception(oss.str().c_str());
4849     }
4850   const int *cptr=getConstPointer();
4851   std::size_t nbOfVals=getNbOfElems();
4852   for(const int *work=cptr;work!=cptr+nbOfVals;)
4853     {
4854       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4855       if(work!=cptr+nbOfVals)
4856         {
4857           if(std::distance(cptr,work)%nbOfCompo!=0)
4858             work++;
4859           else
4860             return std::distance(cptr,work)/nbOfCompo;
4861         }
4862     }
4863   return -1;
4864 }
4865
4866 /*!
4867  * This method searches the sequence specified in input parameter \b vals in \b this.
4868  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4869  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4870  * \sa DataArrayInt::findIdFirstEqualTuple
4871  */
4872 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4873 {
4874   checkAllocated();
4875   int nbOfCompo=getNumberOfComponents();
4876   if(nbOfCompo!=1)
4877     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4878   const int *cptr=getConstPointer();
4879   std::size_t nbOfVals=getNbOfElems();
4880   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4881   if(loc!=cptr+nbOfVals)
4882     return std::distance(cptr,loc);
4883   return -1;
4884 }
4885
4886 /*!
4887  * This method expects to be called when number of components of this is equal to one.
4888  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4889  * If not any tuple contains \b value -1 is returned.
4890  * \sa DataArrayInt::presenceOfValue
4891  */
4892 int DataArrayInt::findIdFirstEqual(int value) const
4893 {
4894   checkAllocated();
4895   if(getNumberOfComponents()!=1)
4896     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4897   const int *cptr=getConstPointer();
4898   int nbOfTuples=getNumberOfTuples();
4899   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4900   if(ret!=cptr+nbOfTuples)
4901     return std::distance(cptr,ret);
4902   return -1;
4903 }
4904
4905 /*!
4906  * This method expects to be called when number of components of this is equal to one.
4907  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4908  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4909  * \sa DataArrayInt::presenceOfValue
4910  */
4911 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4912 {
4913   checkAllocated();
4914   if(getNumberOfComponents()!=1)
4915     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4916   std::set<int> vals2(vals.begin(),vals.end());
4917   const int *cptr=getConstPointer();
4918   int nbOfTuples=getNumberOfTuples();
4919   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4920     if(vals2.find(*w)!=vals2.end())
4921       return std::distance(cptr,w);
4922   return -1;
4923 }
4924
4925 /*!
4926  * This method returns the number of values in \a this that are equals to input parameter \a value.
4927  * This method only works for single component array.
4928  *
4929  * \return a value in [ 0, \c this->getNumberOfTuples() )
4930  *
4931  * \throw If \a this is not allocated
4932  *
4933  */
4934 int DataArrayInt::count(int value) const
4935 {
4936   int ret=0;
4937   checkAllocated();
4938   if(getNumberOfComponents()!=1)
4939     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4940   const int *vals=begin();
4941   int nbOfTuples=getNumberOfTuples();
4942   for(int i=0;i<nbOfTuples;i++,vals++)
4943     if(*vals==value)
4944       ret++;
4945   return ret;
4946 }
4947
4948 /*!
4949  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4950  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4951  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4952  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4953  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4954  * \sa DataArrayInt::findIdFirstEqualTuple
4955  */
4956 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4957 {
4958   return findIdFirstEqualTuple(tupl)!=-1;
4959 }
4960
4961
4962 /*!
4963  * Returns \a true if a given value is present within \a this one-dimensional array.
4964  *  \param [in] value - the value to find within \a this array.
4965  *  \return bool - \a true in case if \a value is present within \a this array.
4966  *  \throw If \a this is not allocated.
4967  *  \throw If \a this->getNumberOfComponents() != 1.
4968  *  \sa findIdFirstEqual()
4969  */
4970 bool DataArrayInt::presenceOfValue(int value) const
4971 {
4972   return findIdFirstEqual(value)!=-1;
4973 }
4974
4975 /*!
4976  * This method expects to be called when number of components of this is equal to one.
4977  * This method returns true if it exists a tuple so that the value is contained in \b vals.
4978  * If not any tuple contains one of the values contained in 'vals' false is returned.
4979  * \sa DataArrayInt::findIdFirstEqual
4980  */
4981 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4982 {
4983   return findIdFirstEqual(vals)!=-1;
4984 }
4985
4986 /*!
4987  * Accumulates values of each component of \a this array.
4988  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
4989  *         by the caller, that is filled by this method with sum value for each
4990  *         component.
4991  *  \throw If \a this is not allocated.
4992  */
4993 void DataArrayInt::accumulate(int *res) const
4994 {
4995   checkAllocated();
4996   const int *ptr=getConstPointer();
4997   int nbTuple=getNumberOfTuples();
4998   int nbComps=getNumberOfComponents();
4999   std::fill(res,res+nbComps,0);
5000   for(int i=0;i<nbTuple;i++)
5001     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5002 }
5003
5004 int DataArrayInt::accumulate(int compId) const
5005 {
5006   checkAllocated();
5007   const int *ptr=getConstPointer();
5008   int nbTuple=getNumberOfTuples();
5009   int nbComps=getNumberOfComponents();
5010   if(compId<0 || compId>=nbComps)
5011     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5012   int ret=0;
5013   for(int i=0;i<nbTuple;i++)
5014     ret+=ptr[i*nbComps+compId];
5015   return ret;
5016 }
5017
5018 /*!
5019  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5020  * The returned array will have same number of components than \a this and number of tuples equal to
5021  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5022  *
5023  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5024  *
5025  * \param [in] bgOfIndex - begin (included) of the input index array.
5026  * \param [in] endOfIndex - end (excluded) of the input index array.
5027  * \return DataArrayInt * - the new instance having the same number of components than \a this.
5028  * 
5029  * \throw If bgOfIndex or end is NULL.
5030  * \throw If input index array is not ascendingly sorted.
5031  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5032  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5033  */
5034 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5035 {
5036   if(!bgOfIndex || !endOfIndex)
5037     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5038   checkAllocated();
5039   int nbCompo=getNumberOfComponents();
5040   int nbOfTuples=getNumberOfTuples();
5041   int sz=(int)std::distance(bgOfIndex,endOfIndex);
5042   if(sz<1)
5043     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5044   sz--;
5045   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5046   const int *w=bgOfIndex;
5047   if(*w<0 || *w>=nbOfTuples)
5048     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5049   const int *srcPt=begin()+(*w)*nbCompo;
5050   int *tmp=ret->getPointer();
5051   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5052     {
5053       std::fill(tmp,tmp+nbCompo,0);
5054       if(w[1]>=w[0])
5055         {
5056           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5057             {
5058               if(j>=0 && j<nbOfTuples)
5059                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5060               else
5061                 {
5062                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5063                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5064                 }
5065             }
5066         }
5067       else
5068         {
5069           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5070           throw INTERP_KERNEL::Exception(oss.str().c_str());
5071         }
5072     }
5073   ret->copyStringInfoFrom(*this);
5074   return ret.retn();
5075 }
5076
5077 /*!
5078  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5079  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5080  * offsetA2</em> and (2)
5081  * the number of component in the result array is same as that of each of given arrays.
5082  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5083  * Info on components is copied from the first of the given arrays. Number of components
5084  * in the given arrays must be the same.
5085  *  \param [in] a1 - an array to include in the result array.
5086  *  \param [in] a2 - another array to include in the result array.
5087  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
5088  *  \return DataArrayInt * - the new instance of DataArrayInt.
5089  *          The caller is to delete this result array using decrRef() as it is no more
5090  *          needed.
5091  *  \throw If either \a a1 or \a a2 is NULL.
5092  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5093  */
5094 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5095 {
5096   if(!a1 || !a2)
5097     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5098   std::size_t nbOfComp(a1->getNumberOfComponents());
5099   if(nbOfComp!=a2->getNumberOfComponents())
5100     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5101   std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5102   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5103   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5104   int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5105   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5106   ret->copyStringInfoFrom(*a1);
5107   return ret.retn();
5108 }
5109
5110 /*!
5111  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5112  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5113  * the number of component in the result array is same as that of each of given arrays.
5114  * Info on components is copied from the first of the given arrays. Number of components
5115  * in the given arrays must be  the same.
5116  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5117  * not the object itself.
5118  *  \param [in] arr - a sequence of arrays to include in the result array.
5119  *  \return DataArrayInt * - the new instance of DataArrayInt.
5120  *          The caller is to delete this result array using decrRef() as it is no more
5121  *          needed.
5122  *  \throw If all arrays within \a arr are NULL.
5123  *  \throw If getNumberOfComponents() of arrays within \a arr.
5124  */
5125 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5126 {
5127   std::vector<const DataArrayInt *> a;
5128   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5129     if(*it4)
5130       a.push_back(*it4);
5131   if(a.empty())
5132     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5133   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5134   std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5135   for(int i=1;it!=a.end();it++,i++)
5136     {
5137       if((*it)->getNumberOfComponents()!=nbOfComp)
5138         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5139       nbt+=(*it)->getNumberOfTuples();
5140     }
5141   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5142   ret->alloc(nbt,nbOfComp);
5143   int *pt=ret->getPointer();
5144   for(it=a.begin();it!=a.end();it++)
5145     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5146   ret->copyStringInfoFrom(*(a[0]));
5147   return ret.retn();
5148 }
5149
5150 /*!
5151  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5152  * A packed index array is an allocated array with one component, and at least one tuple. The first element
5153  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5154  * 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.
5155  * 
5156  * \return DataArrayInt * - a new object to be managed by the caller.
5157  */
5158 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5159 {
5160   int retSz=1;
5161   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5162     {
5163       if(*it4)
5164         {
5165           (*it4)->checkAllocated();
5166           if((*it4)->getNumberOfComponents()!=1)
5167             {
5168               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5169               throw INTERP_KERNEL::Exception(oss.str().c_str());
5170             }
5171           int nbTupl=(*it4)->getNumberOfTuples();
5172           if(nbTupl<1)
5173             {
5174               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5175               throw INTERP_KERNEL::Exception(oss.str().c_str());
5176             }
5177           if((*it4)->front()!=0)
5178             {
5179               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5180               throw INTERP_KERNEL::Exception(oss.str().c_str());
5181             }
5182           retSz+=nbTupl-1;
5183         }
5184       else
5185         {
5186           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5187           throw INTERP_KERNEL::Exception(oss.str().c_str());
5188         }
5189     }
5190   if(arrs.empty())
5191     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5192   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5193   ret->alloc(retSz,1);
5194   int *pt=ret->getPointer(); *pt++=0;
5195   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5196     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5197   ret->copyStringInfoFrom(*(arrs[0]));
5198   return ret.retn();
5199 }
5200
5201 /*!
5202  * Returns in a single walk in \a this the min value and the max value in \a this.
5203  * \a this is expected to be single component array.
5204  *
5205  * \param [out] minValue - the min value in \a this.
5206  * \param [out] maxValue - the max value in \a this.
5207  *
5208  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5209  */
5210 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5211 {
5212   checkAllocated();
5213   if(getNumberOfComponents()!=1)
5214     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5215   int nbTuples(getNumberOfTuples());
5216   const int *pt(begin());
5217   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5218   for(int i=0;i<nbTuples;i++,pt++)
5219     {
5220       if(*pt<minValue)
5221         minValue=*pt;
5222       if(*pt>maxValue)
5223         maxValue=*pt;
5224     }
5225 }
5226
5227 /*!
5228  * Modify all elements of \a this array, so that
5229  * an element _x_ becomes \f$ numerator / x \f$.
5230  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5231  *           array, all elements processed before detection of the zero element remain
5232  *           modified.
5233  *  \param [in] numerator - the numerator used to modify array elements.
5234  *  \throw If \a this is not allocated.
5235  *  \throw If there is an element equal to 0 in \a this array.
5236  */
5237 void DataArrayInt::applyInv(int numerator)
5238 {
5239   checkAllocated();
5240   int *ptr=getPointer();
5241   std::size_t nbOfElems=getNbOfElems();
5242   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5243     {
5244       if(*ptr!=0)
5245         {
5246           *ptr=numerator/(*ptr);
5247         }
5248       else
5249         {
5250           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5251           oss << " !";
5252           throw INTERP_KERNEL::Exception(oss.str().c_str());
5253         }
5254     }
5255   declareAsNew();
5256 }
5257
5258 /*!
5259  * Modify all elements of \a this array, so that
5260  * an element _x_ becomes \f$ x / val \f$.
5261  *  \param [in] val - the denominator used to modify array elements.
5262  *  \throw If \a this is not allocated.
5263  *  \throw If \a val == 0.
5264  */
5265 void DataArrayInt::applyDivideBy(int val)
5266 {
5267   if(val==0)
5268     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5269   checkAllocated();
5270   int *ptr=getPointer();
5271   std::size_t nbOfElems=getNbOfElems();
5272   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5273   declareAsNew();
5274 }
5275
5276 /*!
5277  * Modify all elements of \a this array, so that
5278  * an element _x_ becomes  <em> x % val </em>.
5279  *  \param [in] val - the divisor used to modify array elements.
5280  *  \throw If \a this is not allocated.
5281  *  \throw If \a val <= 0.
5282  */
5283 void DataArrayInt::applyModulus(int val)
5284 {
5285   if(val<=0)
5286     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5287   checkAllocated();
5288   int *ptr=getPointer();
5289   std::size_t nbOfElems=getNbOfElems();
5290   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5291   declareAsNew();
5292 }
5293
5294 /*!
5295  * This method works only on data array with one component.
5296  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5297  * this[*id] in [\b vmin,\b vmax)
5298  * 
5299  * \param [in] vmin begin of range. This value is included in range (included).
5300  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5301  * \return a newly allocated data array that the caller should deal with.
5302  *
5303  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5304  */
5305 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5306 {
5307   InRange<int> ir(vmin,vmax);
5308   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5309   return ret.retn();
5310 }
5311
5312 /*!
5313  * This method works only on data array with one component.
5314  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5315  * this[*id] \b not in [\b vmin,\b vmax)
5316  * 
5317  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5318  * \param [in] vmax end of range. This value is included in range (included).
5319  * \return a newly allocated data array that the caller should deal with.
5320  * 
5321  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5322  */
5323 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5324 {
5325   NotInRange<int> nir(vmin,vmax);
5326   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5327   return ret.retn();
5328 }
5329
5330 /*!
5331  * This method works only on data array with one component.
5332  * 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.
5333  * 
5334  * \param [in] vmin begin of range. This value is included in range (included).
5335  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5336  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5337 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5338 {
5339   checkAllocated();
5340   if(getNumberOfComponents()!=1)
5341     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5342   int nbOfTuples=getNumberOfTuples();
5343   bool ret=true;
5344   const int *cptr=getConstPointer();
5345   for(int i=0;i<nbOfTuples;i++,cptr++)
5346     {
5347       if(*cptr>=vmin && *cptr<vmax)
5348         { ret=ret && *cptr==i; }
5349       else
5350         {
5351           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5352           throw INTERP_KERNEL::Exception(oss.str().c_str());
5353         }
5354     }
5355   return ret;
5356 }
5357
5358 /*!
5359  * Modify all elements of \a this array, so that
5360  * an element _x_ becomes <em> val % x </em>.
5361  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
5362  *           array, all elements processed before detection of the zero element remain
5363  *           modified.
5364  *  \param [in] val - the divident used to modify array elements.
5365  *  \throw If \a this is not allocated.
5366  *  \throw If there is an element equal to or less than 0 in \a this array.
5367  */
5368 void DataArrayInt::applyRModulus(int val)
5369 {
5370   checkAllocated();
5371   int *ptr=getPointer();
5372   std::size_t nbOfElems=getNbOfElems();
5373   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5374     {
5375       if(*ptr>0)
5376         {
5377           *ptr=val%(*ptr);
5378         }
5379       else
5380         {
5381           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5382           oss << " !";
5383           throw INTERP_KERNEL::Exception(oss.str().c_str());
5384         }
5385     }
5386   declareAsNew();
5387 }
5388
5389 /*!
5390  * Modify all elements of \a this array, so that
5391  * an element _x_ becomes <em> val ^ x </em>.
5392  *  \param [in] val - the value used to apply pow on all array elements.
5393  *  \throw If \a this is not allocated.
5394  *  \throw If \a val < 0.
5395  */
5396 void DataArrayInt::applyPow(int val)
5397 {
5398   checkAllocated();
5399   if(val<0)
5400     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5401   int *ptr=getPointer();
5402   std::size_t nbOfElems=getNbOfElems();
5403   if(val==0)
5404     {
5405       std::fill(ptr,ptr+nbOfElems,1);
5406       return ;
5407     }
5408   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5409     {
5410       int tmp=1;
5411       for(int j=0;j<val;j++)
5412         tmp*=*ptr;
5413       *ptr=tmp;
5414     }
5415   declareAsNew();
5416 }
5417
5418 /*!
5419  * Modify all elements of \a this array, so that
5420  * an element _x_ becomes \f$ val ^ x \f$.
5421  *  \param [in] val - the value used to apply pow on all array elements.
5422  *  \throw If \a this is not allocated.
5423  *  \throw If there is an element < 0 in \a this array.
5424  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5425  *           array, all elements processed before detection of the zero element remain
5426  *           modified.
5427  */
5428 void DataArrayInt::applyRPow(int val)
5429 {
5430   checkAllocated();
5431   int *ptr=getPointer();
5432   std::size_t nbOfElems=getNbOfElems();
5433   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5434     {
5435       if(*ptr>=0)
5436         {
5437           int tmp=1;
5438           for(int j=0;j<*ptr;j++)
5439             tmp*=val;
5440           *ptr=tmp;
5441         }
5442       else
5443         {
5444           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5445           oss << " !";
5446           throw INTERP_KERNEL::Exception(oss.str().c_str());
5447         }
5448     }
5449   declareAsNew();
5450 }
5451
5452 /*!
5453  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5454  * The i-th item of the result array is an ID of a set of elements belonging to a
5455  * unique set of groups, which the i-th element is a part of. This set of elements
5456  * belonging to a unique set of groups is called \a family, so the result array contains
5457  * IDs of families each element belongs to.
5458  *
5459  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5460  * then there are 3 families:
5461  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5462  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5463  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5464  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5465  * stands for the element #3 which is in none of groups.
5466  *
5467  *  \param [in] groups - sequence of groups of element IDs.
5468  *  \param [in] newNb - total number of elements; it must be more than max ID of element
5469  *         in \a groups.
5470  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5471  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5472  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
5473  *         delete this array using decrRef() as it is no more needed.
5474  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5475  */
5476 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5477 {
5478   std::vector<const DataArrayInt *> groups2;
5479   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5480     if(*it4)
5481       groups2.push_back(*it4);
5482   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5483   ret->alloc(newNb,1);
5484   int *retPtr=ret->getPointer();
5485   std::fill(retPtr,retPtr+newNb,0);
5486   int fid=1;
5487   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5488     {
5489       const int *ptr=(*iter)->getConstPointer();
5490       std::size_t nbOfElem=(*iter)->getNbOfElems();
5491       int sfid=fid;
5492       for(int j=0;j<sfid;j++)
5493         {
5494           bool found=false;
5495           for(std::size_t i=0;i<nbOfElem;i++)
5496             {
5497               if(ptr[i]>=0 && ptr[i]<newNb)
5498                 {
5499                   if(retPtr[ptr[i]]==j)
5500                     {
5501                       retPtr[ptr[i]]=fid;
5502                       found=true;
5503                     }
5504                 }
5505               else
5506                 {
5507                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5508                   oss << ") !";
5509                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5510                 }
5511             }
5512           if(found)
5513             fid++;
5514         }
5515     }
5516   fidsOfGroups.clear();
5517   fidsOfGroups.resize(groups2.size());
5518   int grId=0;
5519   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5520     {
5521       std::set<int> tmp;
5522       const int *ptr=(*iter)->getConstPointer();
5523       std::size_t nbOfElem=(*iter)->getNbOfElems();
5524       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5525         tmp.insert(retPtr[*p]);
5526       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5527     }
5528   return ret.retn();
5529 }
5530
5531 /*!
5532  * Returns a new DataArrayInt which contains all elements of given one-dimensional
5533  * arrays. The result array does not contain any duplicates and its values
5534  * are sorted in ascending order.
5535  *  \param [in] arr - sequence of DataArrayInt's to unite.
5536  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5537  *         array using decrRef() as it is no more needed.
5538  *  \throw If any \a arr[i] is not allocated.
5539  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5540  */
5541 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5542 {
5543   std::vector<const DataArrayInt *> a;
5544   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5545     if(*it4)
5546       a.push_back(*it4);
5547   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5548     {
5549       (*it)->checkAllocated();
5550       if((*it)->getNumberOfComponents()!=1)
5551         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5552     }
5553   //
5554   std::set<int> r;
5555   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5556     {
5557       const int *pt=(*it)->getConstPointer();
5558       int nbOfTuples=(*it)->getNumberOfTuples();
5559       r.insert(pt,pt+nbOfTuples);
5560     }
5561   DataArrayInt *ret=DataArrayInt::New();
5562   ret->alloc((int)r.size(),1);
5563   std::copy(r.begin(),r.end(),ret->getPointer());
5564   return ret;
5565 }
5566
5567 /*!
5568  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5569  * arrays. The result array does not contain any duplicates and its values
5570  * are sorted in ascending order.
5571  *  \param [in] arr - sequence of DataArrayInt's to intersect.
5572  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5573  *         array using decrRef() as it is no more needed.
5574  *  \throw If any \a arr[i] is not allocated.
5575  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5576  */
5577 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5578 {
5579   std::vector<const DataArrayInt *> a;
5580   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5581     if(*it4)
5582       a.push_back(*it4);
5583   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5584     {
5585       (*it)->checkAllocated();
5586       if((*it)->getNumberOfComponents()!=1)
5587         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5588     }
5589   //
5590   std::set<int> r;
5591   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5592     {
5593       const int *pt=(*it)->getConstPointer();
5594       int nbOfTuples=(*it)->getNumberOfTuples();
5595       std::set<int> s1(pt,pt+nbOfTuples);
5596       if(it!=a.begin())
5597         {
5598           std::set<int> r2;
5599           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5600           r=r2;
5601         }
5602       else
5603         r=s1;
5604     }
5605   DataArrayInt *ret(DataArrayInt::New());
5606   ret->alloc((int)r.size(),1);
5607   std::copy(r.begin(),r.end(),ret->getPointer());
5608   return ret;
5609 }
5610
5611 /// @cond INTERNAL
5612 namespace MEDCouplingImpl
5613 {
5614   class OpSwitchedOn
5615   {
5616   public:
5617     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5618     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5619   private:
5620     int *_pt;
5621     int _cnt;
5622   };
5623
5624   class OpSwitchedOff
5625   {
5626   public:
5627     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5628     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5629   private:
5630     int *_pt;
5631     int _cnt;
5632   };
5633 }
5634 /// @endcond
5635
5636 /*!
5637  * This method returns the list of ids in ascending mode so that v[id]==true.
5638  */
5639 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5640 {
5641   int sz((int)std::count(v.begin(),v.end(),true));
5642   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5643   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5644   return ret.retn();
5645 }
5646
5647 /*!
5648  * This method returns the list of ids in ascending mode so that v[id]==false.
5649  */
5650 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5651 {
5652   int sz((int)std::count(v.begin(),v.end(),false));
5653   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5654   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5655   return ret.retn();
5656 }
5657
5658 /*!
5659  * This method allows to put a vector of vector of integer into a more compact data structure (skyline). 
5660  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5661  *
5662  * \param [in] v the input data structure to be translate into skyline format.
5663  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5664  * \param [out] dataIndex the second element of the skyline format.
5665  */
5666 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5667 {
5668   int sz((int)v.size());
5669   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5670   ret1->alloc(sz+1,1);
5671   int *pt(ret1->getPointer()); *pt=0;
5672   for(int i=0;i<sz;i++,pt++)
5673     pt[1]=pt[0]+(int)v[i].size();
5674   ret0->alloc(ret1->back(),1);
5675   pt=ret0->getPointer();
5676   for(int i=0;i<sz;i++)
5677     pt=std::copy(v[i].begin(),v[i].end(),pt);
5678   data=ret0.retn(); dataIndex=ret1.retn();
5679 }
5680
5681 /*!
5682  * Returns a new DataArrayInt which contains a complement of elements of \a this
5683  * one-dimensional array. I.e. the result array contains all elements from the range [0,
5684  * \a nbOfElement) not present in \a this array.
5685  *  \param [in] nbOfElement - maximal size of the result array.
5686  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5687  *         array using decrRef() as it is no more needed.
5688  *  \throw If \a this is not allocated.
5689  *  \throw If \a this->getNumberOfComponents() != 1.
5690  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5691  *         nbOfElement ).
5692  */
5693 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5694 {
5695   checkAllocated();
5696   if(getNumberOfComponents()!=1)
5697     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5698   std::vector<bool> tmp(nbOfElement);
5699   const int *pt=getConstPointer();
5700   int nbOfTuples=getNumberOfTuples();
5701   for(const int *w=pt;w!=pt+nbOfTuples;w++)
5702     if(*w>=0 && *w<nbOfElement)
5703       tmp[*w]=true;
5704     else
5705       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5706   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5707   DataArrayInt *ret=DataArrayInt::New();
5708   ret->alloc(nbOfRetVal,1);
5709   int j=0;
5710   int *retPtr=ret->getPointer();
5711   for(int i=0;i<nbOfElement;i++)
5712     if(!tmp[i])
5713       retPtr[j++]=i;
5714   return ret;
5715 }
5716
5717 /*!
5718  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5719  * from an \a other one-dimensional array.
5720  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
5721  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5722  *         caller is to delete this array using decrRef() as it is no more needed.
5723  *  \throw If \a other is NULL.
5724  *  \throw If \a other is not allocated.
5725  *  \throw If \a other->getNumberOfComponents() != 1.
5726  *  \throw If \a this is not allocated.
5727  *  \throw If \a this->getNumberOfComponents() != 1.
5728  *  \sa DataArrayInt::buildSubstractionOptimized()
5729  */
5730 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5731 {
5732   if(!other)
5733     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5734   checkAllocated();
5735   other->checkAllocated();
5736   if(getNumberOfComponents()!=1)
5737     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5738   if(other->getNumberOfComponents()!=1)
5739     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5740   const int *pt=getConstPointer();
5741   int nbOfTuples=getNumberOfTuples();
5742   std::set<int> s1(pt,pt+nbOfTuples);
5743   pt=other->getConstPointer();
5744   nbOfTuples=other->getNumberOfTuples();
5745   std::set<int> s2(pt,pt+nbOfTuples);
5746   std::vector<int> r;
5747   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5748   DataArrayInt *ret=DataArrayInt::New();
5749   ret->alloc((int)r.size(),1);
5750   std::copy(r.begin(),r.end(),ret->getPointer());
5751   return ret;
5752 }
5753
5754 /*!
5755  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5756  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5757  * 
5758  * \param [in] other an array with one component and expected to be sorted ascendingly.
5759  * \ret list of ids in \a this but not in \a other.
5760  * \sa DataArrayInt::buildSubstraction
5761  */
5762 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5763 {
5764   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5765   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5766   checkAllocated(); other->checkAllocated();
5767   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5768   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5769   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5770   const int *work1(pt1Bg),*work2(pt2Bg);
5771   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5772   for(;work1!=pt1End;work1++)
5773     {
5774       if(work2!=pt2End && *work1==*work2)
5775         work2++;
5776       else
5777         ret->pushBackSilent(*work1);
5778     }
5779   return ret.retn();
5780 }
5781
5782
5783 /*!
5784  * Returns a new DataArrayInt which contains all elements of \a this and a given
5785  * one-dimensional arrays. The result array does not contain any duplicates
5786  * and its values are sorted in ascending order.
5787  *  \param [in] other - an array to unite with \a this one.
5788  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5789  *         array using decrRef() as it is no more needed.
5790  *  \throw If \a this or \a other is not allocated.
5791  *  \throw If \a this->getNumberOfComponents() != 1.
5792  *  \throw If \a other->getNumberOfComponents() != 1.
5793  */
5794 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5795 {
5796   std::vector<const DataArrayInt *>arrs(2);
5797   arrs[0]=this; arrs[1]=other;
5798   return BuildUnion(arrs);
5799 }
5800
5801
5802 /*!
5803  * Returns a new DataArrayInt which contains elements present in both \a this and a given
5804  * one-dimensional arrays. The result array does not contain any duplicates
5805  * and its values are sorted in ascending order.
5806  *  \param [in] other - an array to intersect with \a this one.
5807  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5808  *         array using decrRef() as it is no more needed.
5809  *  \throw If \a this or \a other is not allocated.
5810  *  \throw If \a this->getNumberOfComponents() != 1.
5811  *  \throw If \a other->getNumberOfComponents() != 1.
5812  */
5813 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5814 {
5815   std::vector<const DataArrayInt *>arrs(2);
5816   arrs[0]=this; arrs[1]=other;
5817   return BuildIntersection(arrs);
5818 }
5819
5820 /*!
5821  * This method can be applied on allocated with one component DataArrayInt instance.
5822  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5823  * 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]
5824  * 
5825  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5826  * \throw if \a this is not allocated or if \a this has not exactly one component.
5827  * \sa DataArrayInt::buildUniqueNotSorted
5828  */
5829 DataArrayInt *DataArrayInt::buildUnique() const
5830 {
5831   checkAllocated();
5832   if(getNumberOfComponents()!=1)
5833     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5834   int nbOfTuples=getNumberOfTuples();
5835   MCAuto<DataArrayInt> tmp=deepCopy();
5836   int *data=tmp->getPointer();
5837   int *last=std::unique(data,data+nbOfTuples);
5838   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5839   ret->alloc(std::distance(data,last),1);
5840   std::copy(data,last,ret->getPointer());
5841   return ret.retn();
5842 }
5843
5844 /*!
5845  * This method can be applied on allocated with one component DataArrayInt instance.
5846  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5847  *
5848  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5849  *
5850  * \throw if \a this is not allocated or if \a this has not exactly one component.
5851  *
5852  * \sa DataArrayInt::buildUnique
5853  */
5854 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5855 {
5856   checkAllocated();
5857     if(getNumberOfComponents()!=1)
5858       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5859   int minVal,maxVal;
5860   getMinMaxValues(minVal,maxVal);
5861   std::vector<bool> b(maxVal-minVal+1,false);
5862   const int *ptBg(begin()),*endBg(end());
5863   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5864   for(const int *pt=ptBg;pt!=endBg;pt++)
5865     {
5866       if(!b[*pt-minVal])
5867         {
5868           ret->pushBackSilent(*pt);
5869           b[*pt-minVal]=true;
5870         }
5871     }
5872   ret->copyStringInfoFrom(*this);
5873   return ret.retn();
5874 }
5875
5876 /*!
5877  * Returns a new DataArrayInt which contains size of every of groups described by \a this
5878  * "index" array. Such "index" array is returned for example by 
5879  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5880  * "MEDCouplingUMesh::buildDescendingConnectivity" and
5881  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5882  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5883  * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5884  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5885  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5886  *          The caller is to delete this array using decrRef() as it is no more needed. 
5887  *  \throw If \a this is not allocated.
5888  *  \throw If \a this->getNumberOfComponents() != 1.
5889  *  \throw If \a this->getNumberOfTuples() < 2.
5890  *
5891  *  \b Example: <br> 
5892  *         - this contains [1,3,6,7,7,9,15]
5893  *         - result array contains [2,3,1,0,2,6],
5894  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5895  *
5896  * \sa DataArrayInt::computeOffsetsFull
5897  */
5898 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5899 {
5900   checkAllocated();
5901   if(getNumberOfComponents()!=1)
5902     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5903   int nbOfTuples=getNumberOfTuples();
5904   if(nbOfTuples<2)
5905     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5906   const int *ptr=getConstPointer();
5907   DataArrayInt *ret=DataArrayInt::New();
5908   ret->alloc(nbOfTuples-1,1);
5909   int *out=ret->getPointer();
5910   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5911   return ret;
5912 }
5913
5914 /*!
5915  * Modifies \a this one-dimensional array so that value of each element \a x
5916  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5917  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5918  * and components remains the same.<br>
5919  * This method is useful for allToAllV in MPI with contiguous policy. This method
5920  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5921  * this one.
5922  *  \throw If \a this is not allocated.
5923  *  \throw If \a this->getNumberOfComponents() != 1.
5924  *
5925  *  \b Example: <br>
5926  *          - Before \a this contains [3,5,1,2,0,8]
5927  *          - After \a this contains  [0,3,8,9,11,11]<br>
5928  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
5929  *          array is retained and thus there is no space to store the last element.
5930  */
5931 void DataArrayInt::computeOffsets()
5932 {
5933   checkAllocated();
5934   if(getNumberOfComponents()!=1)
5935     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5936   int nbOfTuples=getNumberOfTuples();
5937   if(nbOfTuples==0)
5938     return ;
5939   int *work=getPointer();
5940   int tmp=work[0];
5941   work[0]=0;
5942   for(int i=1;i<nbOfTuples;i++)
5943     {
5944       int tmp2=work[i];
5945       work[i]=work[i-1]+tmp;
5946       tmp=tmp2;
5947     }
5948   declareAsNew();
5949 }
5950
5951
5952 /*!
5953  * Modifies \a this one-dimensional array so that value of each element \a x
5954  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5955  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5956  * components remains the same and number of tuples is inceamented by one.<br>
5957  * This method is useful for allToAllV in MPI with contiguous policy. This method
5958  * differs from computeOffsets() in that the number of tuples is changed by this one.
5959  * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5960  *  \throw If \a this is not allocated.
5961  *  \throw If \a this->getNumberOfComponents() != 1.
5962  *
5963  *  \b Example: <br>
5964  *          - Before \a this contains [3,5,1,2,0,8]
5965  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
5966  * \sa DataArrayInt::deltaShiftIndex
5967  */
5968 void DataArrayInt::computeOffsetsFull()
5969 {
5970   checkAllocated();
5971   if(getNumberOfComponents()!=1)
5972     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5973   int nbOfTuples=getNumberOfTuples();
5974   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5975   const int *work=getConstPointer();
5976   ret[0]=0;
5977   for(int i=0;i<nbOfTuples;i++)
5978     ret[i+1]=work[i]+ret[i];
5979   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
5980   declareAsNew();
5981 }
5982
5983 /*!
5984  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5985  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5986  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5987  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5988  * filling completely one of the ranges in \a this.
5989  *
5990  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5991  * \param [out] rangeIdsFetched the range ids fetched
5992  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5993  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
5994  *
5995  * \sa DataArrayInt::computeOffsetsFull
5996  *
5997  *  \b Example: <br>
5998  *          - \a this : [0,3,7,9,15,18]
5999  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
6000  *          - \a rangeIdsFetched result array: [0,2,4]
6001  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6002  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6003  * <br>
6004  */
6005 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6006 {
6007   if(!listOfIds)
6008     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6009   listOfIds->checkAllocated(); checkAllocated();
6010   if(listOfIds->getNumberOfComponents()!=1)
6011     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6012   if(getNumberOfComponents()!=1)
6013     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6014   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6015   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6016   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6017   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6018   while(tupPtr!=tupEnd && offPtr!=offEnd)
6019     {
6020       if(*tupPtr==*offPtr)
6021         {
6022           int i=offPtr[0];
6023           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6024           if(i==offPtr[1])
6025             {
6026               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6027               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6028               offPtr++;
6029             }
6030         }
6031       else
6032         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6033     }
6034   rangeIdsFetched=ret0.retn();
6035   idsInInputListThatFetch=ret1.retn();
6036 }
6037
6038 /*!
6039  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6040  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6041  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6042  * beginning within the "iota" array. And \a this is a one-dimensional array
6043  * considered as a selector of groups described by \a offsets to include into the result array.
6044  *  \throw If \a offsets is NULL.
6045  *  \throw If \a offsets is not allocated.
6046  *  \throw If \a offsets->getNumberOfComponents() != 1.
6047  *  \throw If \a offsets is not monotonically increasing.
6048  *  \throw If \a this is not allocated.
6049  *  \throw If \a this->getNumberOfComponents() != 1.
6050  *  \throw If any element of \a this is not a valid index for \a offsets array.
6051  *
6052  *  \b Example: <br>
6053  *          - \a this: [0,2,3]
6054  *          - \a offsets: [0,3,6,10,14,20]
6055  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6056  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6057  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
6058  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
6059  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6060  */
6061 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6062 {
6063   if(!offsets)
6064     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6065   checkAllocated();
6066   if(getNumberOfComponents()!=1)
6067     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6068   offsets->checkAllocated();
6069   if(offsets->getNumberOfComponents()!=1)
6070     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6071   int othNbTuples=offsets->getNumberOfTuples()-1;
6072   int nbOfTuples=getNumberOfTuples();
6073   int retNbOftuples=0;
6074   const int *work=getConstPointer();
6075   const int *offPtr=offsets->getConstPointer();
6076   for(int i=0;i<nbOfTuples;i++)
6077     {
6078       int val=work[i];
6079       if(val>=0 && val<othNbTuples)
6080         {
6081           int delta=offPtr[val+1]-offPtr[val];
6082           if(delta>=0)
6083             retNbOftuples+=delta;
6084           else
6085             {
6086               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6087               throw INTERP_KERNEL::Exception(oss.str().c_str());
6088             }
6089         }
6090       else
6091         {
6092           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6093           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6094           throw INTERP_KERNEL::Exception(oss.str().c_str());
6095         }
6096     }
6097   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6098   ret->alloc(retNbOftuples,1);
6099   int *retPtr=ret->getPointer();
6100   for(int i=0;i<nbOfTuples;i++)
6101     {
6102       int val=work[i];
6103       int start=offPtr[val];
6104       int off=offPtr[val+1]-start;
6105       for(int j=0;j<off;j++,retPtr++)
6106         *retPtr=start+j;
6107     }
6108   return ret.retn();
6109 }
6110
6111 /*!
6112  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
6113  * scaled array (monotonically increasing).
6114 from that of \a this and \a
6115  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6116  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6117  * beginning within the "iota" array. And \a this is a one-dimensional array
6118  * considered as a selector of groups described by \a offsets to include into the result array.
6119  *  \throw If \a  is NULL.
6120  *  \throw If \a this is not allocated.
6121  *  \throw If \a this->getNumberOfComponents() != 1.
6122  *  \throw If \a this->getNumberOfTuples() == 0.
6123  *  \throw If \a this is not monotonically increasing.
6124  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6125  *
6126  *  \b Example: <br>
6127  *          - \a bg , \a stop and \a step : (0,5,2)
6128  *          - \a this: [0,3,6,10,14,20]
6129  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6130  */
6131 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6132 {
6133   if(!isAllocated())
6134     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6135   if(getNumberOfComponents()!=1)
6136     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6137   int nbOfTuples(getNumberOfTuples());
6138   if(nbOfTuples==0)
6139     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6140   const int *ids(begin());
6141   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6142   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6143     {
6144       if(pos>=0 && pos<nbOfTuples-1)
6145         {
6146           int delta(ids[pos+1]-ids[pos]);
6147           sz+=delta;
6148           if(delta<0)
6149             {
6150               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6151               throw INTERP_KERNEL::Exception(oss.str().c_str());
6152             }          
6153         }
6154       else
6155         {
6156           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
6157           throw INTERP_KERNEL::Exception(oss.str().c_str());
6158         }
6159     }
6160   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6161   int *retPtr(ret->getPointer());
6162   pos=bg;
6163   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6164     {
6165       int delta(ids[pos+1]-ids[pos]);
6166       for(int j=0;j<delta;j++,retPtr++)
6167         *retPtr=pos;
6168     }
6169   return ret.retn();
6170 }
6171
6172 /*!
6173  * 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.
6174  * 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
6175  * in tuple **i** of returned DataArrayInt.
6176  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6177  *
6178  * 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)]
6179  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6180  * 
6181  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6182  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6183  * \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
6184  *        is thrown if no ranges in \a ranges contains value in \a this.
6185  * 
6186  * \sa DataArrayInt::findIdInRangeForEachTuple
6187  */
6188 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6189 {
6190   if(!ranges)
6191     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6192   if(ranges->getNumberOfComponents()!=2)
6193     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6194   checkAllocated();
6195   if(getNumberOfComponents()!=1)
6196     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6197   int nbTuples=getNumberOfTuples();
6198   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6199   int nbOfRanges=ranges->getNumberOfTuples();
6200   const int *rangesPtr=ranges->getConstPointer();
6201   int *retPtr=ret->getPointer();
6202   const int *inPtr=getConstPointer();
6203   for(int i=0;i<nbTuples;i++,retPtr++)
6204     {
6205       int val=inPtr[i];
6206       bool found=false;
6207       for(int j=0;j<nbOfRanges && !found;j++)
6208         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6209           { *retPtr=j; found=true; }
6210       if(found)
6211         continue;
6212       else
6213         {
6214           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6215           throw INTERP_KERNEL::Exception(oss.str().c_str());
6216         }
6217     }
6218   return ret.retn();
6219 }
6220
6221 /*!
6222  * 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.
6223  * 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
6224  * in tuple **i** of returned DataArrayInt.
6225  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6226  *
6227  * 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)]
6228  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6229  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6230  * 
6231  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6232  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6233  * \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
6234  *        is thrown if no ranges in \a ranges contains value in \a this.
6235  * \sa DataArrayInt::findRangeIdForEachTuple
6236  */
6237 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6238 {
6239   if(!ranges)
6240     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6241   if(ranges->getNumberOfComponents()!=2)
6242     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6243   checkAllocated();
6244   if(getNumberOfComponents()!=1)
6245     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6246   int nbTuples=getNumberOfTuples();
6247   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6248   int nbOfRanges=ranges->getNumberOfTuples();
6249   const int *rangesPtr=ranges->getConstPointer();
6250   int *retPtr=ret->getPointer();
6251   const int *inPtr=getConstPointer();
6252   for(int i=0;i<nbTuples;i++,retPtr++)
6253     {
6254       int val=inPtr[i];
6255       bool found=false;
6256       for(int j=0;j<nbOfRanges && !found;j++)
6257         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6258           { *retPtr=val-rangesPtr[2*j]; found=true; }
6259       if(found)
6260         continue;
6261       else
6262         {
6263           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6264           throw INTERP_KERNEL::Exception(oss.str().c_str());
6265         }
6266     }
6267   return ret.retn();
6268 }
6269
6270 /*!
6271  * \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).
6272  * 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).
6273  * 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 !
6274  * If this method has correctly worked, \a this will be able to be considered as a linked list.
6275  * This method does nothing if number of tuples is lower of equal to 1.
6276  *
6277  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6278  *
6279  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6280  */
6281 void DataArrayInt::sortEachPairToMakeALinkedList()
6282 {
6283   checkAllocated();
6284   if(getNumberOfComponents()!=2)
6285     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6286   int nbOfTuples(getNumberOfTuples());
6287   if(nbOfTuples<=1)
6288     return ;
6289   int *conn(getPointer());
6290   for(int i=1;i<nbOfTuples;i++,conn+=2)
6291     {
6292       if(i>1)
6293         {
6294           if(conn[2]==conn[3])
6295             {
6296               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6297               throw INTERP_KERNEL::Exception(oss.str().c_str());
6298             }
6299           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6300             std::swap(conn[2],conn[3]);
6301           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6302           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6303             {
6304               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6305               throw INTERP_KERNEL::Exception(oss.str().c_str());
6306             }
6307         }
6308       else
6309         {
6310           if(conn[0]==conn[1] || conn[2]==conn[3])
6311             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6312           int tmp[4];
6313           std::set<int> s;
6314           s.insert(conn,conn+4);
6315           if(s.size()!=3)
6316             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6317           if(std::count(conn,conn+4,conn[0])==2)
6318             {
6319               tmp[0]=conn[1];
6320               tmp[1]=conn[0];
6321               tmp[2]=conn[0];
6322               if(conn[2]==conn[0])
6323                 { tmp[3]=conn[3]; }
6324               else
6325                 { tmp[3]=conn[2];}
6326               std::copy(tmp,tmp+4,conn);
6327             }
6328           else
6329             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6330               if(conn[1]==conn[3])
6331                 std::swap(conn[2],conn[3]);
6332             }
6333         }
6334     }
6335 }
6336
6337 /*!
6338  * \a this is expected to be a correctly linked list of pairs.
6339  * 
6340  * \sa DataArrayInt::sortEachPairToMakeALinkedList
6341  */
6342 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6343 {
6344   checkAllocated();
6345   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6346   int nbTuples(getNumberOfTuples());
6347   if(nbTuples<1)
6348     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6349   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6350   const int *thisPtr(begin());
6351   int *retPtr(ret->getPointer());
6352   retPtr[0]=thisPtr[0];
6353   for(int i=0;i<nbTuples;i++)
6354     {
6355       retPtr[i+1]=thisPtr[2*i+1];
6356       if(i<nbTuples-1)
6357         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6358           {
6359             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 ?";
6360             throw INTERP_KERNEL::Exception(oss.str());
6361           }
6362     }
6363   return ret;
6364 }
6365
6366 /*!
6367  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6368  * But the number of components can be different from one.
6369  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6370  */
6371 DataArrayInt *DataArrayInt::getDifferentValues() const
6372 {
6373   checkAllocated();
6374   std::set<int> ret;
6375   ret.insert(begin(),end());
6376   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6377   std::copy(ret.begin(),ret.end(),ret2->getPointer());
6378   return ret2.retn();
6379 }
6380
6381 /*!
6382  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6383  * them it tells which tuple id have this id.
6384  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6385  * This method returns two arrays having same size.
6386  * 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.
6387  * 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]]
6388  */
6389 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6390 {
6391   checkAllocated();
6392   if(getNumberOfComponents()!=1)
6393     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6394   int id=0;
6395   std::map<int,int> m,m2,m3;
6396   for(const int *w=begin();w!=end();w++)
6397     m[*w]++;
6398   differentIds.resize(m.size());
6399   std::vector<DataArrayInt *> ret(m.size());
6400   std::vector<int *> retPtr(m.size());
6401   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6402     {
6403       m2[(*it).first]=id;
6404       ret[id]=DataArrayInt::New();
6405       ret[id]->alloc((*it).second,1);
6406       retPtr[id]=ret[id]->getPointer();
6407       differentIds[id]=(*it).first;
6408     }
6409   id=0;
6410   for(const int *w=begin();w!=end();w++,id++)
6411     {
6412       retPtr[m2[*w]][m3[*w]++]=id;
6413     }
6414   return ret;
6415 }
6416
6417 /*!
6418  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6419  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6420  *
6421  * \param [in] nbOfSlices - number of slices expected.
6422  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6423  * 
6424  * \sa DataArray::GetSlice
6425  * \throw If \a this is not allocated or not with exactly one component.
6426  * \throw If an element in \a this if < 0.
6427  */
6428 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6429 {
6430   if(!isAllocated() || getNumberOfComponents()!=1)
6431     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6432   if(nbOfSlices<=0)
6433     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6434   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6435   int sumPerSlc(sum/nbOfSlices),pos(0);
6436   const int *w(begin());
6437   std::vector< std::pair<int,int> > ret(nbOfSlices);
6438   for(int i=0;i<nbOfSlices;i++)
6439     {
6440       std::pair<int,int> p(pos,-1);
6441       int locSum(0);
6442       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6443       if(i!=nbOfSlices-1)
6444         p.second=pos;
6445       else
6446         p.second=nbOfTuples;
6447       ret[i]=p;
6448     }
6449   return ret;
6450 }
6451
6452 /*!
6453  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6454  * valid cases.
6455  * 1.  The arrays have same number of tuples and components. Then each value of
6456  *   the result array (_a_) is a division of the corresponding values of \a a1 and
6457  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6458  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
6459  *   component. Then
6460  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6461  * 3.  The arrays have same number of components and one array, say _a2_, has one
6462  *   tuple. Then
6463  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6464  *
6465  * Info on components is copied either from the first array (in the first case) or from
6466  * the array with maximal number of elements (getNbOfElems()).
6467  *  \warning No check of division by zero is performed!
6468  *  \param [in] a1 - a dividend array.
6469  *  \param [in] a2 - a divisor array.
6470  *  \return DataArrayInt * - the new instance of DataArrayInt.
6471  *          The caller is to delete this result array using decrRef() as it is no more
6472  *          needed.
6473  *  \throw If either \a a1 or \a a2 is NULL.
6474  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6475  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6476  *         none of them has number of tuples or components equal to 1.
6477  */
6478 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6479 {
6480   if(!a1 || !a2)
6481     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6482   int nbOfTuple1=a1->getNumberOfTuples();
6483   int nbOfTuple2=a2->getNumberOfTuples();
6484   int nbOfComp1=a1->getNumberOfComponents();
6485   int nbOfComp2=a2->getNumberOfComponents();
6486   if(nbOfTuple2==nbOfTuple1)
6487     {
6488       if(nbOfComp1==nbOfComp2)
6489         {
6490           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6491           ret->alloc(nbOfTuple2,nbOfComp1);
6492           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6493           ret->copyStringInfoFrom(*a1);
6494           return ret.retn();
6495         }
6496       else if(nbOfComp2==1)
6497         {
6498           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6499           ret->alloc(nbOfTuple1,nbOfComp1);
6500           const int *a2Ptr=a2->getConstPointer();
6501           const int *a1Ptr=a1->getConstPointer();
6502           int *res=ret->getPointer();
6503           for(int i=0;i<nbOfTuple1;i++)
6504             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6505           ret->copyStringInfoFrom(*a1);
6506           return ret.retn();
6507         }
6508       else
6509         {
6510           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6511           return 0;
6512         }
6513     }
6514   else if(nbOfTuple2==1)
6515     {
6516       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6517       MCAuto<DataArrayInt> ret=DataArrayInt::New();
6518       ret->alloc(nbOfTuple1,nbOfComp1);
6519       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6520       int *pt=ret->getPointer();
6521       for(int i=0;i<nbOfTuple1;i++)
6522         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6523       ret->copyStringInfoFrom(*a1);
6524       return ret.retn();
6525     }
6526   else
6527     {
6528       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6529       return 0;
6530     }
6531 }
6532
6533 /*!
6534  * Modify \a this array so that each value becomes a modulus of division of this value by
6535  * a value of another DataArrayInt. There are 3 valid cases.
6536  * 1.  The arrays have same number of tuples and components. Then each value of
6537  *    \a this array is divided by the corresponding value of \a other one, i.e.:
6538  *   _a_ [ i, j ] %= _other_ [ i, j ].
6539  * 2.  The arrays have same number of tuples and \a other array has one component. Then
6540  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
6541  * 3.  The arrays have same number of components and \a other array has one tuple. Then
6542  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
6543  *
6544  *  \warning No check of division by zero is performed!
6545  *  \param [in] other - a divisor array.
6546  *  \throw If \a other is NULL.
6547  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6548  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6549  *         \a other has number of both tuples and components not equal to 1.
6550  */
6551 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6552 {
6553   if(!other)
6554     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6555   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6556   checkAllocated(); other->checkAllocated();
6557   int nbOfTuple=getNumberOfTuples();
6558   int nbOfTuple2=other->getNumberOfTuples();
6559   int nbOfComp=getNumberOfComponents();
6560   int nbOfComp2=other->getNumberOfComponents();
6561   if(nbOfTuple==nbOfTuple2)
6562     {
6563       if(nbOfComp==nbOfComp2)
6564         {
6565           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6566         }
6567       else if(nbOfComp2==1)
6568         {
6569           if(nbOfComp2==nbOfComp)
6570             {
6571               int *ptr=getPointer();
6572               const int *ptrc=other->getConstPointer();
6573               for(int i=0;i<nbOfTuple;i++)
6574                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6575             }
6576           else
6577             throw INTERP_KERNEL::Exception(msg);
6578         }
6579       else
6580         throw INTERP_KERNEL::Exception(msg);
6581     }
6582   else if(nbOfTuple2==1)
6583     {
6584       int *ptr=getPointer();
6585       const int *ptrc=other->getConstPointer();
6586       for(int i=0;i<nbOfTuple;i++)
6587         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6588     }
6589   else
6590     throw INTERP_KERNEL::Exception(msg);
6591   declareAsNew();
6592 }
6593
6594 /*!
6595  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6596  * valid cases.
6597  *
6598  *  \param [in] a1 - an array to pow up.
6599  *  \param [in] a2 - another array to sum up.
6600  *  \return DataArrayInt * - the new instance of DataArrayInt.
6601  *          The caller is to delete this result array using decrRef() as it is no more
6602  *          needed.
6603  *  \throw If either \a a1 or \a a2 is NULL.
6604  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6605  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6606  *  \throw If there is a negative value in \a a2.
6607  */
6608 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6609 {
6610   if(!a1 || !a2)
6611     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6612   int nbOfTuple=a1->getNumberOfTuples();
6613   int nbOfTuple2=a2->getNumberOfTuples();
6614   int nbOfComp=a1->getNumberOfComponents();
6615   int nbOfComp2=a2->getNumberOfComponents();
6616   if(nbOfTuple!=nbOfTuple2)
6617     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6618   if(nbOfComp!=1 || nbOfComp2!=1)
6619     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6620   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6621   const int *ptr1(a1->begin()),*ptr2(a2->begin());
6622   int *ptr=ret->getPointer();
6623   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6624     {
6625       if(*ptr2>=0)
6626         {
6627           int tmp=1;
6628           for(int j=0;j<*ptr2;j++)
6629             tmp*=*ptr1;
6630           *ptr=tmp;
6631         }
6632       else
6633         {
6634           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6635           throw INTERP_KERNEL::Exception(oss.str().c_str());
6636         }
6637     }
6638   return ret.retn();
6639 }
6640
6641 /*!
6642  * Apply pow on values of another DataArrayInt to values of \a this one.
6643  *
6644  *  \param [in] other - an array to pow to \a this one.
6645  *  \throw If \a other is NULL.
6646  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6647  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6648  *  \throw If there is a negative value in \a other.
6649  */
6650 void DataArrayInt::powEqual(const DataArrayInt *other)
6651 {
6652   if(!other)
6653     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6654   int nbOfTuple=getNumberOfTuples();
6655   int nbOfTuple2=other->getNumberOfTuples();
6656   int nbOfComp=getNumberOfComponents();
6657   int nbOfComp2=other->getNumberOfComponents();
6658   if(nbOfTuple!=nbOfTuple2)
6659     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6660   if(nbOfComp!=1 || nbOfComp2!=1)
6661     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6662   int *ptr=getPointer();
6663   const int *ptrc=other->begin();
6664   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6665     {
6666       if(*ptrc>=0)
6667         {
6668           int tmp=1;
6669           for(int j=0;j<*ptrc;j++)
6670             tmp*=*ptr;
6671           *ptr=tmp;
6672         }
6673       else
6674         {
6675           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6676           throw INTERP_KERNEL::Exception(oss.str().c_str());
6677         }
6678     }
6679   declareAsNew();
6680 }
6681
6682 /*!
6683  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6684  * This map, if applied to \a start array, would make it sorted. For example, if
6685  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6686  * [5,6,0,3,2,7,1,4].
6687  *  \param [in] start - pointer to the first element of the array for which the
6688  *         permutation map is computed.
6689  *  \param [in] end - pointer specifying the end of the array \a start, so that
6690  *         the last value of \a start is \a end[ -1 ].
6691  *  \return int * - the result permutation array that the caller is to delete as it is no
6692  *         more needed.
6693  *  \throw If there are equal values in the input array.
6694  */
6695 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6696 {
6697   std::size_t sz=std::distance(start,end);
6698   int *ret=(int *)malloc(sz*sizeof(int));
6699   int *work=new int[sz];
6700   std::copy(start,end,work);
6701   std::sort(work,work+sz);
6702   if(std::unique(work,work+sz)!=work+sz)
6703     {
6704       delete [] work;
6705       free(ret);
6706       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6707     }
6708   std::map<int,int> m;
6709   for(int *workPt=work;workPt!=work+sz;workPt++)
6710     m[*workPt]=(int)std::distance(work,workPt);
6711   int *iter2=ret;
6712   for(const int *iter=start;iter!=end;iter++,iter2++)
6713     *iter2=m[*iter];
6714   delete [] work;
6715   return ret;
6716 }
6717
6718 /*!
6719  * Returns a new DataArrayInt containing an arithmetic progression
6720  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
6721  * function.
6722  *  \param [in] begin - the start value of the result sequence.
6723  *  \param [in] end - limiting value, so that every value of the result array is less than
6724  *              \a end.
6725  *  \param [in] step - specifies the increment or decrement.
6726  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6727  *          array using decrRef() as it is no more needed.
6728  *  \throw If \a step == 0.
6729  *  \throw If \a end < \a begin && \a step > 0.
6730  *  \throw If \a end > \a begin && \a step < 0.
6731  */
6732 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6733 {
6734   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6735   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6736   ret->alloc(nbOfTuples,1);
6737   int *ptr=ret->getPointer();
6738   if(step>0)
6739     {
6740       for(int i=begin;i<end;i+=step,ptr++)
6741         *ptr=i;
6742     }
6743   else
6744     {
6745       for(int i=begin;i>end;i+=step,ptr++)
6746         *ptr=i;
6747     }
6748   return ret.retn();
6749 }
6750
6751 /*!
6752  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6753  * Server side.
6754  */
6755 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6756 {
6757   tinyInfo.resize(2);
6758   if(isAllocated())
6759     {
6760       tinyInfo[0]=getNumberOfTuples();
6761       tinyInfo[1]=getNumberOfComponents();
6762     }
6763   else
6764     {
6765       tinyInfo[0]=-1;
6766       tinyInfo[1]=-1;
6767     }
6768 }
6769
6770 /*!
6771  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6772  * Server side.
6773  */
6774 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6775 {
6776   if(isAllocated())
6777     {
6778       int nbOfCompo=getNumberOfComponents();
6779       tinyInfo.resize(nbOfCompo+1);
6780       tinyInfo[0]=getName();
6781       for(int i=0;i<nbOfCompo;i++)
6782         tinyInfo[i+1]=getInfoOnComponent(i);
6783     }
6784   else
6785     {
6786       tinyInfo.resize(1);
6787       tinyInfo[0]=getName();
6788     }
6789 }
6790
6791 /*!
6792  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6793  * This method returns if a feeding is needed.
6794  */
6795 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6796 {
6797   int nbOfTuple=tinyInfoI[0];
6798   int nbOfComp=tinyInfoI[1];
6799   if(nbOfTuple!=-1 || nbOfComp!=-1)
6800     {
6801       alloc(nbOfTuple,nbOfComp);
6802       return true;
6803     }
6804   return false;
6805 }
6806
6807 /*!
6808  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6809  * This method returns if a feeding is needed.
6810  */
6811 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6812 {
6813   setName(tinyInfoS[0]);
6814   if(isAllocated())
6815     {
6816       int nbOfCompo=tinyInfoI[1];
6817       for(int i=0;i<nbOfCompo;i++)
6818         setInfoOnComponent(i,tinyInfoS[i+1]);
6819     }
6820 }
6821
6822 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6823 {
6824 }
6825
6826 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6827 {
6828 }
6829
6830 std::string DataArrayIntTuple::repr() const
6831 {
6832   std::ostringstream oss; oss << "(";
6833   for(int i=0;i<_nb_of_compo-1;i++)
6834     oss << _pt[i] << ", ";
6835   oss << _pt[_nb_of_compo-1] << ")";
6836   return oss.str();
6837 }
6838
6839 int DataArrayIntTuple::intValue() const
6840 {
6841   return this->zeValue();
6842 }
6843
6844 /*!
6845  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6846  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6847  * 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
6848  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6849  */
6850 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6851 {
6852   return this->buildDA(nbOfTuples,nbOfCompo);
6853 }