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