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