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