]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDCoupling/MEDCouplingMemArray.cxx
Salome HOME
Factorization is on !
[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  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1128  * arranged in memory. If \a this array holds 2 components of 3 values:
1129  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1130  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1131  *  \warning Do not confuse this method with transpose()!
1132  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1133  *          is to delete using decrRef() as it is no more needed.
1134  *  \throw If \a this is not allocated.
1135  */
1136 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1137 {
1138   if(_mem.isNull())
1139     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1140   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1141   DataArrayDouble *ret=DataArrayDouble::New();
1142   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1143   return ret;
1144 }
1145
1146 /*!
1147  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1148  * arranged in memory. If \a this array holds 2 components of 3 values:
1149  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1150  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1151  *  \warning Do not confuse this method with transpose()!
1152  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1153  *          is to delete using decrRef() as it is no more needed.
1154  *  \throw If \a this is not allocated.
1155  */
1156 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1157 {
1158   if(_mem.isNull())
1159     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1160   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1161   DataArrayDouble *ret=DataArrayDouble::New();
1162   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1163   return ret;
1164 }
1165
1166 /*!
1167  * Appends components of another array to components of \a this one, tuple by tuple.
1168  * So that the number of tuples of \a this array remains the same and the number of 
1169  * components increases.
1170  *  \param [in] other - the DataArrayDouble to append to \a this one.
1171  *  \throw If \a this is not allocated.
1172  *  \throw If \a this and \a other arrays have different number of tuples.
1173  *
1174  *  \if ENABLE_EXAMPLES
1175  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1176  *
1177  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1178  *  \endif
1179  */
1180 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1181 {
1182   checkAllocated();
1183   other->checkAllocated();
1184   int nbOfTuples=getNumberOfTuples();
1185   if(nbOfTuples!=other->getNumberOfTuples())
1186     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1187   int nbOfComp1=getNumberOfComponents();
1188   int nbOfComp2=other->getNumberOfComponents();
1189   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1190   double *w=newArr;
1191   const double *inp1=getConstPointer();
1192   const double *inp2=other->getConstPointer();
1193   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1194     {
1195       w=std::copy(inp1,inp1+nbOfComp1,w);
1196       w=std::copy(inp2,inp2+nbOfComp2,w);
1197     }
1198   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1199   std::vector<int> compIds(nbOfComp2);
1200   for(int i=0;i<nbOfComp2;i++)
1201     compIds[i]=nbOfComp1+i;
1202   copyPartOfStringInfoFrom2(compIds,*other);
1203 }
1204
1205 /*!
1206  * This method checks that all tuples in \a other are in \a this.
1207  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1208  * 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.
1209  *
1210  * \param [in] other - the array having the same number of components than \a this.
1211  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1212  * \sa DataArrayDouble::findCommonTuples
1213  */
1214 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1215 {
1216   if(!other)
1217     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1218   checkAllocated(); other->checkAllocated();
1219   if(getNumberOfComponents()!=other->getNumberOfComponents())
1220     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1221   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1222   DataArrayInt *c=0,*ci=0;
1223   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1224   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1225   int newNbOfTuples=-1;
1226   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1227   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1228   tupleIds=ret1.retn();
1229   return newNbOfTuples==getNumberOfTuples();
1230 }
1231
1232 /*!
1233  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1234  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1235  * distance separating two points is computed with the infinite norm.
1236  *
1237  * Indices of coincident tuples are stored in output arrays.
1238  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1239  *
1240  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1241  * MEDCouplingUMesh::mergeNodes().
1242  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1243  *              considered not coincident.
1244  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1245  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1246  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1247  *               \a comm->getNumberOfComponents() == 1. 
1248  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1249  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1250  *               groups of (indices of) coincident tuples. Its every value is a tuple
1251  *               index where a next group of tuples begins. For example the second
1252  *               group of tuples in \a comm is described by following range of indices:
1253  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1254  *               gives the number of groups of coincident tuples.
1255  *  \throw If \a this is not allocated.
1256  *  \throw If the number of components is not in [1,2,3,4].
1257  *
1258  *  \if ENABLE_EXAMPLES
1259  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1260  *
1261  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1262  *  \endif
1263  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1264  */
1265 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1266 {
1267   checkAllocated();
1268   int nbOfCompo=getNumberOfComponents();
1269   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1270     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1271
1272   int nbOfTuples=getNumberOfTuples();
1273   //
1274   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1275   switch(nbOfCompo)
1276   {
1277     case 4:
1278       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1279       break;
1280     case 3:
1281       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1282       break;
1283     case 2:
1284       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1285       break;
1286     case 1:
1287       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1288       break;
1289     default:
1290       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1291   }
1292   comm=c.retn();
1293   commIndex=cI.retn();
1294 }
1295
1296 /*!
1297  * 
1298  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1299  *             \a nbTimes  should be at least equal to 1.
1300  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1301  * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
1302  */
1303 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1304 {
1305   checkAllocated();
1306   if(getNumberOfComponents()!=1)
1307     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1308   if(nbTimes<1)
1309     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1310   int nbTuples=getNumberOfTuples();
1311   const double *inPtr=getConstPointer();
1312   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1313   double *retPtr=ret->getPointer();
1314   for(int i=0;i<nbTuples;i++,inPtr++)
1315     {
1316       double val=*inPtr;
1317       for(int j=0;j<nbTimes;j++,retPtr++)
1318         *retPtr=val;
1319     }
1320   ret->copyStringInfoFrom(*this);
1321   return ret.retn();
1322 }
1323
1324 /*!
1325  * This methods returns the minimal distance between the two set of points \a this and \a other.
1326  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1327  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1328  *
1329  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1330  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1331  * \return the minimal distance between the two set of points \a this and \a other.
1332  * \sa DataArrayDouble::findClosestTupleId
1333  */
1334 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1335 {
1336   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1337   int nbOfCompo(getNumberOfComponents());
1338   int otherNbTuples(other->getNumberOfTuples());
1339   const double *thisPt(begin()),*otherPt(other->begin());
1340   const int *part1Pt(part1->begin());
1341   double ret=std::numeric_limits<double>::max();
1342   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1343     {
1344       double tmp(0.);
1345       for(int j=0;j<nbOfCompo;j++)
1346         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1347       if(tmp<ret)
1348         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1349     }
1350   return sqrt(ret);
1351 }
1352
1353 /*!
1354  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1355  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1356  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1357  *
1358  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1359  * \sa DataArrayDouble::minimalDistanceTo
1360  */
1361 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1362 {
1363   if(!other)
1364     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1365   checkAllocated(); other->checkAllocated();
1366   int nbOfCompo=getNumberOfComponents();
1367   if(nbOfCompo!=other->getNumberOfComponents())
1368     {
1369       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1370       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1371       throw INTERP_KERNEL::Exception(oss.str().c_str());
1372     }
1373   int nbOfTuples=other->getNumberOfTuples();
1374   int thisNbOfTuples=getNumberOfTuples();
1375   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1376   double bounds[6];
1377   getMinMaxPerComponent(bounds);
1378   switch(nbOfCompo)
1379   {
1380     case 3:
1381       {
1382         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1383         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1384         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1385         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1386         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1387         break;
1388       }
1389     case 2:
1390       {
1391         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1392         double delta=std::max(xDelta,yDelta);
1393         double characSize=sqrt(delta/(double)thisNbOfTuples);
1394         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1395         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1396         break;
1397       }
1398     case 1:
1399       {
1400         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1401         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1402         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1403         break;
1404       }
1405     default:
1406       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1407   }
1408   return ret.retn();
1409 }
1410
1411 /*!
1412  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1413  * 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
1414  * how many bounding boxes in \a otherBBoxFrmt.
1415  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1416  *
1417  * \param [in] otherBBoxFrmt - It is an array .
1418  * \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.
1419  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1420  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1421  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1422  */
1423 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1424 {
1425   if(!otherBBoxFrmt)
1426     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1427   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1428     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1429   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1430   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1431     {
1432       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1433       throw INTERP_KERNEL::Exception(oss.str().c_str());
1434     }
1435   if(nbOfComp%2!=0)
1436     {
1437       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1438       throw INTERP_KERNEL::Exception(oss.str().c_str());
1439     }
1440   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1441   const double *thisBBPtr(begin());
1442   int *retPtr(ret->getPointer());
1443   switch(nbOfComp/2)
1444   {
1445     case 3:
1446       {
1447         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1448         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1449           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1450         break;
1451       }
1452     case 2:
1453       {
1454         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1455         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1456           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1457         break;
1458       }
1459     case 1:
1460       {
1461         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1462         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1463           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1464         break;
1465       }
1466     default:
1467       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1468   }
1469
1470   return ret.retn();
1471 }
1472
1473 /*!
1474  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1475  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1476  * space. The distance between tuples is computed using norm2. If several tuples are
1477  * not far each from other than \a prec, only one of them remains in the result
1478  * array. The order of tuples in the result array is same as in \a this one except
1479  * that coincident tuples are excluded.
1480  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1481  *              considered not coincident.
1482  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1483  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1484  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1485  *          is to delete using decrRef() as it is no more needed.
1486  *  \throw If \a this is not allocated.
1487  *  \throw If the number of components is not in [1,2,3,4].
1488  *
1489  *  \if ENABLE_EXAMPLES
1490  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1491  *  \endif
1492  */
1493 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1494 {
1495   checkAllocated();
1496   DataArrayInt *c0=0,*cI0=0;
1497   findCommonTuples(prec,limitTupleId,c0,cI0);
1498   MCAuto<DataArrayInt> c(c0),cI(cI0);
1499   int newNbOfTuples=-1;
1500   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1501   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1502 }
1503
1504 /*!
1505  * Copy all components in a specified order from another DataArrayDouble.
1506  * Both numerical and textual data is copied. The number of tuples in \a this and
1507  * the other array can be different.
1508  *  \param [in] a - the array to copy data from.
1509  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1510  *              to be copied.
1511  *  \throw If \a a is NULL.
1512  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1513  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1514  *
1515  *  \if ENABLE_EXAMPLES
1516  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1517  *  \endif
1518  */
1519 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1520 {
1521   if(!a)
1522     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1523   checkAllocated();
1524   copyPartOfStringInfoFrom2(compoIds,*a);
1525   std::size_t partOfCompoSz=compoIds.size();
1526   int nbOfCompo=getNumberOfComponents();
1527   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1528   const double *ac=a->getConstPointer();
1529   double *nc=getPointer();
1530   for(int i=0;i<nbOfTuples;i++)
1531     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1532       nc[nbOfCompo*i+compoIds[j]]=*ac;
1533 }
1534
1535 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1536 {
1537   if(newArray!=arrayToSet)
1538     {
1539       if(arrayToSet)
1540         arrayToSet->decrRef();
1541       arrayToSet=newArray;
1542       if(arrayToSet)
1543         arrayToSet->incrRef();
1544     }
1545 }
1546
1547 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1548 {
1549   if(!other)
1550     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1551   if(getNumberOfComponents()!=other->getNumberOfComponents())
1552     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1553   _mem.insertAtTheEnd(other->begin(),other->end());
1554 }
1555
1556 /*!
1557  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1558  * is thrown.
1559  * \throw If zero is found in \a this array.
1560  */
1561 void DataArrayDouble::checkNoNullValues() const
1562 {
1563   const double *tmp=getConstPointer();
1564   std::size_t nbOfElems=getNbOfElems();
1565   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1566   if(where!=tmp+nbOfElems)
1567     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1568 }
1569
1570 /*!
1571  * Computes minimal and maximal value in each component. An output array is filled
1572  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1573  * enough memory before calling this method.
1574  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1575  *               It is filled as follows:<br>
1576  *               \a bounds[0] = \c min_of_component_0 <br>
1577  *               \a bounds[1] = \c max_of_component_0 <br>
1578  *               \a bounds[2] = \c min_of_component_1 <br>
1579  *               \a bounds[3] = \c max_of_component_1 <br>
1580  *               ...
1581  */
1582 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1583 {
1584   checkAllocated();
1585   int dim=getNumberOfComponents();
1586   for (int idim=0; idim<dim; idim++)
1587     {
1588       bounds[idim*2]=std::numeric_limits<double>::max();
1589       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1590     } 
1591   const double *ptr=getConstPointer();
1592   int nbOfTuples=getNumberOfTuples();
1593   for(int i=0;i<nbOfTuples;i++)
1594     {
1595       for(int idim=0;idim<dim;idim++)
1596         {
1597           if(bounds[idim*2]>ptr[i*dim+idim])
1598             {
1599               bounds[idim*2]=ptr[i*dim+idim];
1600             }
1601           if(bounds[idim*2+1]<ptr[i*dim+idim])
1602             {
1603               bounds[idim*2+1]=ptr[i*dim+idim];
1604             }
1605         }
1606     }
1607 }
1608
1609 /*!
1610  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1611  * to store both the min and max per component of each tuples. 
1612  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1613  *
1614  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1615  *
1616  * \throw If \a this is not allocated yet.
1617  */
1618 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1619 {
1620   checkAllocated();
1621   const double *dataPtr=getConstPointer();
1622   int nbOfCompo=getNumberOfComponents();
1623   int nbTuples=getNumberOfTuples();
1624   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1625   bbox->alloc(nbTuples,2*nbOfCompo);
1626   double *bboxPtr=bbox->getPointer();
1627   for(int i=0;i<nbTuples;i++)
1628     {
1629       for(int j=0;j<nbOfCompo;j++)
1630         {
1631           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1632           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1633         }
1634     }
1635   return bbox.retn();
1636 }
1637
1638 /*!
1639  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1640  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1641  * 
1642  * \param [in] other a DataArrayDouble having same number of components than \a this.
1643  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1644  * \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.
1645  *             \a cI allows to extract information in \a c.
1646  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1647  *
1648  * \throw In case of:
1649  *  - \a this is not allocated
1650  *  - \a other is not allocated or null
1651  *  - \a this and \a other do not have the same number of components
1652  *  - if number of components of \a this is not in [1,2,3]
1653  *
1654  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1655  */
1656 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1657 {
1658   if(!other)
1659     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1660   checkAllocated();
1661   other->checkAllocated();
1662   int nbOfCompo=getNumberOfComponents();
1663   int otherNbOfCompo=other->getNumberOfComponents();
1664   if(nbOfCompo!=otherNbOfCompo)
1665     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1666   int nbOfTuplesOther=other->getNumberOfTuples();
1667   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1668   switch(nbOfCompo)
1669   {
1670     case 3:
1671       {
1672         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1673         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1674         break;
1675       }
1676     case 2:
1677       {
1678         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1679         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1680         break;
1681       }
1682     case 1:
1683       {
1684         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1685         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1686         break;
1687       }
1688     default:
1689       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1690   }
1691   c=cArr.retn(); cI=cIArr.retn();
1692 }
1693
1694 /*!
1695  * 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
1696  * around origin of 'radius' 1.
1697  * 
1698  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1699  */
1700 void DataArrayDouble::recenterForMaxPrecision(double eps)
1701 {
1702   checkAllocated();
1703   int dim=getNumberOfComponents();
1704   std::vector<double> bounds(2*dim);
1705   getMinMaxPerComponent(&bounds[0]);
1706   for(int i=0;i<dim;i++)
1707     {
1708       double delta=bounds[2*i+1]-bounds[2*i];
1709       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1710       if(delta>eps)
1711         applyLin(1./delta,-offset/delta,i);
1712       else
1713         applyLin(1.,-offset,i);
1714     }
1715 }
1716
1717 /*!
1718  * Returns the maximal value and all its locations within \a this one-dimensional array.
1719  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1720  *               tuples holding the maximal value. The caller is to delete it using
1721  *               decrRef() as it is no more needed.
1722  *  \return double - the maximal value among all values of \a this array.
1723  *  \throw If \a this->getNumberOfComponents() != 1
1724  *  \throw If \a this->getNumberOfTuples() < 1
1725  */
1726 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1727 {
1728   int tmp;
1729   tupleIds=0;
1730   double ret=getMaxValue(tmp);
1731   tupleIds=findIdsInRange(ret,ret);
1732   return ret;
1733 }
1734
1735 /*!
1736  * Returns the minimal value and all its locations within \a this one-dimensional array.
1737  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1738  *               tuples holding the minimal value. The caller is to delete it using
1739  *               decrRef() as it is no more needed.
1740  *  \return double - the minimal value among all values of \a this array.
1741  *  \throw If \a this->getNumberOfComponents() != 1
1742  *  \throw If \a this->getNumberOfTuples() < 1
1743  */
1744 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1745 {
1746   int tmp;
1747   tupleIds=0;
1748   double ret=getMinValue(tmp);
1749   tupleIds=findIdsInRange(ret,ret);
1750   return ret;
1751 }
1752
1753 /*!
1754  * 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.
1755  * This method only works for single component array.
1756  *
1757  * \return a value in [ 0, \c this->getNumberOfTuples() )
1758  *
1759  * \throw If \a this is not allocated
1760  *
1761  */
1762 int DataArrayDouble::count(double value, double eps) const
1763 {
1764   int ret=0;
1765   checkAllocated();
1766   if(getNumberOfComponents()!=1)
1767     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1768   const double *vals=begin();
1769   int nbOfTuples=getNumberOfTuples();
1770   for(int i=0;i<nbOfTuples;i++,vals++)
1771     if(fabs(*vals-value)<=eps)
1772       ret++;
1773   return ret;
1774 }
1775
1776 /*!
1777  * Returns the average value of \a this one-dimensional array.
1778  *  \return double - the average value over all values of \a this array.
1779  *  \throw If \a this->getNumberOfComponents() != 1
1780  *  \throw If \a this->getNumberOfTuples() < 1
1781  */
1782 double DataArrayDouble::getAverageValue() const
1783 {
1784   if(getNumberOfComponents()!=1)
1785     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1786   int nbOfTuples=getNumberOfTuples();
1787   if(nbOfTuples<=0)
1788     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1789   const double *vals=getConstPointer();
1790   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1791   return ret/nbOfTuples;
1792 }
1793
1794 /*!
1795  * Returns the Euclidean norm of the vector defined by \a this array.
1796  *  \return double - the value of the Euclidean norm, i.e.
1797  *          the square root of the inner product of vector.
1798  *  \throw If \a this is not allocated.
1799  */
1800 double DataArrayDouble::norm2() const
1801 {
1802   checkAllocated();
1803   double ret=0.;
1804   std::size_t nbOfElems=getNbOfElems();
1805   const double *pt=getConstPointer();
1806   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1807     ret+=(*pt)*(*pt);
1808   return sqrt(ret);
1809 }
1810
1811 /*!
1812  * Returns the maximum norm of the vector defined by \a this array.
1813  * This method works even if the number of components is diferent from one.
1814  * If the number of elements in \a this is 0, -1. is returned.
1815  *  \return double - the value of the maximum norm, i.e.
1816  *          the maximal absolute value among values of \a this array (whatever its number of components).
1817  *  \throw If \a this is not allocated.
1818  */
1819 double DataArrayDouble::normMax() const
1820 {
1821   checkAllocated();
1822   double ret(-1.);
1823   std::size_t nbOfElems(getNbOfElems());
1824   const double *pt(getConstPointer());
1825   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1826     {
1827       double val(std::abs(*pt));
1828       if(val>ret)
1829         ret=val;
1830     }
1831   return ret;
1832 }
1833
1834 /*!
1835  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1836  * This method works even if the number of components is diferent from one.
1837  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1838  *  \return double - the value of the minimum norm, i.e.
1839  *          the minimal absolute value among values of \a this array (whatever its number of components).
1840  *  \throw If \a this is not allocated.
1841  */
1842 double DataArrayDouble::normMin() const
1843 {
1844   checkAllocated();
1845   double ret(std::numeric_limits<double>::max());
1846   std::size_t nbOfElems(getNbOfElems());
1847   const double *pt(getConstPointer());
1848   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1849     {
1850       double val(std::abs(*pt));
1851       if(val<ret)
1852         ret=val;
1853     }
1854   return ret;
1855 }
1856
1857 /*!
1858  * Accumulates values of each component of \a this array.
1859  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1860  *         by the caller, that is filled by this method with sum value for each
1861  *         component.
1862  *  \throw If \a this is not allocated.
1863  */
1864 void DataArrayDouble::accumulate(double *res) const
1865 {
1866   checkAllocated();
1867   const double *ptr=getConstPointer();
1868   int nbTuple=getNumberOfTuples();
1869   int nbComps=getNumberOfComponents();
1870   std::fill(res,res+nbComps,0.);
1871   for(int i=0;i<nbTuple;i++)
1872     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1873 }
1874
1875 /*!
1876  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1877  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1878  *
1879  *
1880  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1881  * \a tupleEnd. If not an exception will be thrown.
1882  *
1883  * \param [in] tupleBg start pointer (included) of input external tuple
1884  * \param [in] tupleEnd end pointer (not included) of input external tuple
1885  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1886  * \return the min distance.
1887  * \sa MEDCouplingUMesh::distanceToPoint
1888  */
1889 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1890 {
1891   checkAllocated();
1892   int nbTuple=getNumberOfTuples();
1893   int nbComps=getNumberOfComponents();
1894   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1895     { 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()); }
1896   if(nbTuple==0)
1897     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1898   double ret0=std::numeric_limits<double>::max();
1899   tupleId=-1;
1900   const double *work=getConstPointer();
1901   for(int i=0;i<nbTuple;i++)
1902     {
1903       double val=0.;
1904       for(int j=0;j<nbComps;j++,work++) 
1905         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1906       if(val>=ret0)
1907         continue;
1908       else
1909         { ret0=val; tupleId=i; }
1910     }
1911   return sqrt(ret0);
1912 }
1913
1914 /*!
1915  * Accumulate values of the given component of \a this array.
1916  *  \param [in] compId - the index of the component of interest.
1917  *  \return double - a sum value of \a compId-th component.
1918  *  \throw If \a this is not allocated.
1919  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1920  *         not respected.
1921  */
1922 double DataArrayDouble::accumulate(int compId) const
1923 {
1924   checkAllocated();
1925   const double *ptr=getConstPointer();
1926   int nbTuple=getNumberOfTuples();
1927   int nbComps=getNumberOfComponents();
1928   if(compId<0 || compId>=nbComps)
1929     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1930   double ret=0.;
1931   for(int i=0;i<nbTuple;i++)
1932     ret+=ptr[i*nbComps+compId];
1933   return ret;
1934 }
1935
1936 /*!
1937  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1938  * The returned array will have same number of components than \a this and number of tuples equal to
1939  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1940  *
1941  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1942  * 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.
1943  *
1944  * \param [in] bgOfIndex - begin (included) of the input index array.
1945  * \param [in] endOfIndex - end (excluded) of the input index array.
1946  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1947  * 
1948  * \throw If bgOfIndex or end is NULL.
1949  * \throw If input index array is not ascendingly sorted.
1950  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1951  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1952  */
1953 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1954 {
1955   if(!bgOfIndex || !endOfIndex)
1956     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1957   checkAllocated();
1958   int nbCompo=getNumberOfComponents();
1959   int nbOfTuples=getNumberOfTuples();
1960   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1961   if(sz<1)
1962     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1963   sz--;
1964   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1965   const int *w=bgOfIndex;
1966   if(*w<0 || *w>=nbOfTuples)
1967     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1968   const double *srcPt=begin()+(*w)*nbCompo;
1969   double *tmp=ret->getPointer();
1970   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1971     {
1972       std::fill(tmp,tmp+nbCompo,0.);
1973       if(w[1]>=w[0])
1974         {
1975           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1976             {
1977               if(j>=0 && j<nbOfTuples)
1978                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1979               else
1980                 {
1981                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1982                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1983                 }
1984             }
1985         }
1986       else
1987         {
1988           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1989           throw INTERP_KERNEL::Exception(oss.str().c_str());
1990         }
1991     }
1992   ret->copyStringInfoFrom(*this);
1993   return ret.retn();
1994 }
1995
1996 /*!
1997  * 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.
1998  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1999  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
2000  *
2001  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2002  */
2003 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2004 {
2005   checkAllocated();
2006   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2007   int nbOfTuple(getNumberOfTuples());
2008   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2009   double *ptr(ret->getPointer());
2010   ptr[0]=0.;
2011   const double *thisPtr(begin());
2012   for(int i=0;i<nbOfTuple;i++)
2013     ptr[i+1]=ptr[i]+thisPtr[i];
2014   return ret;
2015 }
2016
2017 /*!
2018  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2019  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2020  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2021  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2022  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2023  *          is to delete this array using decrRef() as it is no more needed. The array
2024  *          does not contain any textual info on components.
2025  *  \throw If \a this->getNumberOfComponents() != 2.
2026  * \sa fromCartToPolar
2027  */
2028 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2029 {
2030   checkAllocated();
2031   int nbOfComp(getNumberOfComponents());
2032   if(nbOfComp!=2)
2033     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2034   int nbOfTuple(getNumberOfTuples());
2035   DataArrayDouble *ret(DataArrayDouble::New());
2036   ret->alloc(nbOfTuple,2);
2037   double *w(ret->getPointer());
2038   const double *wIn(getConstPointer());
2039   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2040     {
2041       w[0]=wIn[0]*cos(wIn[1]);
2042       w[1]=wIn[0]*sin(wIn[1]);
2043     }
2044   return ret;
2045 }
2046
2047 /*!
2048  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2049  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2050  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2051  * the Cylindrical CS.
2052  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2053  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2054  *          on the third component is copied from \a this array. The caller
2055  *          is to delete this array using decrRef() as it is no more needed. 
2056  *  \throw If \a this->getNumberOfComponents() != 3.
2057  * \sa fromCartToCyl
2058  */
2059 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2060 {
2061   checkAllocated();
2062   int nbOfComp(getNumberOfComponents());
2063   if(nbOfComp!=3)
2064     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2065   int nbOfTuple(getNumberOfTuples());
2066   DataArrayDouble *ret(DataArrayDouble::New());
2067   ret->alloc(getNumberOfTuples(),3);
2068   double *w(ret->getPointer());
2069   const double *wIn(getConstPointer());
2070   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2071     {
2072       w[0]=wIn[0]*cos(wIn[1]);
2073       w[1]=wIn[0]*sin(wIn[1]);
2074       w[2]=wIn[2];
2075     }
2076   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2077   return ret;
2078 }
2079
2080 /*!
2081  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2082  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2083  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2084  * point in the Cylindrical CS.
2085  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2086  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2087  *          on the third component is copied from \a this array. The caller
2088  *          is to delete this array using decrRef() as it is no more needed.
2089  *  \throw If \a this->getNumberOfComponents() != 3.
2090  * \sa fromCartToSpher
2091  */
2092 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2093 {
2094   checkAllocated();
2095   int nbOfComp(getNumberOfComponents());
2096   if(nbOfComp!=3)
2097     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2098   int nbOfTuple(getNumberOfTuples());
2099   DataArrayDouble *ret(DataArrayDouble::New());
2100   ret->alloc(getNumberOfTuples(),3);
2101   double *w(ret->getPointer());
2102   const double *wIn(getConstPointer());
2103   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2104     {
2105       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2106       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2107       w[2]=wIn[0]*cos(wIn[1]);
2108     }
2109   return ret;
2110 }
2111
2112 /*!
2113  * 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.
2114  * 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.
2115  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2116  *
2117  * \param [in] atOfThis - The axis type of \a this.
2118  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2119  */
2120 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2121 {
2122   checkAllocated();
2123   int nbOfComp(getNumberOfComponents());
2124   MCAuto<DataArrayDouble> ret;
2125   switch(atOfThis)
2126     {
2127     case AX_CART:
2128       ret=deepCopy();
2129     case AX_CYL:
2130       if(nbOfComp==3)
2131         {
2132           ret=fromCylToCart();
2133           break;
2134         }
2135       if(nbOfComp==2)
2136         {
2137           ret=fromPolarToCart();
2138           break;
2139         }
2140       else
2141         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2142     case AX_SPHER:
2143       if(nbOfComp==3)
2144         {
2145           ret=fromSpherToCart();
2146           break;
2147         }
2148       if(nbOfComp==2)
2149         {
2150           ret=fromPolarToCart();
2151           break;
2152         }
2153       else
2154         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2155     default:
2156       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2157     }
2158   ret->copyStringInfoFrom(*this);
2159   return ret.retn();
2160 }
2161
2162 /*!
2163  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2164  * This method expects that \a this has exactly 2 components.
2165  * \sa fromPolarToCart
2166  */
2167 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2168 {
2169   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2170   checkAllocated();
2171   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2172   if(nbOfComp!=2)
2173     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2174   ret->alloc(nbTuples,2);
2175   double *retPtr(ret->getPointer());
2176   const double *ptr(begin());
2177   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2178     {
2179       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2180       retPtr[1]=atan2(ptr[1],ptr[0]);
2181     }
2182   return ret.retn();
2183 }
2184
2185 /*!
2186  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2187  * This method expects that \a this has exactly 3 components.
2188  * \sa fromCylToCart
2189  */
2190 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2191 {
2192   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2193   checkAllocated();
2194   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2195   if(nbOfComp!=3)
2196     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2197   ret->alloc(nbTuples,3);
2198   double *retPtr(ret->getPointer());
2199   const double *ptr(begin());
2200   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2201     {
2202       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2203       retPtr[1]=atan2(ptr[1],ptr[0]);
2204       retPtr[2]=ptr[2];
2205     }
2206   return ret.retn();
2207 }
2208
2209 /*!
2210  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2211  * \sa fromSpherToCart
2212  */
2213 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2214 {
2215   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2216   checkAllocated();
2217   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2218   if(nbOfComp!=3)
2219     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2220   ret->alloc(nbTuples,3);
2221   double *retPtr(ret->getPointer());
2222   const double *ptr(begin());
2223   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2224     {
2225       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2226       retPtr[1]=acos(ptr[2]/retPtr[0]);
2227       retPtr[2]=atan2(ptr[1],ptr[0]);
2228     }
2229   return ret.retn();
2230 }
2231
2232 /*!
2233  * 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.
2234  * This method expects that \a this has exactly 3 components.
2235  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2236  */
2237 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2238 {
2239   if(!coords)
2240     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2241   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2242   checkAllocated(); coords->checkAllocated();
2243   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2244   if(nbOfComp!=3)
2245     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2246   if(coords->getNumberOfComponents()!=3)
2247     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2248   if(coords->getNumberOfTuples()!=nbTuples)
2249     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2250   ret->alloc(nbTuples,nbOfComp);
2251   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2252   if(magOfVect<1e-12)
2253     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2254   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2255   const double *coo(coords->begin()),*vectField(begin());
2256   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2257   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2258     {
2259       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2260       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];
2261       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2262       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2263       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];
2264       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2265       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2266       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2267     }
2268   ret->copyStringInfoFrom(*this);
2269   return ret.retn();
2270 }
2271
2272 /*!
2273  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2274  * array contating 6 components.
2275  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2276  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2277  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2278  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2279  *  \throw If \a this->getNumberOfComponents() != 6.
2280  */
2281 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2282 {
2283   checkAllocated();
2284   int nbOfComp(getNumberOfComponents());
2285   if(nbOfComp!=6)
2286     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2287   DataArrayDouble *ret=DataArrayDouble::New();
2288   int nbOfTuple=getNumberOfTuples();
2289   ret->alloc(nbOfTuple,1);
2290   const double *src=getConstPointer();
2291   double *dest=ret->getPointer();
2292   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2293     *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];
2294   return ret;
2295 }
2296
2297 /*!
2298  * Computes the determinant of every square matrix defined by the tuple of \a this
2299  * array, which contains either 4, 6 or 9 components. The case of 6 components
2300  * corresponds to that of the upper triangular matrix.
2301  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2302  *          is the determinant of matrix of the corresponding tuple of \a this array.
2303  *          The caller is to delete this result array using decrRef() as it is no more
2304  *          needed. 
2305  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2306  */
2307 DataArrayDouble *DataArrayDouble::determinant() const
2308 {
2309   checkAllocated();
2310   DataArrayDouble *ret=DataArrayDouble::New();
2311   int nbOfTuple=getNumberOfTuples();
2312   ret->alloc(nbOfTuple,1);
2313   const double *src=getConstPointer();
2314   double *dest=ret->getPointer();
2315   switch(getNumberOfComponents())
2316   {
2317     case 6:
2318       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2319         *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];
2320       return ret;
2321     case 4:
2322       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2323         *dest=src[0]*src[3]-src[1]*src[2];
2324       return ret;
2325     case 9:
2326       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2327         *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];
2328       return ret;
2329     default:
2330       ret->decrRef();
2331       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2332   }
2333 }
2334
2335 /*!
2336  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2337  * \a this array, which contains 6 components.
2338  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2339  *          components, whose each tuple contains the eigenvalues of the matrix of
2340  *          corresponding tuple of \a this array. 
2341  *          The caller is to delete this result array using decrRef() as it is no more
2342  *          needed. 
2343  *  \throw If \a this->getNumberOfComponents() != 6.
2344  */
2345 DataArrayDouble *DataArrayDouble::eigenValues() const
2346 {
2347   checkAllocated();
2348   int nbOfComp=getNumberOfComponents();
2349   if(nbOfComp!=6)
2350     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2351   DataArrayDouble *ret=DataArrayDouble::New();
2352   int nbOfTuple=getNumberOfTuples();
2353   ret->alloc(nbOfTuple,3);
2354   const double *src=getConstPointer();
2355   double *dest=ret->getPointer();
2356   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2357     INTERP_KERNEL::computeEigenValues6(src,dest);
2358   return ret;
2359 }
2360
2361 /*!
2362  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2363  * \a this array, which contains 6 components.
2364  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2365  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2366  *          corresponding tuple of \a this array.
2367  *          The caller is to delete this result array using decrRef() as it is no more
2368  *          needed.
2369  *  \throw If \a this->getNumberOfComponents() != 6.
2370  */
2371 DataArrayDouble *DataArrayDouble::eigenVectors() const
2372 {
2373   checkAllocated();
2374   int nbOfComp=getNumberOfComponents();
2375   if(nbOfComp!=6)
2376     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2377   DataArrayDouble *ret=DataArrayDouble::New();
2378   int nbOfTuple=getNumberOfTuples();
2379   ret->alloc(nbOfTuple,9);
2380   const double *src=getConstPointer();
2381   double *dest=ret->getPointer();
2382   for(int i=0;i<nbOfTuple;i++,src+=6)
2383     {
2384       double tmp[3];
2385       INTERP_KERNEL::computeEigenValues6(src,tmp);
2386       for(int j=0;j<3;j++,dest+=3)
2387         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2388     }
2389   return ret;
2390 }
2391
2392 /*!
2393  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2394  * array, which contains either 4, 6 or 9 components. The case of 6 components
2395  * corresponds to that of the upper triangular matrix.
2396  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2397  *          same number of components as \a this one, whose each tuple is the inverse
2398  *          matrix of the matrix of corresponding tuple of \a this array. 
2399  *          The caller is to delete this result array using decrRef() as it is no more
2400  *          needed. 
2401  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2402  */
2403 DataArrayDouble *DataArrayDouble::inverse() const
2404 {
2405   checkAllocated();
2406   int nbOfComp=getNumberOfComponents();
2407   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2408     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2409   DataArrayDouble *ret=DataArrayDouble::New();
2410   int nbOfTuple=getNumberOfTuples();
2411   ret->alloc(nbOfTuple,nbOfComp);
2412   const double *src=getConstPointer();
2413   double *dest=ret->getPointer();
2414   if(nbOfComp==6)
2415     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2416       {
2417         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];
2418         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2419         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2420         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2421         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2422         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2423         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2424       }
2425   else if(nbOfComp==4)
2426     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2427       {
2428         double det=src[0]*src[3]-src[1]*src[2];
2429         dest[0]=src[3]/det;
2430         dest[1]=-src[1]/det;
2431         dest[2]=-src[2]/det;
2432         dest[3]=src[0]/det;
2433       }
2434   else
2435     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2436       {
2437         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];
2438         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2439         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2440         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2441         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2442         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2443         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2444         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2445         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2446         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2447       }
2448   return ret;
2449 }
2450
2451 /*!
2452  * Computes the trace of every matrix defined by the tuple of \a this
2453  * array, which contains either 4, 6 or 9 components. The case of 6 components
2454  * corresponds to that of the upper triangular matrix.
2455  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2456  *          1 component, whose each tuple is the trace of
2457  *          the matrix of corresponding tuple of \a this array. 
2458  *          The caller is to delete this result array using decrRef() as it is no more
2459  *          needed. 
2460  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2461  */
2462 DataArrayDouble *DataArrayDouble::trace() const
2463 {
2464   checkAllocated();
2465   int nbOfComp=getNumberOfComponents();
2466   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2467     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2468   DataArrayDouble *ret=DataArrayDouble::New();
2469   int nbOfTuple=getNumberOfTuples();
2470   ret->alloc(nbOfTuple,1);
2471   const double *src=getConstPointer();
2472   double *dest=ret->getPointer();
2473   if(nbOfComp==6)
2474     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2475       *dest=src[0]+src[1]+src[2];
2476   else if(nbOfComp==4)
2477     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2478       *dest=src[0]+src[3];
2479   else
2480     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2481       *dest=src[0]+src[4]+src[8];
2482   return ret;
2483 }
2484
2485 /*!
2486  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2487  * \a this array, which contains 6 components.
2488  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2489  *          same number of components and tuples as \a this array.
2490  *          The caller is to delete this result array using decrRef() as it is no more
2491  *          needed.
2492  *  \throw If \a this->getNumberOfComponents() != 6.
2493  */
2494 DataArrayDouble *DataArrayDouble::deviator() const
2495 {
2496   checkAllocated();
2497   int nbOfComp=getNumberOfComponents();
2498   if(nbOfComp!=6)
2499     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2500   DataArrayDouble *ret=DataArrayDouble::New();
2501   int nbOfTuple=getNumberOfTuples();
2502   ret->alloc(nbOfTuple,6);
2503   const double *src=getConstPointer();
2504   double *dest=ret->getPointer();
2505   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2506     {
2507       double tr=(src[0]+src[1]+src[2])/3.;
2508       dest[0]=src[0]-tr;
2509       dest[1]=src[1]-tr;
2510       dest[2]=src[2]-tr;
2511       dest[3]=src[3];
2512       dest[4]=src[4];
2513       dest[5]=src[5];
2514     }
2515   return ret;
2516 }
2517
2518 /*!
2519  * Computes the magnitude of every vector defined by the tuple of
2520  * \a this array.
2521  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2522  *          same number of tuples as \a this array and one component.
2523  *          The caller is to delete this result array using decrRef() as it is no more
2524  *          needed.
2525  *  \throw If \a this is not allocated.
2526  */
2527 DataArrayDouble *DataArrayDouble::magnitude() const
2528 {
2529   checkAllocated();
2530   int nbOfComp=getNumberOfComponents();
2531   DataArrayDouble *ret=DataArrayDouble::New();
2532   int nbOfTuple=getNumberOfTuples();
2533   ret->alloc(nbOfTuple,1);
2534   const double *src=getConstPointer();
2535   double *dest=ret->getPointer();
2536   for(int i=0;i<nbOfTuple;i++,dest++)
2537     {
2538       double sum=0.;
2539       for(int j=0;j<nbOfComp;j++,src++)
2540         sum+=(*src)*(*src);
2541       *dest=sqrt(sum);
2542     }
2543   return ret;
2544 }
2545
2546 /*!
2547  * Computes for each tuple the sum of number of components values in the tuple and return it.
2548  * 
2549  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2550  *          same number of tuples as \a this array and one component.
2551  *          The caller is to delete this result array using decrRef() as it is no more
2552  *          needed.
2553  *  \throw If \a this is not allocated.
2554  */
2555 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2556 {
2557   checkAllocated();
2558   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2559   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2560   ret->alloc(nbOfTuple,1);
2561   const double *src(getConstPointer());
2562   double *dest(ret->getPointer());
2563   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2564     *dest=std::accumulate(src,src+nbOfComp,0.);
2565   return ret.retn();
2566 }
2567
2568 /*!
2569  * Computes the maximal value within every tuple of \a this array.
2570  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2571  *          same number of tuples as \a this array and one component.
2572  *          The caller is to delete this result array using decrRef() as it is no more
2573  *          needed.
2574  *  \throw If \a this is not allocated.
2575  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2576  */
2577 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2578 {
2579   checkAllocated();
2580   int nbOfComp=getNumberOfComponents();
2581   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2582   int nbOfTuple=getNumberOfTuples();
2583   ret->alloc(nbOfTuple,1);
2584   const double *src=getConstPointer();
2585   double *dest=ret->getPointer();
2586   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2587     *dest=*std::max_element(src,src+nbOfComp);
2588   return ret.retn();
2589 }
2590
2591 /*!
2592  * Computes the maximal value within every tuple of \a this array and it returns the first component
2593  * id for each tuple that corresponds to the maximal value within the tuple.
2594  * 
2595  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2596  *          same number of tuples and only one component.
2597  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2598  *          same number of tuples as \a this array and one component.
2599  *          The caller is to delete this result array using decrRef() as it is no more
2600  *          needed.
2601  *  \throw If \a this is not allocated.
2602  *  \sa DataArrayDouble::maxPerTuple
2603  */
2604 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2605 {
2606   checkAllocated();
2607   int nbOfComp=getNumberOfComponents();
2608   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2609   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2610   int nbOfTuple=getNumberOfTuples();
2611   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2612   const double *src=getConstPointer();
2613   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2614   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2615     {
2616       const double *loc=std::max_element(src,src+nbOfComp);
2617       *dest=*loc;
2618       *dest1=(int)std::distance(src,loc);
2619     }
2620   compoIdOfMaxPerTuple=ret1.retn();
2621   return ret0.retn();
2622 }
2623
2624 /*!
2625  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2626  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2627  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2628  * \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)
2629  *
2630  * \warning use this method with care because it can leads to big amount of consumed memory !
2631  * 
2632  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2633  *
2634  * \throw If \a this is not allocated.
2635  *
2636  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2637  */
2638 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2639 {
2640   checkAllocated();
2641   int nbOfComp=getNumberOfComponents();
2642   int nbOfTuples=getNumberOfTuples();
2643   const double *inData=getConstPointer();
2644   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2645   ret->alloc(nbOfTuples*nbOfTuples,1);
2646   double *outData=ret->getPointer();
2647   for(int i=0;i<nbOfTuples;i++)
2648     {
2649       outData[i*nbOfTuples+i]=0.;
2650       for(int j=i+1;j<nbOfTuples;j++)
2651         {
2652           double dist=0.;
2653           for(int k=0;k<nbOfComp;k++)
2654             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2655           dist=sqrt(dist);
2656           outData[i*nbOfTuples+j]=dist;
2657           outData[j*nbOfTuples+i]=dist;
2658         }
2659     }
2660   return ret.retn();
2661 }
2662
2663 /*!
2664  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2665  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2666  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2667  * \n Output rectangular matrix is sorted along rows.
2668  * \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)
2669  *
2670  * \warning use this method with care because it can leads to big amount of consumed memory !
2671  * 
2672  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2673  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2674  *
2675  * \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.
2676  *
2677  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2678  */
2679 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2680 {
2681   if(!other)
2682     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2683   checkAllocated();
2684   other->checkAllocated();
2685   int nbOfComp=getNumberOfComponents();
2686   int otherNbOfComp=other->getNumberOfComponents();
2687   if(nbOfComp!=otherNbOfComp)
2688     {
2689       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2690       throw INTERP_KERNEL::Exception(oss.str().c_str());
2691     }
2692   int nbOfTuples=getNumberOfTuples();
2693   int otherNbOfTuples=other->getNumberOfTuples();
2694   const double *inData=getConstPointer();
2695   const double *inDataOther=other->getConstPointer();
2696   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2697   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2698   double *outData=ret->getPointer();
2699   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2700     {
2701       for(int j=0;j<nbOfTuples;j++)
2702         {
2703           double dist=0.;
2704           for(int k=0;k<nbOfComp;k++)
2705             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2706           dist=sqrt(dist);
2707           outData[i*nbOfTuples+j]=dist;
2708         }
2709     }
2710   return ret.retn();
2711 }
2712
2713 /*!
2714  * Sorts value within every tuple of \a this array.
2715  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2716  *              in descending order.
2717  *  \throw If \a this is not allocated.
2718  */
2719 void DataArrayDouble::sortPerTuple(bool asc)
2720 {
2721   checkAllocated();
2722   double *pt=getPointer();
2723   int nbOfTuple=getNumberOfTuples();
2724   int nbOfComp=getNumberOfComponents();
2725   if(asc)
2726     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2727       std::sort(pt,pt+nbOfComp);
2728   else
2729     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2730       std::sort(pt,pt+nbOfComp,std::greater<double>());
2731   declareAsNew();
2732 }
2733
2734 /*!
2735  * Converts every value of \a this array to its absolute value.
2736  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2737  * should be called instead.
2738  *
2739  * \throw If \a this is not allocated.
2740  * \sa DataArrayDouble::computeAbs
2741  */
2742 void DataArrayDouble::abs()
2743 {
2744   checkAllocated();
2745   double *ptr(getPointer());
2746   std::size_t nbOfElems(getNbOfElems());
2747   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2748   declareAsNew();
2749 }
2750
2751 /*!
2752  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2753  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2754  *
2755  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2756  *         same number of tuples and component as \a this array.
2757  *         The caller is to delete this result array using decrRef() as it is no more
2758  *         needed.
2759  * \throw If \a this is not allocated.
2760  * \sa DataArrayDouble::abs
2761  */
2762 DataArrayDouble *DataArrayDouble::computeAbs() const
2763 {
2764   checkAllocated();
2765   DataArrayDouble *newArr(DataArrayDouble::New());
2766   int nbOfTuples(getNumberOfTuples());
2767   int nbOfComp(getNumberOfComponents());
2768   newArr->alloc(nbOfTuples,nbOfComp);
2769   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2770   newArr->copyStringInfoFrom(*this);
2771   return newArr;
2772 }
2773
2774 /*!
2775  * Modify all elements of \a this array, so that
2776  * an element _x_ becomes \f$ numerator / x \f$.
2777  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2778  *           array, all elements processed before detection of the zero element remain
2779  *           modified.
2780  *  \param [in] numerator - the numerator used to modify array elements.
2781  *  \throw If \a this is not allocated.
2782  *  \throw If there is an element equal to 0.0 in \a this array.
2783  */
2784 void DataArrayDouble::applyInv(double numerator)
2785 {
2786   checkAllocated();
2787   double *ptr=getPointer();
2788   std::size_t nbOfElems=getNbOfElems();
2789   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2790     {
2791       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2792         {
2793           *ptr=numerator/(*ptr);
2794         }
2795       else
2796         {
2797           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2798           oss << " !";
2799           throw INTERP_KERNEL::Exception(oss.str().c_str());
2800         }
2801     }
2802   declareAsNew();
2803 }
2804
2805 /*!
2806  * Modify all elements of \a this array, so that
2807  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2808  * all values in \a this have to be >= 0 if val is \b not integer.
2809  *  \param [in] val - the value used to apply pow on all array elements.
2810  *  \throw If \a this is not allocated.
2811  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2812  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2813  *           modified.
2814  */
2815 void DataArrayDouble::applyPow(double val)
2816 {
2817   checkAllocated();
2818   double *ptr=getPointer();
2819   std::size_t nbOfElems=getNbOfElems();
2820   int val2=(int)val;
2821   bool isInt=((double)val2)==val;
2822   if(!isInt)
2823     {
2824       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2825         {
2826           if(*ptr>=0)
2827             *ptr=pow(*ptr,val);
2828           else
2829             {
2830               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2831               throw INTERP_KERNEL::Exception(oss.str().c_str());
2832             }
2833         }
2834     }
2835   else
2836     {
2837       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2838         *ptr=pow(*ptr,val2);
2839     }
2840   declareAsNew();
2841 }
2842
2843 /*!
2844  * Modify all elements of \a this array, so that
2845  * an element _x_ becomes \f$ val ^ x \f$.
2846  *  \param [in] val - the value used to apply pow on all array elements.
2847  *  \throw If \a this is not allocated.
2848  *  \throw If \a val < 0.
2849  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2850  *           array, all elements processed before detection of the zero element remain
2851  *           modified.
2852  */
2853 void DataArrayDouble::applyRPow(double val)
2854 {
2855   checkAllocated();
2856   if(val<0.)
2857     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2858   double *ptr=getPointer();
2859   std::size_t nbOfElems=getNbOfElems();
2860   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2861     *ptr=pow(val,*ptr);
2862   declareAsNew();
2863 }
2864
2865 /*!
2866  * Returns a new DataArrayDouble created from \a this one by applying \a
2867  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2868  * For more info see \ref MEDCouplingArrayApplyFunc
2869  *  \param [in] nbOfComp - number of components in the result array.
2870  *  \param [in] func - the \a FunctionToEvaluate declared as 
2871  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2872  *              where \a pos points to the first component of a tuple of \a this array
2873  *              and \a res points to the first component of a tuple of the result array.
2874  *              Note that length (number of components) of \a pos can differ from
2875  *              that of \a res.
2876  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2877  *          same number of tuples as \a this array.
2878  *          The caller is to delete this result array using decrRef() as it is no more
2879  *          needed.
2880  *  \throw If \a this is not allocated.
2881  *  \throw If \a func returns \a false.
2882  */
2883 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2884 {
2885   checkAllocated();
2886   DataArrayDouble *newArr=DataArrayDouble::New();
2887   int nbOfTuples=getNumberOfTuples();
2888   int oldNbOfComp=getNumberOfComponents();
2889   newArr->alloc(nbOfTuples,nbOfComp);
2890   const double *ptr=getConstPointer();
2891   double *ptrToFill=newArr->getPointer();
2892   for(int i=0;i<nbOfTuples;i++)
2893     {
2894       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2895         {
2896           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2897           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2898           oss << ") : Evaluation of function failed !";
2899           newArr->decrRef();
2900           throw INTERP_KERNEL::Exception(oss.str().c_str());
2901         }
2902     }
2903   return newArr;
2904 }
2905
2906 /*!
2907  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2908  * tuple of \a this array. Textual data is not copied.
2909  * For more info see \ref MEDCouplingArrayApplyFunc1.
2910  *  \param [in] nbOfComp - number of components in the result array.
2911  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2912  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2913  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2914  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2915  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2916  *          same number of tuples as \a this array and \a nbOfComp components.
2917  *          The caller is to delete this result array using decrRef() as it is no more
2918  *          needed.
2919  *  \throw If \a this is not allocated.
2920  *  \throw If computing \a func fails.
2921  */
2922 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2923 {
2924   INTERP_KERNEL::ExprParser expr(func);
2925   expr.parse();
2926   std::set<std::string> vars;
2927   expr.getTrueSetOfVars(vars);
2928   std::vector<std::string> varsV(vars.begin(),vars.end());
2929   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2930 }
2931
2932 /*!
2933  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2934  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2935  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2936  *
2937  * For more info see \ref MEDCouplingArrayApplyFunc0.
2938  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2939  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2940  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2941  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
2942  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2943  *          same number of tuples and components as \a this array.
2944  *          The caller is to delete this result array using decrRef() as it is no more
2945  *          needed.
2946  *  \sa applyFuncOnThis
2947  *  \throw If \a this is not allocated.
2948  *  \throw If computing \a func fails.
2949  */
2950 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2951 {
2952   int nbOfComp(getNumberOfComponents());
2953   if(nbOfComp<=0)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2955   checkAllocated();
2956   int nbOfTuples(getNumberOfTuples());
2957   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2958   newArr->alloc(nbOfTuples,nbOfComp);
2959   INTERP_KERNEL::ExprParser expr(func);
2960   expr.parse();
2961   std::set<std::string> vars;
2962   expr.getTrueSetOfVars(vars);
2963   if((int)vars.size()>1)
2964     {
2965       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 : ";
2966       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2967       throw INTERP_KERNEL::Exception(oss.str().c_str());
2968     }
2969   if(vars.empty())
2970     {
2971       expr.prepareFastEvaluator();
2972       newArr->rearrange(1);
2973       newArr->fillWithValue(expr.evaluateDouble());
2974       newArr->rearrange(nbOfComp);
2975       return newArr.retn();
2976     }
2977   std::vector<std::string> vars2(vars.begin(),vars.end());
2978   double buff,*ptrToFill(newArr->getPointer());
2979   const double *ptr(begin());
2980   std::vector<double> stck;
2981   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2982   expr.prepareFastEvaluator();
2983   if(!isSafe)
2984     {
2985       for(int i=0;i<nbOfTuples;i++)
2986         {
2987           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2988             {
2989               buff=*ptr;
2990               expr.evaluateDoubleInternal(stck);
2991               *ptrToFill=stck.back();
2992               stck.pop_back();
2993             }
2994         }
2995     }
2996   else
2997     {
2998       for(int i=0;i<nbOfTuples;i++)
2999         {
3000           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3001             {
3002               buff=*ptr;
3003               try
3004               {
3005                   expr.evaluateDoubleInternalSafe(stck);
3006               }
3007               catch(INTERP_KERNEL::Exception& e)
3008               {
3009                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3010                   oss << buff;
3011                   oss << ") : Evaluation of function failed !" << e.what();
3012                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3013               }
3014               *ptrToFill=stck.back();
3015               stck.pop_back();
3016             }
3017         }
3018     }
3019   return newArr.retn();
3020 }
3021
3022 /*!
3023  * This method is a non const method that modify the array in \a this.
3024  * This method only works on one component array. It means that function \a func must
3025  * contain at most one variable.
3026  * This method is a specialization of applyFunc method with one parameter on one component array.
3027  *
3028  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3029  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3030  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3031  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3032  *
3033  * \sa applyFunc
3034  */
3035 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3036 {
3037   int nbOfComp(getNumberOfComponents());
3038   if(nbOfComp<=0)
3039     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3040   checkAllocated();
3041   int nbOfTuples(getNumberOfTuples());
3042   INTERP_KERNEL::ExprParser expr(func);
3043   expr.parse();
3044   std::set<std::string> vars;
3045   expr.getTrueSetOfVars(vars);
3046   if((int)vars.size()>1)
3047     {
3048       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 : ";
3049       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3050       throw INTERP_KERNEL::Exception(oss.str().c_str());
3051     }
3052   if(vars.empty())
3053     {
3054       expr.prepareFastEvaluator();
3055       std::vector<std::string> compInfo(getInfoOnComponents());
3056       rearrange(1);
3057       fillWithValue(expr.evaluateDouble());
3058       rearrange(nbOfComp);
3059       setInfoOnComponents(compInfo);
3060       return ;
3061     }
3062   std::vector<std::string> vars2(vars.begin(),vars.end());
3063   double buff,*ptrToFill(getPointer());
3064   const double *ptr(begin());
3065   std::vector<double> stck;
3066   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3067   expr.prepareFastEvaluator();
3068   if(!isSafe)
3069     {
3070       for(int i=0;i<nbOfTuples;i++)
3071         {
3072           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3073             {
3074               buff=*ptr;
3075               expr.evaluateDoubleInternal(stck);
3076               *ptrToFill=stck.back();
3077               stck.pop_back();
3078             }
3079         }
3080     }
3081   else
3082     {
3083       for(int i=0;i<nbOfTuples;i++)
3084         {
3085           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3086             {
3087               buff=*ptr;
3088               try
3089               {
3090                   expr.evaluateDoubleInternalSafe(stck);
3091               }
3092               catch(INTERP_KERNEL::Exception& e)
3093               {
3094                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3095                   oss << buff;
3096                   oss << ") : Evaluation of function failed !" << e.what();
3097                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3098               }
3099               *ptrToFill=stck.back();
3100               stck.pop_back();
3101             }
3102         }
3103     }
3104 }
3105
3106 /*!
3107  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3108  * tuple of \a this array. Textual data is not copied.
3109  * For more info see \ref MEDCouplingArrayApplyFunc2.
3110  *  \param [in] nbOfComp - number of components in the result array.
3111  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3112  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3113  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3114  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3115  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3116  *          same number of tuples as \a this array.
3117  *          The caller is to delete this result array using decrRef() as it is no more
3118  *          needed.
3119  *  \throw If \a this is not allocated.
3120  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3121  *  \throw If computing \a func fails.
3122  */
3123 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3124 {
3125   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3126 }
3127
3128 /*!
3129  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3130  * tuple of \a this array. Textual data is not copied.
3131  * For more info see \ref MEDCouplingArrayApplyFunc3.
3132  *  \param [in] nbOfComp - number of components in the result array.
3133  *  \param [in] varsOrder - sequence of vars defining their order.
3134  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3135  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3136  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3137  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3138  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3139  *          same number of tuples as \a this array.
3140  *          The caller is to delete this result array using decrRef() as it is no more
3141  *          needed.
3142  *  \throw If \a this is not allocated.
3143  *  \throw If \a func contains vars not in \a varsOrder.
3144  *  \throw If computing \a func fails.
3145  */
3146 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3147 {
3148   if(nbOfComp<=0)
3149     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3150   std::vector<std::string> varsOrder2(varsOrder);
3151   int oldNbOfComp(getNumberOfComponents());
3152   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3153     varsOrder2.push_back(std::string());
3154   checkAllocated();
3155   int nbOfTuples(getNumberOfTuples());
3156   INTERP_KERNEL::ExprParser expr(func);
3157   expr.parse();
3158   std::set<std::string> vars;
3159   expr.getTrueSetOfVars(vars);
3160   if((int)vars.size()>oldNbOfComp)
3161     {
3162       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3163       oss << vars.size() << " variables : ";
3164       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3165       throw INTERP_KERNEL::Exception(oss.str().c_str());
3166     }
3167   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3168   newArr->alloc(nbOfTuples,nbOfComp);
3169   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3170   double *buffPtr(buff),*ptrToFill;
3171   std::vector<double> stck;
3172   for(int iComp=0;iComp<nbOfComp;iComp++)
3173     {
3174       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3175       expr.prepareFastEvaluator();
3176       const double *ptr(getConstPointer());
3177       ptrToFill=newArr->getPointer()+iComp;
3178       if(!isSafe)
3179         {
3180           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3181             {
3182               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3183               expr.evaluateDoubleInternal(stck);
3184               *ptrToFill=stck.back();
3185               stck.pop_back();
3186             }
3187         }
3188       else
3189         {
3190           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3191             {
3192               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3193               try
3194               {
3195                   expr.evaluateDoubleInternalSafe(stck);
3196                   *ptrToFill=stck.back();
3197                   stck.pop_back();
3198               }
3199               catch(INTERP_KERNEL::Exception& e)
3200               {
3201                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3202                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3203                   oss << ") : Evaluation of function failed !" << e.what();
3204                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3205               }
3206             }
3207         }
3208     }
3209   return newArr.retn();
3210 }
3211
3212 void DataArrayDouble::applyFuncFast32(const std::string& func)
3213 {
3214   checkAllocated();
3215   INTERP_KERNEL::ExprParser expr(func);
3216   expr.parse();
3217   char *funcStr=expr.compileX86();
3218   MYFUNCPTR funcPtr;
3219   *((void **)&funcPtr)=funcStr;//he he...
3220   //
3221   double *ptr=getPointer();
3222   int nbOfComp=getNumberOfComponents();
3223   int nbOfTuples=getNumberOfTuples();
3224   int nbOfElems=nbOfTuples*nbOfComp;
3225   for(int i=0;i<nbOfElems;i++,ptr++)
3226     *ptr=funcPtr(*ptr);
3227   declareAsNew();
3228 }
3229
3230 void DataArrayDouble::applyFuncFast64(const std::string& func)
3231 {
3232   checkAllocated();
3233   INTERP_KERNEL::ExprParser expr(func);
3234   expr.parse();
3235   char *funcStr=expr.compileX86_64();
3236   MYFUNCPTR funcPtr;
3237   *((void **)&funcPtr)=funcStr;//he he...
3238   //
3239   double *ptr=getPointer();
3240   int nbOfComp=getNumberOfComponents();
3241   int nbOfTuples=getNumberOfTuples();
3242   int nbOfElems=nbOfTuples*nbOfComp;
3243   for(int i=0;i<nbOfElems;i++,ptr++)
3244     *ptr=funcPtr(*ptr);
3245   declareAsNew();
3246 }
3247
3248 /*!
3249  * \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.
3250  */
3251 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3252 {
3253   checkAllocated();
3254   if(getNumberOfComponents()!=3)
3255     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3256   int nbTuples(getNumberOfTuples());
3257   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3258   ret->alloc(nbTuples,3);
3259   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3260   return ret;
3261 }
3262
3263 DataArrayDoubleIterator *DataArrayDouble::iterator()
3264 {
3265   return new DataArrayDoubleIterator(this);
3266 }
3267
3268 /*!
3269  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3270  * array whose values are within a given range. Textual data is not copied.
3271  *  \param [in] vmin - a lowest acceptable value (included).
3272  *  \param [in] vmax - a greatest acceptable value (included).
3273  *  \return DataArrayInt * - the new instance of DataArrayInt.
3274  *          The caller is to delete this result array using decrRef() as it is no more
3275  *          needed.
3276  *  \throw If \a this->getNumberOfComponents() != 1.
3277  *
3278  *  \sa DataArrayDouble::findIdsNotInRange
3279  *
3280  *  \if ENABLE_EXAMPLES
3281  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3282  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3283  *  \endif
3284  */
3285 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3286 {
3287   checkAllocated();
3288   if(getNumberOfComponents()!=1)
3289     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3290   const double *cptr(begin());
3291   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3292   int nbOfTuples(getNumberOfTuples());
3293   for(int i=0;i<nbOfTuples;i++,cptr++)
3294     if(*cptr>=vmin && *cptr<=vmax)
3295       ret->pushBackSilent(i);
3296   return ret.retn();
3297 }
3298
3299 /*!
3300  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3301  * array whose values are not within a given range. Textual data is not copied.
3302  *  \param [in] vmin - a lowest not acceptable value (excluded).
3303  *  \param [in] vmax - a greatest not acceptable value (excluded).
3304  *  \return DataArrayInt * - the new instance of DataArrayInt.
3305  *          The caller is to delete this result array using decrRef() as it is no more
3306  *          needed.
3307  *  \throw If \a this->getNumberOfComponents() != 1.
3308  *
3309  *  \sa DataArrayDouble::findIdsInRange
3310  */
3311 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3312 {
3313   checkAllocated();
3314   if(getNumberOfComponents()!=1)
3315     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3316   const double *cptr(begin());
3317   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3318   int nbOfTuples(getNumberOfTuples());
3319   for(int i=0;i<nbOfTuples;i++,cptr++)
3320     if(*cptr<vmin || *cptr>vmax)
3321       ret->pushBackSilent(i);
3322   return ret.retn();
3323 }
3324
3325 /*!
3326  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3327  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3328  * the number of component in the result array is same as that of each of given arrays.
3329  * Info on components is copied from the first of the given arrays. Number of components
3330  * in the given arrays must be  the same.
3331  *  \param [in] a1 - an array to include in the result array.
3332  *  \param [in] a2 - another array to include in the result array.
3333  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3334  *          The caller is to delete this result array using decrRef() as it is no more
3335  *          needed.
3336  *  \throw If both \a a1 and \a a2 are NULL.
3337  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3338  */
3339 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3340 {
3341   std::vector<const DataArrayDouble *> tmp(2);
3342   tmp[0]=a1; tmp[1]=a2;
3343   return Aggregate(tmp);
3344 }
3345
3346 /*!
3347  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3348  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3349  * the number of component in the result array is same as that of each of given arrays.
3350  * Info on components is copied from the first of the given arrays. Number of components
3351  * in the given arrays must be  the same.
3352  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3353  * not the object itself.
3354  *  \param [in] arr - a sequence of arrays to include in the result array.
3355  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3356  *          The caller is to delete this result array using decrRef() as it is no more
3357  *          needed.
3358  *  \throw If all arrays within \a arr are NULL.
3359  *  \throw If getNumberOfComponents() of arrays within \a arr.
3360  */
3361 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3362 {
3363   std::vector<const DataArrayDouble *> a;
3364   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3365     if(*it4)
3366       a.push_back(*it4);
3367   if(a.empty())
3368     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3369   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3370   int nbOfComp=(*it)->getNumberOfComponents();
3371   int nbt=(*it++)->getNumberOfTuples();
3372   for(int i=1;it!=a.end();it++,i++)
3373     {
3374       if((*it)->getNumberOfComponents()!=nbOfComp)
3375         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3376       nbt+=(*it)->getNumberOfTuples();
3377     }
3378   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3379   ret->alloc(nbt,nbOfComp);
3380   double *pt=ret->getPointer();
3381   for(it=a.begin();it!=a.end();it++)
3382     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3383   ret->copyStringInfoFrom(*(a[0]));
3384   return ret.retn();
3385 }
3386
3387 /*!
3388  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3389  * of components in the result array is a sum of the number of components of given arrays
3390  * and (2) the number of tuples in the result array is same as that of each of given
3391  * arrays. In other words the i-th tuple of result array includes all components of
3392  * i-th tuples of all given arrays.
3393  * Number of tuples in the given arrays must be  the same.
3394  *  \param [in] a1 - an array to include in the result array.
3395  *  \param [in] a2 - another array to include in the result array.
3396  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3397  *          The caller is to delete this result array using decrRef() as it is no more
3398  *          needed.
3399  *  \throw If both \a a1 and \a a2 are NULL.
3400  *  \throw If any given array is not allocated.
3401  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3402  */
3403 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3404 {
3405   std::vector<const DataArrayDouble *> arr(2);
3406   arr[0]=a1; arr[1]=a2;
3407   return Meld(arr);
3408 }
3409
3410 /*!
3411  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3412  * of components in the result array is a sum of the number of components of given arrays
3413  * and (2) the number of tuples in the result array is same as that of each of given
3414  * arrays. In other words the i-th tuple of result array includes all components of
3415  * i-th tuples of all given arrays.
3416  * Number of tuples in the given arrays must be  the same.
3417  *  \param [in] arr - a sequence of arrays to include in the result array.
3418  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3419  *          The caller is to delete this result array using decrRef() as it is no more
3420  *          needed.
3421  *  \throw If all arrays within \a arr are NULL.
3422  *  \throw If any given array is not allocated.
3423  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3424  */
3425 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3426 {
3427   std::vector<const DataArrayDouble *> a;
3428   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3429     if(*it4)
3430       a.push_back(*it4);
3431   if(a.empty())
3432     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3433   std::vector<const DataArrayDouble *>::const_iterator it;
3434   for(it=a.begin();it!=a.end();it++)
3435     (*it)->checkAllocated();
3436   it=a.begin();
3437   int nbOfTuples=(*it)->getNumberOfTuples();
3438   std::vector<int> nbc(a.size());
3439   std::vector<const double *> pts(a.size());
3440   nbc[0]=(*it)->getNumberOfComponents();
3441   pts[0]=(*it++)->getConstPointer();
3442   for(int i=1;it!=a.end();it++,i++)
3443     {
3444       if(nbOfTuples!=(*it)->getNumberOfTuples())
3445         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3446       nbc[i]=(*it)->getNumberOfComponents();
3447       pts[i]=(*it)->getConstPointer();
3448     }
3449   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3450   DataArrayDouble *ret=DataArrayDouble::New();
3451   ret->alloc(nbOfTuples,totalNbOfComp);
3452   double *retPtr=ret->getPointer();
3453   for(int i=0;i<nbOfTuples;i++)
3454     for(int j=0;j<(int)a.size();j++)
3455       {
3456         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3457         pts[j]+=nbc[j];
3458       }
3459   int k=0;
3460   for(int i=0;i<(int)a.size();i++)
3461     for(int j=0;j<nbc[i];j++,k++)
3462       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3463   return ret;
3464 }
3465
3466 /*!
3467  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3468  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3469  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3470  * Info on components and name is copied from the first of the given arrays.
3471  * Number of tuples and components in the given arrays must be the same.
3472  *  \param [in] a1 - a given array.
3473  *  \param [in] a2 - another given array.
3474  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3475  *          The caller is to delete this result array using decrRef() as it is no more
3476  *          needed.
3477  *  \throw If either \a a1 or \a a2 is NULL.
3478  *  \throw If any given array is not allocated.
3479  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3480  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3481  */
3482 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3483 {
3484   if(!a1 || !a2)
3485     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3486   a1->checkAllocated();
3487   a2->checkAllocated();
3488   int nbOfComp=a1->getNumberOfComponents();
3489   if(nbOfComp!=a2->getNumberOfComponents())
3490     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3491   int nbOfTuple=a1->getNumberOfTuples();
3492   if(nbOfTuple!=a2->getNumberOfTuples())
3493     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3494   DataArrayDouble *ret=DataArrayDouble::New();
3495   ret->alloc(nbOfTuple,1);
3496   double *retPtr=ret->getPointer();
3497   const double *a1Ptr=a1->getConstPointer();
3498   const double *a2Ptr=a2->getConstPointer();
3499   for(int i=0;i<nbOfTuple;i++)
3500     {
3501       double sum=0.;
3502       for(int j=0;j<nbOfComp;j++)
3503         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3504       retPtr[i]=sum;
3505     }
3506   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3507   ret->setName(a1->getName());
3508   return ret;
3509 }
3510
3511 /*!
3512  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3513  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3514  * product of two vectors defined by the i-th tuples of given arrays.
3515  * Info on components is copied from the first of the given arrays.
3516  * Number of tuples in the given arrays must be the same.
3517  * Number of components in the given arrays must be 3.
3518  *  \param [in] a1 - a given array.
3519  *  \param [in] a2 - another given array.
3520  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3521  *          The caller is to delete this result array using decrRef() as it is no more
3522  *          needed.
3523  *  \throw If either \a a1 or \a a2 is NULL.
3524  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3525  *  \throw If \a a1->getNumberOfComponents() != 3
3526  *  \throw If \a a2->getNumberOfComponents() != 3
3527  */
3528 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3529 {
3530   if(!a1 || !a2)
3531     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3532   int nbOfComp=a1->getNumberOfComponents();
3533   if(nbOfComp!=a2->getNumberOfComponents())
3534     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3535   if(nbOfComp!=3)
3536     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3537   int nbOfTuple=a1->getNumberOfTuples();
3538   if(nbOfTuple!=a2->getNumberOfTuples())
3539     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3540   DataArrayDouble *ret=DataArrayDouble::New();
3541   ret->alloc(nbOfTuple,3);
3542   double *retPtr=ret->getPointer();
3543   const double *a1Ptr=a1->getConstPointer();
3544   const double *a2Ptr=a2->getConstPointer();
3545   for(int i=0;i<nbOfTuple;i++)
3546     {
3547       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3548       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3549       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3550     }
3551   ret->copyStringInfoFrom(*a1);
3552   return ret;
3553 }
3554
3555 /*!
3556  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3557  * Info on components is copied from the first of the given arrays.
3558  * Number of tuples and components in the given arrays must be the same.
3559  *  \param [in] a1 - an array to compare values with another one.
3560  *  \param [in] a2 - another array to compare values with the first one.
3561  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3562  *          The caller is to delete this result array using decrRef() as it is no more
3563  *          needed.
3564  *  \throw If either \a a1 or \a a2 is NULL.
3565  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3566  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3567  */
3568 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3569 {
3570   if(!a1 || !a2)
3571     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3572   int nbOfComp=a1->getNumberOfComponents();
3573   if(nbOfComp!=a2->getNumberOfComponents())
3574     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3575   int nbOfTuple=a1->getNumberOfTuples();
3576   if(nbOfTuple!=a2->getNumberOfTuples())
3577     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3578   DataArrayDouble *ret=DataArrayDouble::New();
3579   ret->alloc(nbOfTuple,nbOfComp);
3580   double *retPtr=ret->getPointer();
3581   const double *a1Ptr=a1->getConstPointer();
3582   const double *a2Ptr=a2->getConstPointer();
3583   int nbElem=nbOfTuple*nbOfComp;
3584   for(int i=0;i<nbElem;i++)
3585     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3586   ret->copyStringInfoFrom(*a1);
3587   return ret;
3588 }
3589
3590 /*!
3591  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3592  * Info on components is copied from the first of the given arrays.
3593  * Number of tuples and components in the given arrays must be the same.
3594  *  \param [in] a1 - an array to compare values with another one.
3595  *  \param [in] a2 - another array to compare values with the first one.
3596  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3597  *          The caller is to delete this result array using decrRef() as it is no more
3598  *          needed.
3599  *  \throw If either \a a1 or \a a2 is NULL.
3600  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3601  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3602  */
3603 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3604 {
3605   if(!a1 || !a2)
3606     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3607   int nbOfComp=a1->getNumberOfComponents();
3608   if(nbOfComp!=a2->getNumberOfComponents())
3609     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3610   int nbOfTuple=a1->getNumberOfTuples();
3611   if(nbOfTuple!=a2->getNumberOfTuples())
3612     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3613   DataArrayDouble *ret=DataArrayDouble::New();
3614   ret->alloc(nbOfTuple,nbOfComp);
3615   double *retPtr=ret->getPointer();
3616   const double *a1Ptr=a1->getConstPointer();
3617   const double *a2Ptr=a2->getConstPointer();
3618   int nbElem=nbOfTuple*nbOfComp;
3619   for(int i=0;i<nbElem;i++)
3620     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3621   ret->copyStringInfoFrom(*a1);
3622   return ret;
3623 }
3624
3625 /*!
3626  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3627  * valid cases.
3628  * 1.  The arrays have same number of tuples and components. Then each value of
3629  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3630  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3631  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3632  *   component. Then
3633  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3634  * 3.  The arrays have same number of components and one array, say _a2_, has one
3635  *   tuple. Then
3636  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3637  *
3638  * Info on components is copied either from the first array (in the first case) or from
3639  * the array with maximal number of elements (getNbOfElems()).
3640  *  \param [in] a1 - an array to sum up.
3641  *  \param [in] a2 - another array to sum up.
3642  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3643  *          The caller is to delete this result array using decrRef() as it is no more
3644  *          needed.
3645  *  \throw If either \a a1 or \a a2 is NULL.
3646  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3647  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3648  *         none of them has number of tuples or components equal to 1.
3649  */
3650 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3651 {
3652   if(!a1 || !a2)
3653     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3654   int nbOfTuple=a1->getNumberOfTuples();
3655   int nbOfTuple2=a2->getNumberOfTuples();
3656   int nbOfComp=a1->getNumberOfComponents();
3657   int nbOfComp2=a2->getNumberOfComponents();
3658   MCAuto<DataArrayDouble> ret=0;
3659   if(nbOfTuple==nbOfTuple2)
3660     {
3661       if(nbOfComp==nbOfComp2)
3662         {
3663           ret=DataArrayDouble::New();
3664           ret->alloc(nbOfTuple,nbOfComp);
3665           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3666           ret->copyStringInfoFrom(*a1);
3667         }
3668       else
3669         {
3670           int nbOfCompMin,nbOfCompMax;
3671           const DataArrayDouble *aMin, *aMax;
3672           if(nbOfComp>nbOfComp2)
3673             {
3674               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3675               aMin=a2; aMax=a1;
3676             }
3677           else
3678             {
3679               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3680               aMin=a1; aMax=a2;
3681             }
3682           if(nbOfCompMin==1)
3683             {
3684               ret=DataArrayDouble::New();
3685               ret->alloc(nbOfTuple,nbOfCompMax);
3686               const double *aMinPtr=aMin->getConstPointer();
3687               const double *aMaxPtr=aMax->getConstPointer();
3688               double *res=ret->getPointer();
3689               for(int i=0;i<nbOfTuple;i++)
3690                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3691               ret->copyStringInfoFrom(*aMax);
3692             }
3693           else
3694             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3695         }
3696     }
3697   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3698     {
3699       if(nbOfComp==nbOfComp2)
3700         {
3701           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3702           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3703           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3704           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3705           ret=DataArrayDouble::New();
3706           ret->alloc(nbOfTupleMax,nbOfComp);
3707           double *res=ret->getPointer();
3708           for(int i=0;i<nbOfTupleMax;i++)
3709             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3710           ret->copyStringInfoFrom(*aMax);
3711         }
3712       else
3713         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3714     }
3715   else
3716     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3717   return ret.retn();
3718 }
3719
3720 /*!
3721  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3722  * valid cases.
3723  * 1.  The arrays have same number of tuples and components. Then each value of
3724  *   \a other array is added to the corresponding value of \a this array, i.e.:
3725  *   _a_ [ i, j ] += _other_ [ i, j ].
3726  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3727  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3728  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3729  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3730  *
3731  *  \param [in] other - an array to add to \a this one.
3732  *  \throw If \a other is NULL.
3733  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3734  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3735  *         \a other has number of both tuples and components not equal to 1.
3736  */
3737 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3738 {
3739   if(!other)
3740     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3741   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3742   checkAllocated();
3743   other->checkAllocated();
3744   int nbOfTuple=getNumberOfTuples();
3745   int nbOfTuple2=other->getNumberOfTuples();
3746   int nbOfComp=getNumberOfComponents();
3747   int nbOfComp2=other->getNumberOfComponents();
3748   if(nbOfTuple==nbOfTuple2)
3749     {
3750       if(nbOfComp==nbOfComp2)
3751         {
3752           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3753         }
3754       else if(nbOfComp2==1)
3755         {
3756           double *ptr=getPointer();
3757           const double *ptrc=other->getConstPointer();
3758           for(int i=0;i<nbOfTuple;i++)
3759             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3760         }
3761       else
3762         throw INTERP_KERNEL::Exception(msg);
3763     }
3764   else if(nbOfTuple2==1)
3765     {
3766       if(nbOfComp2==nbOfComp)
3767         {
3768           double *ptr=getPointer();
3769           const double *ptrc=other->getConstPointer();
3770           for(int i=0;i<nbOfTuple;i++)
3771             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3772         }
3773       else
3774         throw INTERP_KERNEL::Exception(msg);
3775     }
3776   else
3777     throw INTERP_KERNEL::Exception(msg);
3778   declareAsNew();
3779 }
3780
3781 /*!
3782  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3783  * valid cases.
3784  * 1.  The arrays have same number of tuples and components. Then each value of
3785  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3786  *   _a_ [ i, j ] -= _other_ [ i, j ].
3787  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3788  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3789  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3790  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3791  *
3792  *  \param [in] other - an array to subtract from \a this one.
3793  *  \throw If \a other is NULL.
3794  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3795  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3796  *         \a other has number of both tuples and components not equal to 1.
3797  */
3798 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3799 {
3800   if(!other)
3801     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3802   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3803   checkAllocated();
3804   other->checkAllocated();
3805   int nbOfTuple=getNumberOfTuples();
3806   int nbOfTuple2=other->getNumberOfTuples();
3807   int nbOfComp=getNumberOfComponents();
3808   int nbOfComp2=other->getNumberOfComponents();
3809   if(nbOfTuple==nbOfTuple2)
3810     {
3811       if(nbOfComp==nbOfComp2)
3812         {
3813           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3814         }
3815       else if(nbOfComp2==1)
3816         {
3817           double *ptr=getPointer();
3818           const double *ptrc=other->getConstPointer();
3819           for(int i=0;i<nbOfTuple;i++)
3820             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3821         }
3822       else
3823         throw INTERP_KERNEL::Exception(msg);
3824     }
3825   else if(nbOfTuple2==1)
3826     {
3827       if(nbOfComp2==nbOfComp)
3828         {
3829           double *ptr=getPointer();
3830           const double *ptrc=other->getConstPointer();
3831           for(int i=0;i<nbOfTuple;i++)
3832             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3833         }
3834       else
3835         throw INTERP_KERNEL::Exception(msg);
3836     }
3837   else
3838     throw INTERP_KERNEL::Exception(msg);
3839   declareAsNew();
3840 }
3841
3842 /*!
3843  * Divide values of \a this array by values of another DataArrayDouble. There are 3
3844  * valid cases.
3845  * 1.  The arrays have same number of tuples and components. Then each value of
3846  *    \a this array is divided by the corresponding value of \a other one, i.e.:
3847  *   _a_ [ i, j ] /= _other_ [ i, j ].
3848  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3849  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
3850  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3851  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
3852  *
3853  *  \warning No check of division by zero is performed!
3854  *  \param [in] other - an array to divide \a this one by.
3855  *  \throw If \a other is NULL.
3856  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3857  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3858  *         \a other has number of both tuples and components not equal to 1.
3859  */
3860 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
3861 {
3862   if(!other)
3863     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
3864   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
3865   checkAllocated();
3866   other->checkAllocated();
3867   int nbOfTuple=getNumberOfTuples();
3868   int nbOfTuple2=other->getNumberOfTuples();
3869   int nbOfComp=getNumberOfComponents();
3870   int nbOfComp2=other->getNumberOfComponents();
3871   if(nbOfTuple==nbOfTuple2)
3872     {
3873       if(nbOfComp==nbOfComp2)
3874         {
3875           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
3876         }
3877       else if(nbOfComp2==1)
3878         {
3879           double *ptr=getPointer();
3880           const double *ptrc=other->getConstPointer();
3881           for(int i=0;i<nbOfTuple;i++)
3882             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
3883         }
3884       else
3885         throw INTERP_KERNEL::Exception(msg);
3886     }
3887   else if(nbOfTuple2==1)
3888     {
3889       if(nbOfComp2==nbOfComp)
3890         {
3891           double *ptr=getPointer();
3892           const double *ptrc=other->getConstPointer();
3893           for(int i=0;i<nbOfTuple;i++)
3894             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
3895         }
3896       else
3897         throw INTERP_KERNEL::Exception(msg);
3898     }
3899   else
3900     throw INTERP_KERNEL::Exception(msg);
3901   declareAsNew();
3902 }
3903
3904 /*!
3905  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3906  * valid cases.
3907  *
3908  *  \param [in] a1 - an array to pow up.
3909  *  \param [in] a2 - another array to sum up.
3910  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3911  *          The caller is to delete this result array using decrRef() as it is no more
3912  *          needed.
3913  *  \throw If either \a a1 or \a a2 is NULL.
3914  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3915  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3916  *  \throw If there is a negative value in \a a1.
3917  */
3918 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3919 {
3920   if(!a1 || !a2)
3921     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3922   int nbOfTuple=a1->getNumberOfTuples();
3923   int nbOfTuple2=a2->getNumberOfTuples();
3924   int nbOfComp=a1->getNumberOfComponents();
3925   int nbOfComp2=a2->getNumberOfComponents();
3926   if(nbOfTuple!=nbOfTuple2)
3927     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3928   if(nbOfComp!=1 || nbOfComp2!=1)
3929     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3930   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3931   const double *ptr1(a1->begin()),*ptr2(a2->begin());
3932   double *ptr=ret->getPointer();
3933   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3934     {
3935       if(*ptr1>=0)
3936         {
3937           *ptr=pow(*ptr1,*ptr2);
3938         }
3939       else
3940         {
3941           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3942           throw INTERP_KERNEL::Exception(oss.str().c_str());
3943         }
3944     }
3945   return ret.retn();
3946 }
3947
3948 /*!
3949  * Apply pow on values of another DataArrayDouble to values of \a this one.
3950  *
3951  *  \param [in] other - an array to pow to \a this one.
3952  *  \throw If \a other is NULL.
3953  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3954  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3955  *  \throw If there is a negative value in \a this.
3956  */
3957 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3958 {
3959   if(!other)
3960     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3961   int nbOfTuple=getNumberOfTuples();
3962   int nbOfTuple2=other->getNumberOfTuples();
3963   int nbOfComp=getNumberOfComponents();
3964   int nbOfComp2=other->getNumberOfComponents();
3965   if(nbOfTuple!=nbOfTuple2)
3966     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3967   if(nbOfComp!=1 || nbOfComp2!=1)
3968     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3969   double *ptr=getPointer();
3970   const double *ptrc=other->begin();
3971   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3972     {
3973       if(*ptr>=0)
3974         *ptr=pow(*ptr,*ptrc);
3975       else
3976         {
3977           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3978           throw INTERP_KERNEL::Exception(oss.str().c_str());
3979         }
3980     }
3981   declareAsNew();
3982 }
3983
3984 /*!
3985  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3986  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3987  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3988  *
3989  * \throw if \a this is not allocated.
3990  * \throw if \a this has not exactly one component.
3991  */
3992 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3993 {
3994   checkAllocated();
3995   if(getNumberOfComponents()!=1)
3996     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3997   int nbt(getNumberOfTuples());
3998   std::vector<bool> ret(nbt);
3999   const double *pt(begin());
4000   for(int i=0;i<nbt;i++)
4001     {
4002       if(fabs(pt[i])<eps)
4003         ret[i]=false;
4004       else if(fabs(pt[i]-1.)<eps)
4005         ret[i]=true;
4006       else
4007         {
4008           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4009           throw INTERP_KERNEL::Exception(oss.str().c_str());
4010         }
4011     }
4012   return ret;
4013 }
4014
4015 /*!
4016  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4017  * Server side.
4018  */
4019 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4020 {
4021   tinyInfo.resize(2);
4022   if(isAllocated())
4023     {
4024       tinyInfo[0]=getNumberOfTuples();
4025       tinyInfo[1]=getNumberOfComponents();
4026     }
4027   else
4028     {
4029       tinyInfo[0]=-1;
4030       tinyInfo[1]=-1;
4031     }
4032 }
4033
4034 /*!
4035  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4036  * Server side.
4037  */
4038 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4039 {
4040   if(isAllocated())
4041     {
4042       int nbOfCompo=getNumberOfComponents();
4043       tinyInfo.resize(nbOfCompo+1);
4044       tinyInfo[0]=getName();
4045       for(int i=0;i<nbOfCompo;i++)
4046         tinyInfo[i+1]=getInfoOnComponent(i);
4047     }
4048   else
4049     {
4050       tinyInfo.resize(1);
4051       tinyInfo[0]=getName();
4052     }
4053 }
4054
4055 /*!
4056  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4057  * This method returns if a feeding is needed.
4058  */
4059 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4060 {
4061   int nbOfTuple=tinyInfoI[0];
4062   int nbOfComp=tinyInfoI[1];
4063   if(nbOfTuple!=-1 || nbOfComp!=-1)
4064     {
4065       alloc(nbOfTuple,nbOfComp);
4066       return true;
4067     }
4068   return false;
4069 }
4070
4071 /*!
4072  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4073  */
4074 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4075 {
4076   setName(tinyInfoS[0]);
4077   if(isAllocated())
4078     {
4079       int nbOfCompo=getNumberOfComponents();
4080       for(int i=0;i<nbOfCompo;i++)
4081         setInfoOnComponent(i,tinyInfoS[i+1]);
4082     }
4083 }
4084
4085 /*!
4086  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4087  * around an axe ( \a center, \a vect) and with angle \a angle.
4088  */
4089 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4090 {
4091   if(!center || !vect)
4092     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4093   double sina(sin(angle));
4094   double cosa(cos(angle));
4095   double vectorNorm[3];
4096   double matrix[9];
4097   double matrixTmp[9];
4098   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4099   if(norm<std::numeric_limits<double>::min())
4100     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4101   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4102   //rotation matrix computation
4103   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;
4104   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4105   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4106   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4107   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4108   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4109   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4110   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4111   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4112   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4113   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4114   //rotation matrix computed.
4115   double tmp[3];
4116   for(int i=0; i<nbNodes; i++)
4117     {
4118       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4119       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4120       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4121       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4122     }
4123 }
4124
4125 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4126 {
4127   double matrix[9],matrix2[9],matrix3[9];
4128   double vect[3],crossVect[3];
4129   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4130   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4131   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4132   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4133   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4134   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4135   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4136   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4137   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4138   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4139   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4140   for(int i=0;i<3;i++)
4141     for(int j=0;j<3;j++)
4142       {
4143         double val(0.);
4144         for(int k=0;k<3;k++)
4145           val+=matrix[3*i+k]*matrix2[3*k+j];
4146         matrix3[3*i+j]=val;
4147       }
4148   //rotation matrix computed.
4149   double tmp[3];
4150   for(int i=0; i<nbNodes; i++)
4151     {
4152       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4153       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4154       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4155       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4156     }
4157 }
4158
4159 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4160 {
4161   double vect[3],crossVect[3];
4162   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4163   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4164   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4165   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4166   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4167   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4168   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4169   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4170 }
4171
4172 /*!
4173  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4174  * around the center point \a center and with angle \a angle.
4175  */
4176 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4177 {
4178   double cosa=cos(angle);
4179   double sina=sin(angle);
4180   double matrix[4];
4181   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4182   double tmp[2];
4183   for(int i=0; i<nbNodes; i++)
4184     {
4185       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4186       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4187       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4188     }
4189 }
4190
4191 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
4192 {
4193 }
4194
4195 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
4196 {
4197 }
4198
4199
4200 std::string DataArrayDoubleTuple::repr() const
4201 {
4202   std::ostringstream oss; oss.precision(17); oss << "(";
4203   for(int i=0;i<_nb_of_compo-1;i++)
4204     oss << _pt[i] << ", ";
4205   oss << _pt[_nb_of_compo-1] << ")";
4206   return oss.str();
4207 }
4208
4209 double DataArrayDoubleTuple::doubleValue() const
4210 {
4211   return this->zeValue();
4212 }
4213
4214 /*!
4215  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4216  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4217  * 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
4218  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4219  */
4220 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4221 {
4222   return this->buildDA(nbOfTuples,nbOfCompo);
4223 }
4224
4225 /*!
4226  * Returns a new instance of DataArrayInt. The caller is to delete this array
4227  * using decrRef() as it is no more needed. 
4228  */
4229 DataArrayInt *DataArrayInt::New()
4230 {
4231   return new DataArrayInt;
4232 }
4233
4234 /*!
4235  * Returns the only one value in \a this, if and only if number of elements
4236  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4237  *  \return double - the sole value stored in \a this array.
4238  *  \throw If at least one of conditions stated above is not fulfilled.
4239  */
4240 int DataArrayInt::intValue() const
4241 {
4242   if(isAllocated())
4243     {
4244       if(getNbOfElems()==1)
4245         {
4246           return *getConstPointer();
4247         }
4248       else
4249         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4250     }
4251   else
4252     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4253 }
4254
4255 /*!
4256  * Returns an integer value characterizing \a this array, which is useful for a quick
4257  * comparison of many instances of DataArrayInt.
4258  *  \return int - the hash value.
4259  *  \throw If \a this is not allocated.
4260  */
4261 int DataArrayInt::getHashCode() const
4262 {
4263   checkAllocated();
4264   std::size_t nbOfElems=getNbOfElems();
4265   int ret=nbOfElems*65536;
4266   int delta=3;
4267   if(nbOfElems>48)
4268     delta=nbOfElems/8;
4269   int ret0=0;
4270   const int *pt=begin();
4271   for(std::size_t i=0;i<nbOfElems;i+=delta)
4272     ret0+=pt[i] & 0x1FFF;
4273   return ret+ret0;
4274 }
4275
4276 /*!
4277  * Returns a full copy of \a this. For more info on copying data arrays see
4278  * \ref MEDCouplingArrayBasicsCopyDeep.
4279  *  \return DataArrayInt * - a new instance of DataArrayInt.
4280  */
4281 DataArrayInt *DataArrayInt::deepCopy() const
4282 {
4283   return new DataArrayInt(*this);
4284 }
4285
4286 /*!
4287  * Returns either a \a deep or \a shallow copy of this array. For more info see
4288  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4289  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4290  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4291  *          == \a true) or \a this instance (if \a dCpy == \a false).
4292  */
4293 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4294 {
4295   return DataArrayTemplateClassic<int>::PerformCopyOrIncrRef(dCpy,*this);
4296 }
4297
4298 /*!
4299  * Assign zero to all values in \a this array. To know more on filling arrays see
4300  * \ref MEDCouplingArrayFill.
4301  * \throw If \a this is not allocated.
4302  */
4303 void DataArrayInt::fillWithZero()
4304 {
4305   fillWithValue(0);
4306 }
4307
4308 /*!
4309  * Set all values in \a this array so that the i-th element equals to \a init + i
4310  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4311  *  \param [in] init - value to assign to the first element of array.
4312  *  \throw If \a this->getNumberOfComponents() != 1
4313  *  \throw If \a this is not allocated.
4314  */
4315 void DataArrayInt::iota(int init)
4316 {
4317   checkAllocated();
4318   if(getNumberOfComponents()!=1)
4319     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4320   int *ptr=getPointer();
4321   int ntuples=getNumberOfTuples();
4322   for(int i=0;i<ntuples;i++)
4323     ptr[i]=init+i;
4324   declareAsNew();
4325 }
4326
4327 /*!
4328  * Returns a textual and human readable representation of \a this instance of
4329  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4330  * \return std::string - text describing \a this DataArrayInt.
4331  * 
4332  * \sa reprNotTooLong, reprZip
4333  */
4334 std::string DataArrayInt::repr() const
4335 {
4336   std::ostringstream ret;
4337   reprStream(ret);
4338   return ret.str();
4339 }
4340
4341 std::string DataArrayInt::reprZip() const
4342 {
4343   std::ostringstream ret;
4344   reprZipStream(ret);
4345   return ret.str();
4346 }
4347
4348 /*!
4349  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4350  * printed out to avoid to consume too much space in interpretor.
4351  * \sa repr
4352  */
4353 std::string DataArrayInt::reprNotTooLong() const
4354 {
4355   std::ostringstream ret;
4356   reprNotTooLongStream(ret);
4357   return ret.str();
4358 }
4359
4360 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4361 {
4362   static const char SPACE[4]={' ',' ',' ',' '};
4363   checkAllocated();
4364   std::string idt(indent,' ');
4365   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4366   if(byteArr)
4367     {
4368       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4369       if(std::string(type)=="Int32")
4370         {
4371           const char *data(reinterpret_cast<const char *>(begin()));
4372           std::size_t sz(getNbOfElems()*sizeof(int));
4373           byteArr->insertAtTheEnd(data,data+sz);
4374           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4375         }
4376       else if(std::string(type)=="Int8")
4377         {
4378           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4379           std::copy(begin(),end(),(char *)tmp);
4380           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4381           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4382         }
4383       else if(std::string(type)=="UInt8")
4384         {
4385           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4386           std::copy(begin(),end(),(unsigned char *)tmp);
4387           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4388           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4389         }
4390       else
4391         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4392     }
4393   else
4394     {
4395       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4396       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4397     }
4398   ofs << std::endl << idt << "</DataArray>\n";
4399 }
4400
4401 void DataArrayInt::reprStream(std::ostream& stream) const
4402 {
4403   stream << "Name of int array : \"" << _name << "\"\n";
4404   reprWithoutNameStream(stream);
4405 }
4406
4407 void DataArrayInt::reprZipStream(std::ostream& stream) const
4408 {
4409   stream << "Name of int array : \"" << _name << "\"\n";
4410   reprZipWithoutNameStream(stream);
4411 }
4412
4413 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4414 {
4415   stream << "Name of int array : \"" << _name << "\"\n";
4416   reprNotTooLongWithoutNameStream(stream);
4417 }
4418
4419 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4420 {
4421   DataArray::reprWithoutNameStream(stream);
4422   _mem.repr(getNumberOfComponents(),stream);
4423 }
4424
4425 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4426 {
4427   DataArray::reprWithoutNameStream(stream);
4428   _mem.reprZip(getNumberOfComponents(),stream);
4429 }
4430
4431 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4432 {
4433   DataArray::reprWithoutNameStream(stream);
4434   stream.precision(17);
4435   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4436 }
4437
4438 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4439 {
4440   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4441   const int *data=getConstPointer();
4442   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4443   if(nbTuples*nbComp>=1)
4444     {
4445       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4446       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4447       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4448       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4449     }
4450   else
4451     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4452   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4453 }
4454
4455 /*!
4456  * Method that gives a quick overvien of \a this for python.
4457  */
4458 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4459 {
4460   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4461   stream << "DataArrayInt C++ instance at " << this << ". ";
4462   if(isAllocated())
4463     {
4464       int nbOfCompo=(int)_info_on_compo.size();
4465       if(nbOfCompo>=1)
4466         {
4467           int nbOfTuples=getNumberOfTuples();
4468           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4469           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4470         }
4471       else
4472         stream << "Number of components : 0.";
4473     }
4474   else
4475     stream << "*** No data allocated ****";
4476 }
4477
4478 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4479 {
4480   const int *data=begin();
4481   int nbOfTuples=getNumberOfTuples();
4482   int nbOfCompo=(int)_info_on_compo.size();
4483   std::ostringstream oss2; oss2 << "[";
4484   std::string oss2Str(oss2.str());
4485   bool isFinished=true;
4486   for(int i=0;i<nbOfTuples && isFinished;i++)
4487     {
4488       if(nbOfCompo>1)
4489         {
4490           oss2 << "(";
4491           for(int j=0;j<nbOfCompo;j++,data++)
4492             {
4493               oss2 << *data;
4494               if(j!=nbOfCompo-1) oss2 << ", ";
4495             }
4496           oss2 << ")";
4497         }
4498       else
4499         oss2 << *data++;
4500       if(i!=nbOfTuples-1) oss2 << ", ";
4501       std::string oss3Str(oss2.str());
4502       if(oss3Str.length()<maxNbOfByteInRepr)
4503         oss2Str=oss3Str;
4504       else
4505         isFinished=false;
4506     }
4507   stream << oss2Str;
4508   if(!isFinished)
4509     stream << "... ";
4510   stream << "]";
4511 }
4512
4513 /*!
4514  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4515  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4516  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4517  *         to \a this array.
4518  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4519  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4520  *  \throw If \a this->getNumberOfComponents() != 1
4521  *  \throw If any value of \a this can't be used as a valid index for 
4522  *         [\a indArrBg, \a indArrEnd).
4523  *
4524  *  \sa changeValue
4525  */
4526 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4527 {
4528   checkAllocated();
4529   if(getNumberOfComponents()!=1)
4530     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4531   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4532   for(int i=0;i<nbOfTuples;i++,pt++)
4533     {
4534       if(*pt>=0 && *pt<nbElemsIn)
4535         *pt=indArrBg[*pt];
4536       else
4537         {
4538           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4539           throw INTERP_KERNEL::Exception(oss.str().c_str());
4540         }
4541     }
4542   declareAsNew();
4543 }
4544
4545 /*!
4546  * Computes distribution of values of \a this one-dimensional array between given value
4547  * ranges (casts). This method is typically useful for entity number spliting by types,
4548  * for example. 
4549  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4550  *           check of this is be done. If not, the result is not warranted. 
4551  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4552  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4553  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4554  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4555  *         should be more than every value in \a this array.
4556  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4557  *              the last value of \a arrBg is \a arrEnd[ -1 ].
4558  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4559  *         (same number of tuples and components), the caller is to delete 
4560  *         using decrRef() as it is no more needed.
4561  *         This array contains indices of ranges for every value of \a this array. I.e.
4562  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
4563  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
4564  *         this in which cast it holds.
4565  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4566  *         array, the caller is to delete using decrRef() as it is no more needed.
4567  *         This array contains ranks of values of \a this array within ranges
4568  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4569  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4570  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
4571  *         for each tuple its rank inside its cast. The rank is computed as difference
4572  *         between the value and the lowest value of range.
4573  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4574  *         ranges (casts) to which at least one value of \a this array belongs.
4575  *         Or, in other words, this param contains the casts that \a this contains.
4576  *         The caller is to delete this array using decrRef() as it is no more needed.
4577  *
4578  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4579  *            the output of this method will be : 
4580  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4581  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4582  * - \a castsPresent  : [0,1]
4583  *
4584  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4585  * range #1 and its rank within this range is 2; etc.
4586  *
4587  *  \throw If \a this->getNumberOfComponents() != 1.
4588  *  \throw If \a arrEnd - arrBg < 2.
4589  *  \throw If any value of \a this is not less than \a arrEnd[-1].
4590  */
4591 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4592                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4593 {
4594   checkAllocated();
4595   if(getNumberOfComponents()!=1)
4596     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4597   int nbOfTuples=getNumberOfTuples();
4598   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4599   if(nbOfCast<2)
4600     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4601   nbOfCast--;
4602   const int *work=getConstPointer();
4603   typedef std::reverse_iterator<const int *> rintstart;
4604   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4605   rintstart end2(arrBg);
4606   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4607   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4608   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4609   ret1->alloc(nbOfTuples,1);
4610   ret2->alloc(nbOfTuples,1);
4611   int *ret1Ptr=ret1->getPointer();
4612   int *ret2Ptr=ret2->getPointer();
4613   std::set<std::size_t> castsDetected;
4614   for(int i=0;i<nbOfTuples;i++)
4615     {
4616       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4617       std::size_t pos=std::distance(bg,res);
4618       std::size_t pos2=nbOfCast-pos;
4619       if(pos2<nbOfCast)
4620         {
4621           ret1Ptr[i]=(int)pos2;
4622           ret2Ptr[i]=work[i]-arrBg[pos2];
4623           castsDetected.insert(pos2);
4624         }
4625       else
4626         {
4627           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4628           throw INTERP_KERNEL::Exception(oss.str().c_str());
4629         }
4630     }
4631   ret3->alloc((int)castsDetected.size(),1);
4632   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4633   castArr=ret1.retn();
4634   rankInsideCast=ret2.retn();
4635   castsPresent=ret3.retn();
4636 }
4637
4638 /*!
4639  * 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 ).
4640  * 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 ).
4641  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4642  *
4643  * \param [out] strt - the start of the range (included) if true is returned.
4644  * \param [out] sttoopp - the end of the range (not included) if true is returned.
4645  * \param [out] stteepp - the step of the range if true is returned.
4646  * \return the verdict of the check.
4647  *
4648  * \sa DataArray::GetNumberOfItemGivenBES
4649  */
4650 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4651 {
4652   checkAllocated();
4653   if(getNumberOfComponents()!=1)
4654     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4655   int nbTuples(getNumberOfTuples());
4656   if(nbTuples==0)
4657     { strt=0; sttoopp=0; stteepp=1; return true; }
4658   const int *pt(begin());
4659   strt=*pt; 
4660   if(nbTuples==1)
4661     { sttoopp=strt+1; stteepp=1; return true; }
4662   strt=*pt; sttoopp=pt[nbTuples-1];
4663   if(strt==sttoopp)
4664     return false;
4665   if(sttoopp>strt)
4666     {
4667       sttoopp++;
4668       int a(sttoopp-1-strt),tmp(strt);
4669       if(a%(nbTuples-1)!=0)
4670         return false;
4671       stteepp=a/(nbTuples-1);
4672       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4673         if(pt[i]!=tmp)
4674           return false;
4675       return true;
4676     }
4677   else
4678     {
4679       sttoopp--;
4680       int a(strt-sttoopp-1),tmp(strt);
4681       if(a%(nbTuples-1)!=0)
4682         return false;
4683       stteepp=-(a/(nbTuples-1));
4684       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4685         if(pt[i]!=tmp)
4686           return false;
4687       return true;
4688     }
4689 }
4690
4691 /*!
4692  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
4693  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4694  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4695  * new value in place \a indArr[ \a v ] is i.
4696  *  \param [in] indArrBg - the array holding indices within the result array to assign
4697  *         indices of values of \a this array pointing to values of \a indArrBg.
4698  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4699  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4700  *  \return DataArrayInt * - the new instance of DataArrayInt.
4701  *          The caller is to delete this result array using decrRef() as it is no more
4702  *          needed.
4703  *  \throw If \a this->getNumberOfComponents() != 1.
4704  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
4705  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
4706  */
4707 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4708 {
4709   checkAllocated();
4710   if(getNumberOfComponents()!=1)
4711     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4712   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4713   int nbOfTuples=getNumberOfTuples();
4714   const int *pt=getConstPointer();
4715   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4716   ret->alloc(nbOfTuples,1);
4717   ret->fillWithValue(-1);
4718   int *tmp=ret->getPointer();
4719   for(int i=0;i<nbOfTuples;i++,pt++)
4720     {
4721       if(*pt>=0 && *pt<nbElemsIn)
4722         {
4723           int pos=indArrBg[*pt];
4724           if(pos>=0 && pos<nbOfTuples)
4725             tmp[pos]=i;
4726           else
4727             {
4728               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4729               throw INTERP_KERNEL::Exception(oss.str().c_str());
4730             }
4731         }
4732       else
4733         {
4734           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4735           throw INTERP_KERNEL::Exception(oss.str().c_str());
4736         }
4737     }
4738   return ret.retn();
4739 }
4740
4741 /*!
4742  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4743  * from values of \a this array, which is supposed to contain a renumbering map in 
4744  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4745  * To know how to use the renumbering maps see \ref numbering.
4746  *  \param [in] newNbOfElem - the number of tuples in the result array.
4747  *  \return DataArrayInt * - the new instance of DataArrayInt.
4748  *          The caller is to delete this result array using decrRef() as it is no more
4749  *          needed.
4750  * 
4751  *  \if ENABLE_EXAMPLES
4752  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4753  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
4754  *  \endif
4755  */
4756 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4757 {
4758   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4759   ret->alloc(newNbOfElem,1);
4760   int nbOfOldNodes=getNumberOfTuples();
4761   const int *old2New=getConstPointer();
4762   int *pt=ret->getPointer();
4763   for(int i=0;i!=nbOfOldNodes;i++)
4764     {
4765       int newp(old2New[i]);
4766       if(newp!=-1)
4767         {
4768           if(newp>=0 && newp<newNbOfElem)
4769             pt[newp]=i;
4770           else
4771             {
4772               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4773               throw INTERP_KERNEL::Exception(oss.str().c_str());
4774             }
4775         }
4776     }
4777   return ret.retn();
4778 }
4779
4780 /*!
4781  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
4782  * 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]
4783  */
4784 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4785 {
4786   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4787   ret->alloc(newNbOfElem,1);
4788   int nbOfOldNodes=getNumberOfTuples();
4789   const int *old2New=getConstPointer();
4790   int *pt=ret->getPointer();
4791   for(int i=nbOfOldNodes-1;i>=0;i--)
4792     {
4793       int newp(old2New[i]);
4794       if(newp!=-1)
4795         {
4796           if(newp>=0 && newp<newNbOfElem)
4797             pt[newp]=i;
4798           else
4799             {
4800               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4801               throw INTERP_KERNEL::Exception(oss.str().c_str());
4802             }
4803         }
4804     }
4805   return ret.retn();
4806 }
4807
4808 /*!
4809  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4810  * from values of \a this array, which is supposed to contain a renumbering map in 
4811  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4812  * To know how to use the renumbering maps see \ref numbering.
4813  *  \param [in] newNbOfElem - the number of tuples in the result array.
4814  *  \return DataArrayInt * - the new instance of DataArrayInt.
4815  *          The caller is to delete this result array using decrRef() as it is no more
4816  *          needed.
4817  * 
4818  *  \if ENABLE_EXAMPLES
4819  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4820  *
4821  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4822  *  \endif
4823  */
4824 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4825 {
4826   checkAllocated();
4827   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4828   ret->alloc(oldNbOfElem,1);
4829   const int *new2Old=getConstPointer();
4830   int *pt=ret->getPointer();
4831   std::fill(pt,pt+oldNbOfElem,-1);
4832   int nbOfNewElems=getNumberOfTuples();
4833   for(int i=0;i<nbOfNewElems;i++)
4834     {
4835       int v(new2Old[i]);
4836       if(v>=0 && v<oldNbOfElem)
4837         pt[v]=i;
4838       else
4839         {
4840           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4841           throw INTERP_KERNEL::Exception(oss.str().c_str());
4842         }
4843     }
4844   return ret.retn();
4845 }
4846
4847 /*!
4848  * Equivalent to DataArrayInt::isEqual except that if false the reason of
4849  * mismatch is given.
4850  * 
4851  * \param [in] other the instance to be compared with \a this
4852  * \param [out] reason In case of inequality returns the reason.
4853  * \sa DataArrayInt::isEqual
4854  */
4855 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
4856 {
4857   if(!areInfoEqualsIfNotWhy(other,reason))
4858     return false;
4859   return _mem.isEqual(other._mem,0,reason);
4860 }
4861
4862 /*!
4863  * Checks if \a this and another DataArrayInt are fully equal. For more info see
4864  * \ref MEDCouplingArrayBasicsCompare.
4865  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
4866  *  \return bool - \a true if the two arrays are equal, \a false else.
4867  */
4868 bool DataArrayInt::isEqual(const DataArrayInt& other) const
4869 {
4870   std::string tmp;
4871   return isEqualIfNotWhy(other,tmp);
4872 }
4873
4874 /*!
4875  * Checks if values of \a this and another DataArrayInt are equal. For more info see
4876  * \ref MEDCouplingArrayBasicsCompare.
4877  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
4878  *  \return bool - \a true if the values of two arrays are equal, \a false else.
4879  */
4880 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
4881 {
4882   std::string tmp;
4883   return _mem.isEqual(other._mem,0,tmp);
4884 }
4885
4886 /*!
4887  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
4888  * performed on sorted value sequences.
4889  * For more info see\ref MEDCouplingArrayBasicsCompare.
4890  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
4891  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
4892  */
4893 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
4894 {
4895   MCAuto<DataArrayInt> a=deepCopy();
4896   MCAuto<DataArrayInt> b=other.deepCopy();
4897   a->sort();
4898   b->sort();
4899   return a->isEqualWithoutConsideringStr(*b);
4900 }
4901
4902 /*!
4903  * This method compares content of input vector \a v and \a this.
4904  * 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.
4905  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
4906  *
4907  * \param [in] v - the vector of 'flags' to be compared with \a this.
4908  *
4909  * \throw If \a this is not sorted ascendingly.
4910  * \throw If \a this has not exactly one component.
4911  * \throw If \a this is not allocated.
4912  */
4913 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
4914 {
4915   checkAllocated();
4916   if(getNumberOfComponents()!=1)
4917     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
4918   const int *w(begin()),*end2(end());
4919   int refVal=-std::numeric_limits<int>::max();
4920   int i=0;
4921   std::vector<bool>::const_iterator it(v.begin());
4922   for(;it!=v.end();it++,i++)
4923     {
4924       if(*it)
4925         {
4926           if(w!=end2)
4927             {
4928               if(*w++==i)
4929                 {
4930                   if(i>refVal)
4931                     refVal=i;
4932                   else
4933                     {
4934                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
4935                       throw INTERP_KERNEL::Exception(oss.str().c_str());
4936                     }
4937                 }
4938               else
4939                 return false;
4940             }
4941           else
4942             return false;
4943         }
4944     }
4945   return w==end2;
4946 }
4947
4948 /*!
4949  * 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
4950  * put True to the corresponding entry in \a vec.
4951  * \a vec is expected to be with the same size than the number of tuples of \a this.
4952  *
4953  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
4954  */
4955 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
4956 {
4957   checkAllocated();
4958   if(getNumberOfComponents()!=1)
4959     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
4960   int nbOfTuples(getNumberOfTuples());
4961   if(nbOfTuples!=(int)vec.size())
4962     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4963   const int *pt(begin());
4964   for(int i=0;i<nbOfTuples;i++)
4965     if(pt[i]==val)
4966       vec[i]=true;
4967 }
4968
4969 /*!
4970  * 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
4971  * put True to the corresponding entry in \a vec.
4972  * \a vec is expected to be with the same size than the number of tuples of \a this.
4973  * 
4974  *  \sa DataArrayInt::switchOnTupleEqualTo.
4975  */
4976 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
4977 {
4978   checkAllocated();
4979   if(getNumberOfComponents()!=1)
4980     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
4981   int nbOfTuples(getNumberOfTuples());
4982   if(nbOfTuples!=(int)vec.size())
4983     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4984   const int *pt(begin());
4985   for(int i=0;i<nbOfTuples;i++)
4986     if(pt[i]!=val)
4987       vec[i]=true;
4988 }
4989
4990 /*!
4991  * Computes for each tuple the sum of number of components values in the tuple and return it.
4992  * 
4993  * \return DataArrayInt * - the new instance of DataArrayInt containing the
4994  *          same number of tuples as \a this array and one component.
4995  *          The caller is to delete this result array using decrRef() as it is no more
4996  *          needed.
4997  *  \throw If \a this is not allocated.
4998  */
4999 DataArrayInt *DataArrayInt::sumPerTuple() const
5000 {
5001   checkAllocated();
5002   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5003   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5004   ret->alloc(nbOfTuple,1);
5005   const int *src(getConstPointer());
5006   int *dest(ret->getPointer());
5007   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5008     *dest=std::accumulate(src,src+nbOfComp,0);
5009   return ret.retn();
5010 }
5011
5012 /*!
5013  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5014  * If not an exception is thrown.
5015  *  \param [in] increasing - if \a true, the array values should be increasing.
5016  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5017  *         increasing arg.
5018  *  \throw If \a this->getNumberOfComponents() != 1.
5019  *  \throw If \a this is not allocated.
5020  */
5021 void DataArrayInt::checkMonotonic(bool increasing) const
5022 {
5023   if(!isMonotonic(increasing))
5024     {
5025       if (increasing)
5026         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5027       else
5028         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5029     }
5030 }
5031
5032 /*!
5033  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5034  *  \param [in] increasing - if \a true, array values should be increasing.
5035  *  \return bool - \a true if values change in accordance with \a increasing arg.
5036  *  \throw If \a this->getNumberOfComponents() != 1.
5037  *  \throw If \a this is not allocated.
5038  */
5039 bool DataArrayInt::isMonotonic(bool increasing) const
5040 {
5041   checkAllocated();
5042   if(getNumberOfComponents()!=1)
5043     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5044   int nbOfElements=getNumberOfTuples();
5045   const int *ptr=getConstPointer();
5046   if(nbOfElements==0)
5047     return true;
5048   int ref=ptr[0];
5049   if(increasing)
5050     {
5051       for(int i=1;i<nbOfElements;i++)
5052         {
5053           if(ptr[i]>=ref)
5054             ref=ptr[i];
5055           else
5056             return false;
5057         }
5058     }
5059   else
5060     {
5061       for(int i=1;i<nbOfElements;i++)
5062         {
5063           if(ptr[i]<=ref)
5064             ref=ptr[i];
5065           else
5066             return false;
5067         }
5068     }
5069   return true;
5070 }
5071
5072 /*!
5073  * This method check that array consistently INCREASING or DECREASING in value.
5074  */
5075 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5076 {
5077   checkAllocated();
5078   if(getNumberOfComponents()!=1)
5079     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5080   int nbOfElements=getNumberOfTuples();
5081   const int *ptr=getConstPointer();
5082   if(nbOfElements==0)
5083     return true;
5084   int ref=ptr[0];
5085   if(increasing)
5086     {
5087       for(int i=1;i<nbOfElements;i++)
5088         {
5089           if(ptr[i]>ref)
5090             ref=ptr[i];
5091           else
5092             return false;
5093         }
5094     }
5095   else
5096     {
5097       for(int i=1;i<nbOfElements;i++)
5098         {
5099           if(ptr[i]<ref)
5100             ref=ptr[i];
5101           else
5102             return false;
5103         }
5104     }
5105   return true;
5106 }
5107
5108 /*!
5109  * This method check that array consistently INCREASING or DECREASING in value.
5110  */
5111 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5112 {
5113   if(!isStrictlyMonotonic(increasing))
5114     {
5115       if (increasing)
5116         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5117       else
5118         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5119     }
5120 }
5121
5122 /*!
5123  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5124  * one-dimensional arrays that must be of the same length. The result array describes
5125  * correspondence between \a this and \a other arrays, so that 
5126  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5127  * not possible because some element in \a other is not in \a this, an exception is thrown.
5128  *  \param [in] other - an array to compute permutation to.
5129  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5130  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5131  * no more needed.
5132  *  \throw If \a this->getNumberOfComponents() != 1.
5133  *  \throw If \a other->getNumberOfComponents() != 1.
5134  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5135  *  \throw If \a other includes a value which is not in \a this array.
5136  * 
5137  *  \if ENABLE_EXAMPLES
5138  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5139  *
5140  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5141  *  \endif
5142  */
5143 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5144 {
5145   checkAllocated();
5146   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5147     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5148   int nbTuple=getNumberOfTuples();
5149   other.checkAllocated();
5150   if(nbTuple!=other.getNumberOfTuples())
5151     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5152   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5153   ret->alloc(nbTuple,1);
5154   ret->fillWithValue(-1);
5155   const int *pt=getConstPointer();
5156   std::map<int,int> mm;
5157   for(int i=0;i<nbTuple;i++)
5158     mm[pt[i]]=i;
5159   pt=other.getConstPointer();
5160   int *retToFill=ret->getPointer();
5161   for(int i=0;i<nbTuple;i++)
5162     {
5163       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5164       if(it==mm.end())
5165         {
5166           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5167           throw INTERP_KERNEL::Exception(oss.str().c_str());
5168         }
5169       retToFill[i]=(*it).second;
5170     }
5171   return ret.retn();
5172 }
5173
5174 /*!
5175  * Elements of \a partOfThis are expected to be included in \a this.
5176  * The returned array \a ret is so that this[ret]==partOfThis
5177  *
5178  * 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]
5179  * the return array will contain [3,2,5,7].
5180  *
5181  * \a this is expected to be a 1 compo allocated array.
5182  * \param [in] partOfThis - A 1 compo allocated array
5183  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5184  * \throw if two same element is present twice in \a this
5185  * \throw if an element in \a partOfThis is \b NOT in \a this.
5186  */
5187 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5188 {
5189   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5190     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5191   checkAllocated(); partOfThis.checkAllocated();
5192   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5193   const int *thisPt(begin()),*pt(partOfThis.begin());
5194   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5195   ret->alloc(nbTuples,1);
5196   int *retPt(ret->getPointer());
5197   std::map<int,int> m;
5198   for(int i=0;i<thisNbTuples;i++,thisPt++)
5199     m[*thisPt]=i;
5200   if(m.size()!=thisNbTuples)
5201     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5202   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5203     {
5204       std::map<int,int>::const_iterator it(m.find(*pt));
5205       if(it!=m.end())
5206         *retPt=(*it).second;
5207       else
5208         {
5209           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5210           throw INTERP_KERNEL::Exception(oss.str());
5211         }
5212     }
5213   return ret.retn();
5214 }
5215
5216 void DataArrayInt::aggregate(const DataArrayInt *other)
5217 {
5218   if(!other)
5219     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5220   if(getNumberOfComponents()!=other->getNumberOfComponents())
5221     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5222   _mem.insertAtTheEnd(other->begin(),other->end());
5223 }
5224
5225 /*!
5226  * Returns a new DataArrayInt holding the same values as \a this array but differently
5227  * arranged in memory. If \a this array holds 2 components of 3 values:
5228  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5229  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5230  *  \warning Do not confuse this method with transpose()!
5231  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5232  *          is to delete using decrRef() as it is no more needed.
5233  *  \throw If \a this is not allocated.
5234  */
5235 DataArrayInt *DataArrayInt::fromNoInterlace() const
5236 {
5237   checkAllocated();
5238   if(_mem.isNull())
5239     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5240   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5241   DataArrayInt *ret=DataArrayInt::New();
5242   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5243   return ret;
5244 }
5245
5246 /*!
5247  * Returns a new DataArrayInt holding the same values as \a this array but differently
5248  * arranged in memory. If \a this array holds 2 components of 3 values:
5249  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5250  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5251  *  \warning Do not confuse this method with transpose()!
5252  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5253  *          is to delete using decrRef() as it is no more needed.
5254  *  \throw If \a this is not allocated.
5255  */
5256 DataArrayInt *DataArrayInt::toNoInterlace() const
5257 {
5258   checkAllocated();
5259   if(_mem.isNull())
5260     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5261   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5262   DataArrayInt *ret=DataArrayInt::New();
5263   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5264   return ret;
5265 }
5266
5267 /*!
5268  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5269  * This map, if applied to \a this array, would make it sorted. For example, if
5270  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5271  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5272  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5273  * This method is useful for renumbering (in MED file for example). For more info
5274  * on renumbering see \ref numbering.
5275  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5276  *          array using decrRef() as it is no more needed.
5277  *  \throw If \a this is not allocated.
5278  *  \throw If \a this->getNumberOfComponents() != 1.
5279  *  \throw If there are equal values in \a this array.
5280  */
5281 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5282 {
5283   checkAllocated();
5284   if(getNumberOfComponents()!=1)
5285     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5286   int nbTuples=getNumberOfTuples();
5287   const int *pt=getConstPointer();
5288   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5289   DataArrayInt *ret=DataArrayInt::New();
5290   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5291   return ret;
5292 }
5293
5294 /*!
5295  * 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
5296  * input array \a ids2.
5297  * \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.
5298  * 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
5299  * inversely.
5300  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5301  *
5302  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5303  *          array using decrRef() as it is no more needed.
5304  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5305  * 
5306  */
5307 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5308 {
5309   if(!ids1 || !ids2)
5310     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5311   if(!ids1->isAllocated() || !ids2->isAllocated())
5312     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5313   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5314     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5315   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5316     {
5317       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 !";
5318       throw INTERP_KERNEL::Exception(oss.str().c_str());
5319     }
5320   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5321   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5322   p1->sort(true); p2->sort(true);
5323   if(!p1->isEqualWithoutConsideringStr(*p2))
5324     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5325   p1=ids1->checkAndPreparePermutation();
5326   p2=ids2->checkAndPreparePermutation();
5327   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5328   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5329   return p2.retn();
5330 }
5331
5332 /*!
5333  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5334  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5335  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5336  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5337  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5338  * The first of out arrays returns indices of elements of \a this array, grouped by their
5339  * place in the set \a B. The second out array is the index of the first one; it shows how
5340  * many elements of \a A are mapped into each element of \a B. <br>
5341  * For more info on
5342  * mapping and its usage in renumbering see \ref numbering. <br>
5343  * \b Example:
5344  * - \a this: [0,3,2,3,2,2,1,2]
5345  * - \a targetNb: 4
5346  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5347  * - \a arrI: [0,1,2,6,8]
5348  *
5349  * This result means: <br>
5350  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5351  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5352  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5353  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5354  * \a arrI[ 2+1 ]]); <br> etc.
5355  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5356  *         than the maximal value of \a A.
5357  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5358  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5359  *         this array using decrRef() as it is no more needed.
5360  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5361  *         elements of \a this. The caller is to delete this array using decrRef() as it
5362  *         is no more needed.
5363  *  \throw If \a this is not allocated.
5364  *  \throw If \a this->getNumberOfComponents() != 1.
5365  *  \throw If any value in \a this is more or equal to \a targetNb.
5366  */
5367 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5368 {
5369   checkAllocated();
5370   if(getNumberOfComponents()!=1)
5371     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5372   int nbOfTuples=getNumberOfTuples();
5373   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5374   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5375   retI->alloc(targetNb+1,1);
5376   const int *input=getConstPointer();
5377   std::vector< std::vector<int> > tmp(targetNb);
5378   for(int i=0;i<nbOfTuples;i++)
5379     {
5380       int tmp2=input[i];
5381       if(tmp2>=0 && tmp2<targetNb)
5382         tmp[tmp2].push_back(i);
5383       else
5384         {
5385           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5386           throw INTERP_KERNEL::Exception(oss.str().c_str());
5387         }
5388     }
5389   int *retIPtr=retI->getPointer();
5390   *retIPtr=0;
5391   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5392     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5393   if(nbOfTuples!=retI->getIJ(targetNb,0))
5394     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5395   ret->alloc(nbOfTuples,1);
5396   int *retPtr=ret->getPointer();
5397   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5398     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5399   arr=ret.retn();
5400   arrI=retI.retn();
5401 }
5402
5403
5404 /*!
5405  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5406  * from a zip representation of a surjective format (returned e.g. by
5407  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5408  * for example). The result array minimizes the permutation. <br>
5409  * For more info on renumbering see \ref numbering. <br>
5410  * \b Example: <br>
5411  * - \a nbOfOldTuples: 10 
5412  * - \a arr          : [0,3, 5,7,9]
5413  * - \a arrIBg       : [0,2,5]
5414  * - \a newNbOfTuples: 7
5415  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5416  *
5417  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5418  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5419  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5420  *         (indices of) equal values. Its every element (except the last one) points to
5421  *         the first element of a group of equal values.
5422  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5423  *          arrIBg is \a arrIEnd[ -1 ].
5424  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5425  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5426  *          array using decrRef() as it is no more needed.
5427  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5428  */
5429 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5430 {
5431   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5432   ret->alloc(nbOfOldTuples,1);
5433   int *pt=ret->getPointer();
5434   std::fill(pt,pt+nbOfOldTuples,-1);
5435   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5436   const int *cIPtr=arrIBg;
5437   for(int i=0;i<nbOfGrps;i++)
5438     pt[arr[cIPtr[i]]]=-(i+2);
5439   int newNb=0;
5440   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5441     {
5442       if(pt[iNode]<0)
5443         {
5444           if(pt[iNode]==-1)
5445             pt[iNode]=newNb++;
5446           else
5447             {
5448               int grpId=-(pt[iNode]+2);
5449               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5450                 {
5451                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5452                     pt[arr[j]]=newNb;
5453                   else
5454                     {
5455                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5456                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5457                     }
5458                 }
5459               newNb++;
5460             }
5461         }
5462     }
5463   newNbOfTuples=newNb;
5464   return ret.retn();
5465 }
5466
5467 /*!
5468  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5469  * which if applied to \a this array would make it sorted ascendingly.
5470  * For more info on renumbering see \ref numbering. <br>
5471  * \b Example: <br>
5472  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5473  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5474  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5475  *
5476  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5477  *          array using decrRef() as it is no more needed.
5478  *  \throw If \a this is not allocated.
5479  *  \throw If \a this->getNumberOfComponents() != 1.
5480  */
5481 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5482 {
5483   checkAllocated();
5484   if(getNumberOfComponents()!=1)
5485     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5486   int nbOfTuples=getNumberOfTuples();
5487   const int *pt=getConstPointer();
5488   std::map<int,int> m;
5489   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5490   ret->alloc(nbOfTuples,1);
5491   int *opt=ret->getPointer();
5492   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5493     {
5494       int val=*pt;
5495       std::map<int,int>::iterator it=m.find(val);
5496       if(it!=m.end())
5497         {
5498           *opt=(*it).second;
5499           (*it).second++;
5500         }
5501       else
5502         {
5503           *opt=0;
5504           m.insert(std::pair<int,int>(val,1));
5505         }
5506     }
5507   int sum=0;
5508   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5509     {
5510       int vt=(*it).second;
5511       (*it).second=sum;
5512       sum+=vt;
5513     }
5514   pt=getConstPointer();
5515   opt=ret->getPointer();
5516   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5517     *opt+=m[*pt];
5518   //
5519   return ret.retn();
5520 }
5521
5522 /*!
5523  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5524  * iota(). This method is particularly useful for DataArrayInt instances that represent
5525  * a renumbering array, to check if there is a real need in renumbering.
5526  * This method checks than \a this can be considered as an identity mapping
5527  * of a set having \a sizeExpected elements into itself.
5528  *
5529  *  \param [in] sizeExpected - The number of elements expected.
5530  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5531  *  \throw If \a this is not allocated.
5532  *  \throw If \a this->getNumberOfComponents() != 1.
5533  */
5534 bool DataArrayInt::isIota(int sizeExpected) const
5535 {
5536   checkAllocated();
5537   if(getNumberOfComponents()!=1)
5538     return false;
5539   int nbOfTuples(getNumberOfTuples());
5540   if(nbOfTuples!=sizeExpected)
5541     return false;
5542   const int *pt=getConstPointer();
5543   for(int i=0;i<nbOfTuples;i++,pt++)
5544     if(*pt!=i)
5545       return false;
5546   return true;
5547 }
5548
5549 /*!
5550  * Checks if all values in \a this array are equal to \a val.
5551  *  \param [in] val - value to check equality of array values to.
5552  *  \return bool - \a true if all values are \a val.
5553  *  \throw If \a this is not allocated.
5554  *  \throw If \a this->getNumberOfComponents() != 1
5555  */
5556 bool DataArrayInt::isUniform(int val) const
5557 {
5558   checkAllocated();
5559   if(getNumberOfComponents()!=1)
5560     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5561   int nbOfTuples=getNumberOfTuples();
5562   const int *w=getConstPointer();
5563   const int *end2=w+nbOfTuples;
5564   for(;w!=end2;w++)
5565     if(*w!=val)
5566       return false;
5567   return true;
5568 }
5569
5570 /*!
5571  * Checks if all values in \a this array are unique.
5572  *  \return bool - \a true if condition above is true
5573  *  \throw If \a this is not allocated.
5574  *  \throw If \a this->getNumberOfComponents() != 1
5575  */
5576 bool DataArrayInt::hasUniqueValues() const
5577 {
5578   checkAllocated();
5579   if(getNumberOfComponents()!=1)
5580     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5581   int nbOfTuples(getNumberOfTuples());
5582   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
5583   if (s.size() != nbOfTuples)
5584     return false;
5585   return true;
5586 }
5587
5588 /*!
5589  * Appends components of another array to components of \a this one, tuple by tuple.
5590  * So that the number of tuples of \a this array remains the same and the number of 
5591  * components increases.
5592  *  \param [in] other - the DataArrayInt to append to \a this one.
5593  *  \throw If \a this is not allocated.
5594  *  \throw If \a this and \a other arrays have different number of tuples.
5595  *
5596  *  \if ENABLE_EXAMPLES
5597  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
5598  *
5599  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
5600  *  \endif
5601  */
5602 void DataArrayInt::meldWith(const DataArrayInt *other)
5603 {
5604   if(!other)
5605     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
5606   checkAllocated();
5607   other->checkAllocated();
5608   int nbOfTuples=getNumberOfTuples();
5609   if(nbOfTuples!=other->getNumberOfTuples())
5610     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
5611   int nbOfComp1=getNumberOfComponents();
5612   int nbOfComp2=other->getNumberOfComponents();
5613   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
5614   int *w=newArr;
5615   const int *inp1=getConstPointer();
5616   const int *inp2=other->getConstPointer();
5617   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
5618     {
5619       w=std::copy(inp1,inp1+nbOfComp1,w);
5620       w=std::copy(inp2,inp2+nbOfComp2,w);
5621     }
5622   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
5623   std::vector<int> compIds(nbOfComp2);
5624   for(int i=0;i<nbOfComp2;i++)
5625     compIds[i]=nbOfComp1+i;
5626   copyPartOfStringInfoFrom2(compIds,*other);
5627 }
5628
5629 /*!
5630  * Copy all components in a specified order from another DataArrayInt.
5631  * The specified components become the first ones in \a this array.
5632  * Both numerical and textual data is copied. The number of tuples in \a this and
5633  * the other array can be different.
5634  *  \param [in] a - the array to copy data from.
5635  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
5636  *              to be copied.
5637  *  \throw If \a a is NULL.
5638  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
5639  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
5640  *
5641  *  \if ENABLE_EXAMPLES
5642  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
5643  *  \endif
5644  */
5645 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
5646 {
5647   if(!a)
5648     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
5649   checkAllocated();
5650   a->checkAllocated();
5651   copyPartOfStringInfoFrom2(compoIds,*a);
5652   std::size_t partOfCompoSz=compoIds.size();
5653   int nbOfCompo=getNumberOfComponents();
5654   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
5655   const int *ac=a->getConstPointer();
5656   int *nc=getPointer();
5657   for(int i=0;i<nbOfTuples;i++)
5658     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
5659       nc[nbOfCompo*i+compoIds[j]]=*ac;
5660 }
5661
5662 /*!
5663  * Assign pointer to one array to a pointer to another appay. Reference counter of
5664  * \a arrayToSet is incremented / decremented.
5665  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
5666  *  \param [in,out] arrayToSet - the pointer to array to assign to.
5667  */
5668 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
5669 {
5670   if(newArray!=arrayToSet)
5671     {
5672       if(arrayToSet)
5673         arrayToSet->decrRef();
5674       arrayToSet=newArray;
5675       if(arrayToSet)
5676         arrayToSet->incrRef();
5677     }
5678 }
5679
5680 DataArrayIntIterator *DataArrayInt::iterator()
5681 {
5682   return new DataArrayIntIterator(this);
5683 }
5684
5685 /*!
5686  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
5687  * given one. The ids are sorted in the ascending order.
5688  *  \param [in] val - the value to find within \a this.
5689  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5690  *          array using decrRef() as it is no more needed.
5691  *  \throw If \a this is not allocated.
5692  *  \throw If \a this->getNumberOfComponents() != 1.
5693  *  \sa DataArrayInt::findIdsEqualTuple
5694  */
5695 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
5696 {
5697   checkAllocated();
5698   if(getNumberOfComponents()!=1)
5699     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
5700   const int *cptr(getConstPointer());
5701   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5702   int nbOfTuples=getNumberOfTuples();
5703   for(int i=0;i<nbOfTuples;i++,cptr++)
5704     if(*cptr==val)
5705       ret->pushBackSilent(i);
5706   return ret.retn();
5707 }
5708
5709 /*!
5710  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
5711  * equal to a given one. 
5712  *  \param [in] val - the value to ignore within \a this.
5713  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5714  *          array using decrRef() as it is no more needed.
5715  *  \throw If \a this is not allocated.
5716  *  \throw If \a this->getNumberOfComponents() != 1.
5717  */
5718 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
5719 {
5720   checkAllocated();
5721   if(getNumberOfComponents()!=1)
5722     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
5723   const int *cptr(getConstPointer());
5724   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5725   int nbOfTuples=getNumberOfTuples();
5726   for(int i=0;i<nbOfTuples;i++,cptr++)
5727     if(*cptr!=val)
5728       ret->pushBackSilent(i);
5729   return ret.retn();
5730 }
5731
5732 /*!
5733  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
5734  * This method is an extension of  DataArrayInt::findIdsEqual method.
5735  *
5736  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
5737  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
5738  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5739  *          array using decrRef() as it is no more needed.
5740  *  \throw If \a this is not allocated.
5741  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
5742  * \throw If \a this->getNumberOfComponents() is equal to 0.
5743  * \sa DataArrayInt::findIdsEqual
5744  */
5745 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
5746 {
5747   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
5748   checkAllocated();
5749   if(getNumberOfComponents()!=(int)nbOfCompoExp)
5750     {
5751       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
5752       throw INTERP_KERNEL::Exception(oss.str().c_str());
5753     }
5754   if(nbOfCompoExp==0)
5755     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
5756   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5757   const int *bg(begin()),*end2(end()),*work(begin());
5758   while(work!=end2)
5759     {
5760       work=std::search(work,end2,tupleBg,tupleEnd);
5761       if(work!=end2)
5762         {
5763           std::size_t pos(std::distance(bg,work));
5764           if(pos%nbOfCompoExp==0)
5765             ret->pushBackSilent(pos/nbOfCompoExp);
5766           work++;
5767         }
5768     }
5769   return ret.retn();
5770 }
5771
5772 /*!
5773  * Assigns \a newValue to all elements holding \a oldValue within \a this
5774  * one-dimensional array.
5775  *  \param [in] oldValue - the value to replace.
5776  *  \param [in] newValue - the value to assign.
5777  *  \return int - number of replacements performed.
5778  *  \throw If \a this is not allocated.
5779  *  \throw If \a this->getNumberOfComponents() != 1.
5780  */
5781 int DataArrayInt::changeValue(int oldValue, int newValue)
5782 {
5783   checkAllocated();
5784   if(getNumberOfComponents()!=1)
5785     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5786   if(oldValue==newValue)
5787     return 0;
5788   int *start(getPointer()),*end2(start+getNbOfElems());
5789   int ret(0);
5790   for(int *val=start;val!=end2;val++)
5791     {
5792       if(*val==oldValue)
5793         {
5794           *val=newValue;
5795           ret++;
5796         }
5797     }
5798   if(ret>0)
5799     declareAsNew();
5800   return ret;
5801 }
5802
5803 /*!
5804  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
5805  * one of given values.
5806  *  \param [in] valsBg - an array of values to find within \a this array.
5807  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5808  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5809  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5810  *          array using decrRef() as it is no more needed.
5811  *  \throw If \a this->getNumberOfComponents() != 1.
5812  */
5813 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
5814 {
5815   if(getNumberOfComponents()!=1)
5816     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
5817   std::set<int> vals2(valsBg,valsEnd);
5818   const int *cptr(getConstPointer());
5819   std::vector<int> res;
5820   int nbOfTuples(getNumberOfTuples());
5821   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5822   for(int i=0;i<nbOfTuples;i++,cptr++)
5823     if(vals2.find(*cptr)!=vals2.end())
5824       ret->pushBackSilent(i);
5825   return ret.retn();
5826 }
5827
5828 /*!
5829  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5830  * equal to any of given values.
5831  *  \param [in] valsBg - an array of values to ignore within \a this array.
5832  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5833  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5834  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5835  *          array using decrRef() as it is no more needed.
5836  *  \throw If \a this->getNumberOfComponents() != 1.
5837  */
5838 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
5839 {
5840   if(getNumberOfComponents()!=1)
5841     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5842   std::set<int> vals2(valsBg,valsEnd);
5843   const int *cptr=getConstPointer();
5844   std::vector<int> res;
5845   int nbOfTuples=getNumberOfTuples();
5846   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5847   for(int i=0;i<nbOfTuples;i++,cptr++)
5848     if(vals2.find(*cptr)==vals2.end())
5849       ret->pushBackSilent(i);
5850   return ret.retn();
5851 }
5852
5853 /*!
5854  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5855  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5856  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5857  * If any the tuple id is returned. If not -1 is returned.
5858  * 
5859  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5860  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5861  *
5862  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5863  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5864  */
5865 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
5866 {
5867   checkAllocated();
5868   int nbOfCompo=getNumberOfComponents();
5869   if(nbOfCompo==0)
5870     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5871   if(nbOfCompo!=(int)tupl.size())
5872     {
5873       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5874       throw INTERP_KERNEL::Exception(oss.str().c_str());
5875     }
5876   const int *cptr=getConstPointer();
5877   std::size_t nbOfVals=getNbOfElems();
5878   for(const int *work=cptr;work!=cptr+nbOfVals;)
5879     {
5880       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5881       if(work!=cptr+nbOfVals)
5882         {
5883           if(std::distance(cptr,work)%nbOfCompo!=0)
5884             work++;
5885           else
5886             return std::distance(cptr,work)/nbOfCompo;
5887         }
5888     }
5889   return -1;
5890 }
5891
5892 /*!
5893  * This method searches the sequence specified in input parameter \b vals in \b this.
5894  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5895  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5896  * \sa DataArrayInt::findIdFirstEqualTuple
5897  */
5898 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
5899 {
5900   checkAllocated();
5901   int nbOfCompo=getNumberOfComponents();
5902   if(nbOfCompo!=1)
5903     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5904   const int *cptr=getConstPointer();
5905   std::size_t nbOfVals=getNbOfElems();
5906   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5907   if(loc!=cptr+nbOfVals)
5908     return std::distance(cptr,loc);
5909   return -1;
5910 }
5911
5912 /*!
5913  * This method expects to be called when number of components of this is equal to one.
5914  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5915  * If not any tuple contains \b value -1 is returned.
5916  * \sa DataArrayInt::presenceOfValue
5917  */
5918 int DataArrayInt::findIdFirstEqual(int value) const
5919 {
5920   checkAllocated();
5921   if(getNumberOfComponents()!=1)
5922     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5923   const int *cptr=getConstPointer();
5924   int nbOfTuples=getNumberOfTuples();
5925   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
5926   if(ret!=cptr+nbOfTuples)
5927     return std::distance(cptr,ret);
5928   return -1;
5929 }
5930
5931 /*!
5932  * This method expects to be called when number of components of this is equal to one.
5933  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5934  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5935  * \sa DataArrayInt::presenceOfValue
5936  */
5937 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
5938 {
5939   checkAllocated();
5940   if(getNumberOfComponents()!=1)
5941     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5942   std::set<int> vals2(vals.begin(),vals.end());
5943   const int *cptr=getConstPointer();
5944   int nbOfTuples=getNumberOfTuples();
5945   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
5946     if(vals2.find(*w)!=vals2.end())
5947       return std::distance(cptr,w);
5948   return -1;
5949 }
5950
5951 /*!
5952  * This method returns the number of values in \a this that are equals to input parameter \a value.
5953  * This method only works for single component array.
5954  *
5955  * \return a value in [ 0, \c this->getNumberOfTuples() )
5956  *
5957  * \throw If \a this is not allocated
5958  *
5959  */
5960 int DataArrayInt::count(int value) const
5961 {
5962   int ret=0;
5963   checkAllocated();
5964   if(getNumberOfComponents()!=1)
5965     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5966   const int *vals=begin();
5967   int nbOfTuples=getNumberOfTuples();
5968   for(int i=0;i<nbOfTuples;i++,vals++)
5969     if(*vals==value)
5970       ret++;
5971   return ret;
5972 }
5973
5974 /*!
5975  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5976  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5977  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5978  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5979  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5980  * \sa DataArrayInt::findIdFirstEqualTuple
5981  */
5982 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5983 {
5984   return findIdFirstEqualTuple(tupl)!=-1;
5985 }
5986
5987
5988 /*!
5989  * Returns \a true if a given value is present within \a this one-dimensional array.
5990  *  \param [in] value - the value to find within \a this array.
5991  *  \return bool - \a true in case if \a value is present within \a this array.
5992  *  \throw If \a this is not allocated.
5993  *  \throw If \a this->getNumberOfComponents() != 1.
5994  *  \sa findIdFirstEqual()
5995  */
5996 bool DataArrayInt::presenceOfValue(int value) const
5997 {
5998   return findIdFirstEqual(value)!=-1;
5999 }
6000
6001 /*!
6002  * This method expects to be called when number of components of this is equal to one.
6003  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6004  * If not any tuple contains one of the values contained in 'vals' false is returned.
6005  * \sa DataArrayInt::findIdFirstEqual
6006  */
6007 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6008 {
6009   return findIdFirstEqual(vals)!=-1;
6010 }
6011
6012 /*!
6013  * Accumulates values of each component of \a this array.
6014  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6015  *         by the caller, that is filled by this method with sum value for each
6016  *         component.
6017  *  \throw If \a this is not allocated.
6018  */
6019 void DataArrayInt::accumulate(int *res) const
6020 {
6021   checkAllocated();
6022   const int *ptr=getConstPointer();
6023   int nbTuple=getNumberOfTuples();
6024   int nbComps=getNumberOfComponents();
6025   std::fill(res,res+nbComps,0);
6026   for(int i=0;i<nbTuple;i++)
6027     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6028 }
6029
6030 int DataArrayInt::accumulate(int compId) const
6031 {
6032   checkAllocated();
6033   const int *ptr=getConstPointer();
6034   int nbTuple=getNumberOfTuples();
6035   int nbComps=getNumberOfComponents();
6036   if(compId<0 || compId>=nbComps)
6037     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6038   int ret=0;
6039   for(int i=0;i<nbTuple;i++)
6040     ret+=ptr[i*nbComps+compId];
6041   return ret;
6042 }
6043
6044 /*!
6045  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6046  * The returned array will have same number of components than \a this and number of tuples equal to
6047  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6048  *
6049  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6050  *
6051  * \param [in] bgOfIndex - begin (included) of the input index array.
6052  * \param [in] endOfIndex - end (excluded) of the input index array.
6053  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6054  * 
6055  * \throw If bgOfIndex or end is NULL.
6056  * \throw If input index array is not ascendingly sorted.
6057  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6058  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6059  */
6060 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6061 {
6062   if(!bgOfIndex || !endOfIndex)
6063     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6064   checkAllocated();
6065   int nbCompo=getNumberOfComponents();
6066   int nbOfTuples=getNumberOfTuples();
6067   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6068   if(sz<1)
6069     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6070   sz--;
6071   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6072   const int *w=bgOfIndex;
6073   if(*w<0 || *w>=nbOfTuples)
6074     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6075   const int *srcPt=begin()+(*w)*nbCompo;
6076   int *tmp=ret->getPointer();
6077   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6078     {
6079       std::fill(tmp,tmp+nbCompo,0);
6080       if(w[1]>=w[0])
6081         {
6082           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6083             {
6084               if(j>=0 && j<nbOfTuples)
6085                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6086               else
6087                 {
6088                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6089                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6090                 }
6091             }
6092         }
6093       else
6094         {
6095           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6096           throw INTERP_KERNEL::Exception(oss.str().c_str());
6097         }
6098     }
6099   ret->copyStringInfoFrom(*this);
6100   return ret.retn();
6101 }
6102
6103 /*!
6104  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6105  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6106  * offsetA2</em> and (2)
6107  * the number of component in the result array is same as that of each of given arrays.
6108  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6109  * Info on components is copied from the first of the given arrays. Number of components
6110  * in the given arrays must be the same.
6111  *  \param [in] a1 - an array to include in the result array.
6112  *  \param [in] a2 - another array to include in the result array.
6113  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6114  *  \return DataArrayInt * - the new instance of DataArrayInt.
6115  *          The caller is to delete this result array using decrRef() as it is no more
6116  *          needed.
6117  *  \throw If either \a a1 or \a a2 is NULL.
6118  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6119  */
6120 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6121 {
6122   if(!a1 || !a2)
6123     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6124   int nbOfComp=a1->getNumberOfComponents();
6125   if(nbOfComp!=a2->getNumberOfComponents())
6126     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6127   int nbOfTuple1=a1->getNumberOfTuples();
6128   int nbOfTuple2=a2->getNumberOfTuples();
6129   DataArrayInt *ret=DataArrayInt::New();
6130   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6131   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6132   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6133   ret->copyStringInfoFrom(*a1);
6134   return ret;
6135 }
6136
6137 /*!
6138  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6139  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6140  * the number of component in the result array is same as that of each of given arrays.
6141  * Info on components is copied from the first of the given arrays. Number of components
6142  * in the given arrays must be  the same.
6143  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6144  * not the object itself.
6145  *  \param [in] arr - a sequence of arrays to include in the result array.
6146  *  \return DataArrayInt * - the new instance of DataArrayInt.
6147  *          The caller is to delete this result array using decrRef() as it is no more
6148  *          needed.
6149  *  \throw If all arrays within \a arr are NULL.
6150  *  \throw If getNumberOfComponents() of arrays within \a arr.
6151  */
6152 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6153 {
6154   std::vector<const DataArrayInt *> a;
6155   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6156     if(*it4)
6157       a.push_back(*it4);
6158   if(a.empty())
6159     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6160   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6161   int nbOfComp=(*it)->getNumberOfComponents();
6162   int nbt=(*it++)->getNumberOfTuples();
6163   for(int i=1;it!=a.end();it++,i++)
6164     {
6165       if((*it)->getNumberOfComponents()!=nbOfComp)
6166         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6167       nbt+=(*it)->getNumberOfTuples();
6168     }
6169   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6170   ret->alloc(nbt,nbOfComp);
6171   int *pt=ret->getPointer();
6172   for(it=a.begin();it!=a.end();it++)
6173     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6174   ret->copyStringInfoFrom(*(a[0]));
6175   return ret.retn();
6176 }
6177
6178 /*!
6179  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6180  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6181  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6182  * 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.
6183  * 
6184  * \return DataArrayInt * - a new object to be managed by the caller.
6185  */
6186 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6187 {
6188   int retSz=1;
6189   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6190     {
6191       if(*it4)
6192         {
6193           (*it4)->checkAllocated();
6194           if((*it4)->getNumberOfComponents()!=1)
6195             {
6196               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6197               throw INTERP_KERNEL::Exception(oss.str().c_str());
6198             }
6199           int nbTupl=(*it4)->getNumberOfTuples();
6200           if(nbTupl<1)
6201             {
6202               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6203               throw INTERP_KERNEL::Exception(oss.str().c_str());
6204             }
6205           if((*it4)->front()!=0)
6206             {
6207               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6208               throw INTERP_KERNEL::Exception(oss.str().c_str());
6209             }
6210           retSz+=nbTupl-1;
6211         }
6212       else
6213         {
6214           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6215           throw INTERP_KERNEL::Exception(oss.str().c_str());
6216         }
6217     }
6218   if(arrs.empty())
6219     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6220   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6221   ret->alloc(retSz,1);
6222   int *pt=ret->getPointer(); *pt++=0;
6223   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6224     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6225   ret->copyStringInfoFrom(*(arrs[0]));
6226   return ret.retn();
6227 }
6228
6229 /*!
6230  * Returns in a single walk in \a this the min value and the max value in \a this.
6231  * \a this is expected to be single component array.
6232  *
6233  * \param [out] minValue - the min value in \a this.
6234  * \param [out] maxValue - the max value in \a this.
6235  *
6236  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6237  */
6238 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6239 {
6240   checkAllocated();
6241   if(getNumberOfComponents()!=1)
6242     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6243   int nbTuples(getNumberOfTuples());
6244   const int *pt(begin());
6245   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6246   for(int i=0;i<nbTuples;i++,pt++)
6247     {
6248       if(*pt<minValue)
6249         minValue=*pt;
6250       if(*pt>maxValue)
6251         maxValue=*pt;
6252     }
6253 }
6254
6255 /*!
6256  * Converts every value of \a this array to its absolute value.
6257  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6258  * should be called instead.
6259  *
6260  * \throw If \a this is not allocated.
6261  * \sa DataArrayInt::computeAbs
6262  */
6263 void DataArrayInt::abs()
6264 {
6265   checkAllocated();
6266   int *ptr(getPointer());
6267   std::size_t nbOfElems(getNbOfElems());
6268   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6269   declareAsNew();
6270 }
6271
6272 /*!
6273  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6274  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6275  *
6276  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6277  *         same number of tuples and component as \a this array.
6278  *         The caller is to delete this result array using decrRef() as it is no more
6279  *         needed.
6280  * \throw If \a this is not allocated.
6281  * \sa DataArrayInt::abs
6282  */
6283 DataArrayInt *DataArrayInt::computeAbs() const
6284 {
6285   checkAllocated();
6286   DataArrayInt *newArr(DataArrayInt::New());
6287   int nbOfTuples(getNumberOfTuples());
6288   int nbOfComp(getNumberOfComponents());
6289   newArr->alloc(nbOfTuples,nbOfComp);
6290   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6291   newArr->copyStringInfoFrom(*this);
6292   return newArr;
6293 }
6294
6295 /*!
6296  * Modify all elements of \a this array, so that
6297  * an element _x_ becomes \f$ numerator / x \f$.
6298  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6299  *           array, all elements processed before detection of the zero element remain
6300  *           modified.
6301  *  \param [in] numerator - the numerator used to modify array elements.
6302  *  \throw If \a this is not allocated.
6303  *  \throw If there is an element equal to 0 in \a this array.
6304  */
6305 void DataArrayInt::applyInv(int numerator)
6306 {
6307   checkAllocated();
6308   int *ptr=getPointer();
6309   std::size_t nbOfElems=getNbOfElems();
6310   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6311     {
6312       if(*ptr!=0)
6313         {
6314           *ptr=numerator/(*ptr);
6315         }
6316       else
6317         {
6318           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6319           oss << " !";
6320           throw INTERP_KERNEL::Exception(oss.str().c_str());
6321         }
6322     }
6323   declareAsNew();
6324 }
6325
6326 /*!
6327  * Modify all elements of \a this array, so that
6328  * an element _x_ becomes \f$ x / val \f$.
6329  *  \param [in] val - the denominator used to modify array elements.
6330  *  \throw If \a this is not allocated.
6331  *  \throw If \a val == 0.
6332  */
6333 void DataArrayInt::applyDivideBy(int val)
6334 {
6335   if(val==0)
6336     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6337   checkAllocated();
6338   int *ptr=getPointer();
6339   std::size_t nbOfElems=getNbOfElems();
6340   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6341   declareAsNew();
6342 }
6343
6344 /*!
6345  * Modify all elements of \a this array, so that
6346  * an element _x_ becomes  <em> x % val </em>.
6347  *  \param [in] val - the divisor used to modify array elements.
6348  *  \throw If \a this is not allocated.
6349  *  \throw If \a val <= 0.
6350  */
6351 void DataArrayInt::applyModulus(int val)
6352 {
6353   if(val<=0)
6354     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6355   checkAllocated();
6356   int *ptr=getPointer();
6357   std::size_t nbOfElems=getNbOfElems();
6358   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6359   declareAsNew();
6360 }
6361
6362 struct GreatEqual
6363 {
6364   GreatEqual(int v):_v(v) { }
6365   bool operator()(int v) const { return v>=_v; }
6366   int _v;
6367 };
6368
6369 struct GreaterThan
6370 {
6371   GreaterThan(int v):_v(v) { }
6372   bool operator()(int v) const { return v>_v; }
6373   int _v;
6374 };
6375
6376 struct LowerEqual
6377 {
6378   LowerEqual(int v):_v(v) { }
6379   bool operator()(int v) const { return v<=_v; }
6380   int _v;
6381 };
6382
6383 struct LowerThan
6384 {
6385   LowerThan(int v):_v(v) { }
6386   bool operator()(int v) const { return v<_v; }
6387   int _v;
6388 };
6389
6390 struct InRange
6391 {
6392   InRange(int a, int b):_a(a),_b(b) { }
6393   bool operator()(int v) const { return v>=_a && v<_b; }
6394   int _a,_b;
6395 };
6396
6397 /*!
6398  * This method works only on data array with one component.
6399  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6400  * this[*id] in [\b vmin,\b vmax)
6401  * 
6402  * \param [in] vmin begin of range. This value is included in range (included).
6403  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6404  * \return a newly allocated data array that the caller should deal with.
6405  *
6406  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6407  */
6408 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6409 {
6410   InRange ir(vmin,vmax);
6411   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6412   return ret.retn();
6413 }
6414
6415 struct NotInRange
6416 {
6417   NotInRange(int a, int b):_a(a),_b(b) { }
6418   bool operator()(int v) const { return v<_a || v>=_b; }
6419   int _a,_b;
6420 };
6421
6422 /*!
6423  * This method works only on data array with one component.
6424  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6425  * this[*id] \b not in [\b vmin,\b vmax)
6426  * 
6427  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6428  * \param [in] vmax end of range. This value is included in range (included).
6429  * \return a newly allocated data array that the caller should deal with.
6430  * 
6431  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6432  */
6433 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6434 {
6435   NotInRange nir(vmin,vmax);
6436   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
6437   return ret.retn();
6438 }
6439
6440 /*!
6441  * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
6442  *
6443  * \return a newly allocated data array that the caller should deal with.
6444  * \sa DataArrayInt::findIdsInRange
6445  */
6446 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6447 {
6448   LowerThan lt(0);
6449   MCAuto<DataArrayInt> ret(findIdsAdv(lt));
6450   return ret.retn();
6451 }
6452
6453 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
6454 {
6455   GreatEqual ge(val);
6456   return findIdsAdv(ge);
6457 }
6458
6459 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
6460 {
6461   GreaterThan gt(val);
6462   return findIdsAdv(gt);
6463 }
6464
6465 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
6466 {
6467   LowerEqual le(val);
6468   return findIdsAdv(le);
6469 }
6470
6471 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
6472 {
6473   LowerThan lt(val);
6474   return findIdsAdv(lt);
6475 }
6476
6477 /*!
6478  * This method works only on data array with one component.
6479  * 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.
6480  * 
6481  * \param [in] vmin begin of range. This value is included in range (included).
6482  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6483  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6484 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6485 {
6486   checkAllocated();
6487   if(getNumberOfComponents()!=1)
6488     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6489   int nbOfTuples=getNumberOfTuples();
6490   bool ret=true;
6491   const int *cptr=getConstPointer();
6492   for(int i=0;i<nbOfTuples;i++,cptr++)
6493     {
6494       if(*cptr>=vmin && *cptr<vmax)
6495         { ret=ret && *cptr==i; }
6496       else
6497         {
6498           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6499           throw INTERP_KERNEL::Exception(oss.str().c_str());
6500         }
6501     }
6502   return ret;
6503 }
6504
6505 /*!
6506  * Modify all elements of \a this array, so that
6507  * an element _x_ becomes <em> val % x </em>.
6508  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6509  *           array, all elements processed before detection of the zero element remain
6510  *           modified.
6511  *  \param [in] val - the divident used to modify array elements.
6512  *  \throw If \a this is not allocated.
6513  *  \throw If there is an element equal to or less than 0 in \a this array.
6514  */
6515 void DataArrayInt::applyRModulus(int val)
6516 {
6517   checkAllocated();
6518   int *ptr=getPointer();
6519   std::size_t nbOfElems=getNbOfElems();
6520   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6521     {
6522       if(*ptr>0)
6523         {
6524           *ptr=val%(*ptr);
6525         }
6526       else
6527         {
6528           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6529           oss << " !";
6530           throw INTERP_KERNEL::Exception(oss.str().c_str());
6531         }
6532     }
6533   declareAsNew();
6534 }
6535
6536 /*!
6537  * Modify all elements of \a this array, so that
6538  * an element _x_ becomes <em> val ^ x </em>.
6539  *  \param [in] val - the value used to apply pow on all array elements.
6540  *  \throw If \a this is not allocated.
6541  *  \throw If \a val < 0.
6542  */
6543 void DataArrayInt::applyPow(int val)
6544 {
6545   checkAllocated();
6546   if(val<0)
6547     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
6548   int *ptr=getPointer();
6549   std::size_t nbOfElems=getNbOfElems();
6550   if(val==0)
6551     {
6552       std::fill(ptr,ptr+nbOfElems,1);
6553       return ;
6554     }
6555   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6556     {
6557       int tmp=1;
6558       for(int j=0;j<val;j++)
6559         tmp*=*ptr;
6560       *ptr=tmp;
6561     }
6562   declareAsNew();
6563 }
6564
6565 /*!
6566  * Modify all elements of \a this array, so that
6567  * an element _x_ becomes \f$ val ^ x \f$.
6568  *  \param [in] val - the value used to apply pow on all array elements.
6569  *  \throw If \a this is not allocated.
6570  *  \throw If there is an element < 0 in \a this array.
6571  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6572  *           array, all elements processed before detection of the zero element remain
6573  *           modified.
6574  */
6575 void DataArrayInt::applyRPow(int val)
6576 {
6577   checkAllocated();
6578   int *ptr=getPointer();
6579   std::size_t nbOfElems=getNbOfElems();
6580   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6581     {
6582       if(*ptr>=0)
6583         {
6584           int tmp=1;
6585           for(int j=0;j<*ptr;j++)
6586             tmp*=val;
6587           *ptr=tmp;
6588         }
6589       else
6590         {
6591           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6592           oss << " !";
6593           throw INTERP_KERNEL::Exception(oss.str().c_str());
6594         }
6595     }
6596   declareAsNew();
6597 }
6598
6599 /*!
6600  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
6601  * of components in the result array is a sum of the number of components of given arrays
6602  * and (2) the number of tuples in the result array is same as that of each of given
6603  * arrays. In other words the i-th tuple of result array includes all components of
6604  * i-th tuples of all given arrays.
6605  * Number of tuples in the given arrays must be the same.
6606  *  \param [in] a1 - an array to include in the result array.
6607  *  \param [in] a2 - another array to include in the result array.
6608  *  \return DataArrayInt * - the new instance of DataArrayInt.
6609  *          The caller is to delete this result array using decrRef() as it is no more
6610  *          needed.
6611  *  \throw If both \a a1 and \a a2 are NULL.
6612  *  \throw If any given array is not allocated.
6613  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6614  */
6615 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
6616 {
6617   std::vector<const DataArrayInt *> arr(2);
6618   arr[0]=a1; arr[1]=a2;
6619   return Meld(arr);
6620 }
6621
6622 /*!
6623  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
6624  * of components in the result array is a sum of the number of components of given arrays
6625  * and (2) the number of tuples in the result array is same as that of each of given
6626  * arrays. In other words the i-th tuple of result array includes all components of
6627  * i-th tuples of all given arrays.
6628  * Number of tuples in the given arrays must be  the same.
6629  *  \param [in] arr - a sequence of arrays to include in the result array.
6630  *  \return DataArrayInt * - the new instance of DataArrayInt.
6631  *          The caller is to delete this result array using decrRef() as it is no more
6632  *          needed.
6633  *  \throw If all arrays within \a arr are NULL.
6634  *  \throw If any given array is not allocated.
6635  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
6636  */
6637 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
6638 {
6639   std::vector<const DataArrayInt *> a;
6640   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6641     if(*it4)
6642       a.push_back(*it4);
6643   if(a.empty())
6644     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
6645   std::vector<const DataArrayInt *>::const_iterator it;
6646   for(it=a.begin();it!=a.end();it++)
6647     (*it)->checkAllocated();
6648   it=a.begin();
6649   int nbOfTuples=(*it)->getNumberOfTuples();
6650   std::vector<int> nbc(a.size());
6651   std::vector<const int *> pts(a.size());
6652   nbc[0]=(*it)->getNumberOfComponents();
6653   pts[0]=(*it++)->getConstPointer();
6654   for(int i=1;it!=a.end();it++,i++)
6655     {
6656       if(nbOfTuples!=(*it)->getNumberOfTuples())
6657         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
6658       nbc[i]=(*it)->getNumberOfComponents();
6659       pts[i]=(*it)->getConstPointer();
6660     }
6661   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
6662   DataArrayInt *ret=DataArrayInt::New();
6663   ret->alloc(nbOfTuples,totalNbOfComp);
6664   int *retPtr=ret->getPointer();
6665   for(int i=0;i<nbOfTuples;i++)
6666     for(int j=0;j<(int)a.size();j++)
6667       {
6668         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
6669         pts[j]+=nbc[j];
6670       }
6671   int k=0;
6672   for(int i=0;i<(int)a.size();i++)
6673     for(int j=0;j<nbc[i];j++,k++)
6674       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
6675   return ret;
6676 }
6677
6678 /*!
6679  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
6680  * The i-th item of the result array is an ID of a set of elements belonging to a
6681  * unique set of groups, which the i-th element is a part of. This set of elements
6682  * belonging to a unique set of groups is called \a family, so the result array contains
6683  * IDs of families each element belongs to.
6684  *
6685  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
6686  * then there are 3 families:
6687  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
6688  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
6689  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
6690  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
6691  * stands for the element #3 which is in none of groups.
6692  *
6693  *  \param [in] groups - sequence of groups of element IDs.
6694  *  \param [in] newNb - total number of elements; it must be more than max ID of element
6695  *         in \a groups.
6696  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
6697  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
6698  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
6699  *         delete this array using decrRef() as it is no more needed.
6700  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
6701  */
6702 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
6703 {
6704   std::vector<const DataArrayInt *> groups2;
6705   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
6706     if(*it4)
6707       groups2.push_back(*it4);
6708   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6709   ret->alloc(newNb,1);
6710   int *retPtr=ret->getPointer();
6711   std::fill(retPtr,retPtr+newNb,0);
6712   int fid=1;
6713   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
6714     {
6715       const int *ptr=(*iter)->getConstPointer();
6716       std::size_t nbOfElem=(*iter)->getNbOfElems();
6717       int sfid=fid;
6718       for(int j=0;j<sfid;j++)
6719         {
6720           bool found=false;
6721           for(std::size_t i=0;i<nbOfElem;i++)
6722             {
6723               if(ptr[i]>=0 && ptr[i]<newNb)
6724                 {
6725                   if(retPtr[ptr[i]]==j)
6726                     {
6727                       retPtr[ptr[i]]=fid;
6728                       found=true;
6729                     }
6730                 }
6731               else
6732                 {
6733                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
6734                   oss << ") !";
6735                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6736                 }
6737             }
6738           if(found)
6739             fid++;
6740         }
6741     }
6742   fidsOfGroups.clear();
6743   fidsOfGroups.resize(groups2.size());
6744   int grId=0;
6745   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
6746     {
6747       std::set<int> tmp;
6748       const int *ptr=(*iter)->getConstPointer();
6749       std::size_t nbOfElem=(*iter)->getNbOfElems();
6750       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
6751         tmp.insert(retPtr[*p]);
6752       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
6753     }
6754   return ret.retn();
6755 }
6756
6757 /*!
6758  * Returns a new DataArrayInt which contains all elements of given one-dimensional
6759  * arrays. The result array does not contain any duplicates and its values
6760  * are sorted in ascending order.
6761  *  \param [in] arr - sequence of DataArrayInt's to unite.
6762  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6763  *         array using decrRef() as it is no more needed.
6764  *  \throw If any \a arr[i] is not allocated.
6765  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
6766  */
6767 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
6768 {
6769   std::vector<const DataArrayInt *> a;
6770   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6771     if(*it4)
6772       a.push_back(*it4);
6773   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6774     {
6775       (*it)->checkAllocated();
6776       if((*it)->getNumberOfComponents()!=1)
6777         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
6778     }
6779   //
6780   std::set<int> r;
6781   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6782     {
6783       const int *pt=(*it)->getConstPointer();
6784       int nbOfTuples=(*it)->getNumberOfTuples();
6785       r.insert(pt,pt+nbOfTuples);
6786     }
6787   DataArrayInt *ret=DataArrayInt::New();
6788   ret->alloc((int)r.size(),1);
6789   std::copy(r.begin(),r.end(),ret->getPointer());
6790   return ret;
6791 }
6792
6793 /*!
6794  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
6795  * arrays. The result array does not contain any duplicates and its values
6796  * are sorted in ascending order.
6797  *  \param [in] arr - sequence of DataArrayInt's to intersect.
6798  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6799  *         array using decrRef() as it is no more needed.
6800  *  \throw If any \a arr[i] is not allocated.
6801  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
6802  */
6803 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
6804 {
6805   std::vector<const DataArrayInt *> a;
6806   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6807     if(*it4)
6808       a.push_back(*it4);
6809   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6810     {
6811       (*it)->checkAllocated();
6812       if((*it)->getNumberOfComponents()!=1)
6813         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
6814     }
6815   //
6816   std::set<int> r;
6817   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6818     {
6819       const int *pt=(*it)->getConstPointer();
6820       int nbOfTuples=(*it)->getNumberOfTuples();
6821       std::set<int> s1(pt,pt+nbOfTuples);
6822       if(it!=a.begin())
6823         {
6824           std::set<int> r2;
6825           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
6826           r=r2;
6827         }
6828       else
6829         r=s1;
6830     }
6831   DataArrayInt *ret(DataArrayInt::New());
6832   ret->alloc((int)r.size(),1);
6833   std::copy(r.begin(),r.end(),ret->getPointer());
6834   return ret;
6835 }
6836
6837 /// @cond INTERNAL
6838 namespace MEDCouplingImpl
6839 {
6840   class OpSwitchedOn
6841   {
6842   public:
6843     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
6844     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
6845   private:
6846     int *_pt;
6847     int _cnt;
6848   };
6849
6850   class OpSwitchedOff
6851   {
6852   public:
6853     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
6854     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
6855   private:
6856     int *_pt;
6857     int _cnt;
6858   };
6859 }
6860 /// @endcond
6861
6862 /*!
6863  * This method returns the list of ids in ascending mode so that v[id]==true.
6864  */
6865 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
6866 {
6867   int sz((int)std::count(v.begin(),v.end(),true));
6868   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6869   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
6870   return ret.retn();
6871 }
6872
6873 /*!
6874  * This method returns the list of ids in ascending mode so that v[id]==false.
6875  */
6876 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
6877 {
6878   int sz((int)std::count(v.begin(),v.end(),false));
6879   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6880   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
6881   return ret.retn();
6882 }
6883
6884 /*!
6885  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
6886  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
6887  *
6888  * \param [in] v the input data structure to be translate into skyline format.
6889  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
6890  * \param [out] dataIndex the second element of the skyline format.
6891  */
6892 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
6893 {
6894   int sz((int)v.size());
6895   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
6896   ret1->alloc(sz+1,1);
6897   int *pt(ret1->getPointer()); *pt=0;
6898   for(int i=0;i<sz;i++,pt++)
6899     pt[1]=pt[0]+(int)v[i].size();
6900   ret0->alloc(ret1->back(),1);
6901   pt=ret0->getPointer();
6902   for(int i=0;i<sz;i++)
6903     pt=std::copy(v[i].begin(),v[i].end(),pt);
6904   data=ret0.retn(); dataIndex=ret1.retn();
6905 }
6906
6907 /*!
6908  * Returns a new DataArrayInt which contains a complement of elements of \a this
6909  * one-dimensional array. I.e. the result array contains all elements from the range [0,
6910  * \a nbOfElement) not present in \a this array.
6911  *  \param [in] nbOfElement - maximal size of the result array.
6912  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6913  *         array using decrRef() as it is no more needed.
6914  *  \throw If \a this is not allocated.
6915  *  \throw If \a this->getNumberOfComponents() != 1.
6916  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
6917  *         nbOfElement ).
6918  */
6919 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
6920 {
6921   checkAllocated();
6922   if(getNumberOfComponents()!=1)
6923     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
6924   std::vector<bool> tmp(nbOfElement);
6925   const int *pt=getConstPointer();
6926   int nbOfTuples=getNumberOfTuples();
6927   for(const int *w=pt;w!=pt+nbOfTuples;w++)
6928     if(*w>=0 && *w<nbOfElement)
6929       tmp[*w]=true;
6930     else
6931       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
6932   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
6933   DataArrayInt *ret=DataArrayInt::New();
6934   ret->alloc(nbOfRetVal,1);
6935   int j=0;
6936   int *retPtr=ret->getPointer();
6937   for(int i=0;i<nbOfElement;i++)
6938     if(!tmp[i])
6939       retPtr[j++]=i;
6940   return ret;
6941 }
6942
6943 /*!
6944  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
6945  * from an \a other one-dimensional array.
6946  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
6947  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
6948  *         caller is to delete this array using decrRef() as it is no more needed.
6949  *  \throw If \a other is NULL.
6950  *  \throw If \a other is not allocated.
6951  *  \throw If \a other->getNumberOfComponents() != 1.
6952  *  \throw If \a this is not allocated.
6953  *  \throw If \a this->getNumberOfComponents() != 1.
6954  *  \sa DataArrayInt::buildSubstractionOptimized()
6955  */
6956 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
6957 {
6958   if(!other)
6959     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
6960   checkAllocated();
6961   other->checkAllocated();
6962   if(getNumberOfComponents()!=1)
6963     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
6964   if(other->getNumberOfComponents()!=1)
6965     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
6966   const int *pt=getConstPointer();
6967   int nbOfTuples=getNumberOfTuples();
6968   std::set<int> s1(pt,pt+nbOfTuples);
6969   pt=other->getConstPointer();
6970   nbOfTuples=other->getNumberOfTuples();
6971   std::set<int> s2(pt,pt+nbOfTuples);
6972   std::vector<int> r;
6973   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
6974   DataArrayInt *ret=DataArrayInt::New();
6975   ret->alloc((int)r.size(),1);
6976   std::copy(r.begin(),r.end(),ret->getPointer());
6977   return ret;
6978 }
6979
6980 /*!
6981  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
6982  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
6983  * 
6984  * \param [in] other an array with one component and expected to be sorted ascendingly.
6985  * \ret list of ids in \a this but not in \a other.
6986  * \sa DataArrayInt::buildSubstraction
6987  */
6988 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
6989 {
6990   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
6991   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
6992   checkAllocated(); other->checkAllocated();
6993   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6994   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6995   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
6996   const int *work1(pt1Bg),*work2(pt2Bg);
6997   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6998   for(;work1!=pt1End;work1++)
6999     {
7000       if(work2!=pt2End && *work1==*work2)
7001         work2++;
7002       else
7003         ret->pushBackSilent(*work1);
7004     }
7005   return ret.retn();
7006 }
7007
7008
7009 /*!
7010  * Returns a new DataArrayInt which contains all elements of \a this and a given
7011  * one-dimensional arrays. The result array does not contain any duplicates
7012  * and its values are sorted in ascending order.
7013  *  \param [in] other - an array to unite with \a this one.
7014  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7015  *         array using decrRef() as it is no more needed.
7016  *  \throw If \a this or \a other is not allocated.
7017  *  \throw If \a this->getNumberOfComponents() != 1.
7018  *  \throw If \a other->getNumberOfComponents() != 1.
7019  */
7020 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7021 {
7022   std::vector<const DataArrayInt *>arrs(2);
7023   arrs[0]=this; arrs[1]=other;
7024   return BuildUnion(arrs);
7025 }
7026
7027
7028 /*!
7029  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7030  * one-dimensional arrays. The result array does not contain any duplicates
7031  * and its values are sorted in ascending order.
7032  *  \param [in] other - an array to intersect with \a this one.
7033  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7034  *         array using decrRef() as it is no more needed.
7035  *  \throw If \a this or \a other is not allocated.
7036  *  \throw If \a this->getNumberOfComponents() != 1.
7037  *  \throw If \a other->getNumberOfComponents() != 1.
7038  */
7039 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7040 {
7041   std::vector<const DataArrayInt *>arrs(2);
7042   arrs[0]=this; arrs[1]=other;
7043   return BuildIntersection(arrs);
7044 }
7045
7046 /*!
7047  * This method can be applied on allocated with one component DataArrayInt instance.
7048  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7049  * 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]
7050  * 
7051  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7052  * \throw if \a this is not allocated or if \a this has not exactly one component.
7053  * \sa DataArrayInt::buildUniqueNotSorted
7054  */
7055 DataArrayInt *DataArrayInt::buildUnique() const
7056 {
7057   checkAllocated();
7058   if(getNumberOfComponents()!=1)
7059     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7060   int nbOfTuples=getNumberOfTuples();
7061   MCAuto<DataArrayInt> tmp=deepCopy();
7062   int *data=tmp->getPointer();
7063   int *last=std::unique(data,data+nbOfTuples);
7064   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7065   ret->alloc(std::distance(data,last),1);
7066   std::copy(data,last,ret->getPointer());
7067   return ret.retn();
7068 }
7069
7070 /*!
7071  * This method can be applied on allocated with one component DataArrayInt instance.
7072  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7073  *
7074  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7075  *
7076  * \throw if \a this is not allocated or if \a this has not exactly one component.
7077  *
7078  * \sa DataArrayInt::buildUnique
7079  */
7080 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7081 {
7082   checkAllocated();
7083     if(getNumberOfComponents()!=1)
7084       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7085   int minVal,maxVal;
7086   getMinMaxValues(minVal,maxVal);
7087   std::vector<bool> b(maxVal-minVal+1,false);
7088   const int *ptBg(begin()),*endBg(end());
7089   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7090   for(const int *pt=ptBg;pt!=endBg;pt++)
7091     {
7092       if(!b[*pt-minVal])
7093         {
7094           ret->pushBackSilent(*pt);
7095           b[*pt-minVal]=true;
7096         }
7097     }
7098   ret->copyStringInfoFrom(*this);
7099   return ret.retn();
7100 }
7101
7102 /*!
7103  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7104  * "index" array. Such "index" array is returned for example by 
7105  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7106  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7107  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7108  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7109  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7110  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7111  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7112  *          The caller is to delete this array using decrRef() as it is no more needed. 
7113  *  \throw If \a this is not allocated.
7114  *  \throw If \a this->getNumberOfComponents() != 1.
7115  *  \throw If \a this->getNumberOfTuples() < 2.
7116  *
7117  *  \b Example: <br> 
7118  *         - this contains [1,3,6,7,7,9,15]
7119  *         - result array contains [2,3,1,0,2,6],
7120  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7121  *
7122  * \sa DataArrayInt::computeOffsetsFull
7123  */
7124 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7125 {
7126   checkAllocated();
7127   if(getNumberOfComponents()!=1)
7128     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7129   int nbOfTuples=getNumberOfTuples();
7130   if(nbOfTuples<2)
7131     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7132   const int *ptr=getConstPointer();
7133   DataArrayInt *ret=DataArrayInt::New();
7134   ret->alloc(nbOfTuples-1,1);
7135   int *out=ret->getPointer();
7136   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7137   return ret;
7138 }
7139
7140 /*!
7141  * Modifies \a this one-dimensional array so that value of each element \a x
7142  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7143  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7144  * and components remains the same.<br>
7145  * This method is useful for allToAllV in MPI with contiguous policy. This method
7146  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7147  * this one.
7148  *  \throw If \a this is not allocated.
7149  *  \throw If \a this->getNumberOfComponents() != 1.
7150  *
7151  *  \b Example: <br>
7152  *          - Before \a this contains [3,5,1,2,0,8]
7153  *          - After \a this contains  [0,3,8,9,11,11]<br>
7154  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7155  *          array is retained and thus there is no space to store the last element.
7156  */
7157 void DataArrayInt::computeOffsets()
7158 {
7159   checkAllocated();
7160   if(getNumberOfComponents()!=1)
7161     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7162   int nbOfTuples=getNumberOfTuples();
7163   if(nbOfTuples==0)
7164     return ;
7165   int *work=getPointer();
7166   int tmp=work[0];
7167   work[0]=0;
7168   for(int i=1;i<nbOfTuples;i++)
7169     {
7170       int tmp2=work[i];
7171       work[i]=work[i-1]+tmp;
7172       tmp=tmp2;
7173     }
7174   declareAsNew();
7175 }
7176
7177
7178 /*!
7179  * Modifies \a this one-dimensional array so that value of each element \a x
7180  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7181  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7182  * components remains the same and number of tuples is inceamented by one.<br>
7183  * This method is useful for allToAllV in MPI with contiguous policy. This method
7184  * differs from computeOffsets() in that the number of tuples is changed by this one.
7185  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7186  *  \throw If \a this is not allocated.
7187  *  \throw If \a this->getNumberOfComponents() != 1.
7188  *
7189  *  \b Example: <br>
7190  *          - Before \a this contains [3,5,1,2,0,8]
7191  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7192  * \sa DataArrayInt::deltaShiftIndex
7193  */
7194 void DataArrayInt::computeOffsetsFull()
7195 {
7196   checkAllocated();
7197   if(getNumberOfComponents()!=1)
7198     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7199   int nbOfTuples=getNumberOfTuples();
7200   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7201   const int *work=getConstPointer();
7202   ret[0]=0;
7203   for(int i=0;i<nbOfTuples;i++)
7204     ret[i+1]=work[i]+ret[i];
7205   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7206   declareAsNew();
7207 }
7208
7209 /*!
7210  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7211  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7212  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7213  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7214  * filling completely one of the ranges in \a this.
7215  *
7216  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7217  * \param [out] rangeIdsFetched the range ids fetched
7218  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7219  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7220  *
7221  * \sa DataArrayInt::computeOffsetsFull
7222  *
7223  *  \b Example: <br>
7224  *          - \a this : [0,3,7,9,15,18]
7225  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7226  *          - \a rangeIdsFetched result array: [0,2,4]
7227  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7228  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7229  * <br>
7230  */
7231 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7232 {
7233   if(!listOfIds)
7234     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7235   listOfIds->checkAllocated(); checkAllocated();
7236   if(listOfIds->getNumberOfComponents()!=1)
7237     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7238   if(getNumberOfComponents()!=1)
7239     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7240   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7241   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7242   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7243   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7244   while(tupPtr!=tupEnd && offPtr!=offEnd)
7245     {
7246       if(*tupPtr==*offPtr)
7247         {
7248           int i=offPtr[0];
7249           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7250           if(i==offPtr[1])
7251             {
7252               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7253               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7254               offPtr++;
7255             }
7256         }
7257       else
7258         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7259     }
7260   rangeIdsFetched=ret0.retn();
7261   idsInInputListThatFetch=ret1.retn();
7262 }
7263
7264 /*!
7265  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7266  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7267  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7268  * beginning within the "iota" array. And \a this is a one-dimensional array
7269  * considered as a selector of groups described by \a offsets to include into the result array.
7270  *  \throw If \a offsets is NULL.
7271  *  \throw If \a offsets is not allocated.
7272  *  \throw If \a offsets->getNumberOfComponents() != 1.
7273  *  \throw If \a offsets is not monotonically increasing.
7274  *  \throw If \a this is not allocated.
7275  *  \throw If \a this->getNumberOfComponents() != 1.
7276  *  \throw If any element of \a this is not a valid index for \a offsets array.
7277  *
7278  *  \b Example: <br>
7279  *          - \a this: [0,2,3]
7280  *          - \a offsets: [0,3,6,10,14,20]
7281  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7282  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7283  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7284  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7285  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7286  */
7287 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7288 {
7289   if(!offsets)
7290     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7291   checkAllocated();
7292   if(getNumberOfComponents()!=1)
7293     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7294   offsets->checkAllocated();
7295   if(offsets->getNumberOfComponents()!=1)
7296     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7297   int othNbTuples=offsets->getNumberOfTuples()-1;
7298   int nbOfTuples=getNumberOfTuples();
7299   int retNbOftuples=0;
7300   const int *work=getConstPointer();
7301   const int *offPtr=offsets->getConstPointer();
7302   for(int i=0;i<nbOfTuples;i++)
7303     {
7304       int val=work[i];
7305       if(val>=0 && val<othNbTuples)
7306         {
7307           int delta=offPtr[val+1]-offPtr[val];
7308           if(delta>=0)
7309             retNbOftuples+=delta;
7310           else
7311             {
7312               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7313               throw INTERP_KERNEL::Exception(oss.str().c_str());
7314             }
7315         }
7316       else
7317         {
7318           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7319           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7320           throw INTERP_KERNEL::Exception(oss.str().c_str());
7321         }
7322     }
7323   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7324   ret->alloc(retNbOftuples,1);
7325   int *retPtr=ret->getPointer();
7326   for(int i=0;i<nbOfTuples;i++)
7327     {
7328       int val=work[i];
7329       int start=offPtr[val];
7330       int off=offPtr[val+1]-start;
7331       for(int j=0;j<off;j++,retPtr++)
7332         *retPtr=start+j;
7333     }
7334   return ret.retn();
7335 }
7336
7337 /*!
7338  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7339  * scaled array (monotonically increasing).
7340 from that of \a this and \a
7341  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7342  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7343  * beginning within the "iota" array. And \a this is a one-dimensional array
7344  * considered as a selector of groups described by \a offsets to include into the result array.
7345  *  \throw If \a  is NULL.
7346  *  \throw If \a this is not allocated.
7347  *  \throw If \a this->getNumberOfComponents() != 1.
7348  *  \throw If \a this->getNumberOfTuples() == 0.
7349  *  \throw If \a this is not monotonically increasing.
7350  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7351  *
7352  *  \b Example: <br>
7353  *          - \a bg , \a stop and \a step : (0,5,2)
7354  *          - \a this: [0,3,6,10,14,20]
7355  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7356  */
7357 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7358 {
7359   if(!isAllocated())
7360     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7361   if(getNumberOfComponents()!=1)
7362     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7363   int nbOfTuples(getNumberOfTuples());
7364   if(nbOfTuples==0)
7365     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7366   const int *ids(begin());
7367   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7368   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7369     {
7370       if(pos>=0 && pos<nbOfTuples-1)
7371         {
7372           int delta(ids[pos+1]-ids[pos]);
7373           sz+=delta;
7374           if(delta<0)
7375             {
7376               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7377               throw INTERP_KERNEL::Exception(oss.str().c_str());
7378             }          
7379         }
7380       else
7381         {
7382           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7383           throw INTERP_KERNEL::Exception(oss.str().c_str());
7384         }
7385     }
7386   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7387   int *retPtr(ret->getPointer());
7388   pos=bg;
7389   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7390     {
7391       int delta(ids[pos+1]-ids[pos]);
7392       for(int j=0;j<delta;j++,retPtr++)
7393         *retPtr=pos;
7394     }
7395   return ret.retn();
7396 }
7397
7398 /*!
7399  * 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.
7400  * 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
7401  * in tuple **i** of returned DataArrayInt.
7402  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7403  *
7404  * 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)]
7405  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7406  * 
7407  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7408  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7409  * \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
7410  *        is thrown if no ranges in \a ranges contains value in \a this.
7411  * 
7412  * \sa DataArrayInt::findIdInRangeForEachTuple
7413  */
7414 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7415 {
7416   if(!ranges)
7417     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7418   if(ranges->getNumberOfComponents()!=2)
7419     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7420   checkAllocated();
7421   if(getNumberOfComponents()!=1)
7422     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7423   int nbTuples=getNumberOfTuples();
7424   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7425   int nbOfRanges=ranges->getNumberOfTuples();
7426   const int *rangesPtr=ranges->getConstPointer();
7427   int *retPtr=ret->getPointer();
7428   const int *inPtr=getConstPointer();
7429   for(int i=0;i<nbTuples;i++,retPtr++)
7430     {
7431       int val=inPtr[i];
7432       bool found=false;
7433       for(int j=0;j<nbOfRanges && !found;j++)
7434         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7435           { *retPtr=j; found=true; }
7436       if(found)
7437         continue;
7438       else
7439         {
7440           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7441           throw INTERP_KERNEL::Exception(oss.str().c_str());
7442         }
7443     }
7444   return ret.retn();
7445 }
7446
7447 /*!
7448  * 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.
7449  * 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
7450  * in tuple **i** of returned DataArrayInt.
7451  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7452  *
7453  * 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)]
7454  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7455  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7456  * 
7457  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7458  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7459  * \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
7460  *        is thrown if no ranges in \a ranges contains value in \a this.
7461  * \sa DataArrayInt::findRangeIdForEachTuple
7462  */
7463 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7464 {
7465   if(!ranges)
7466     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7467   if(ranges->getNumberOfComponents()!=2)
7468     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7469   checkAllocated();
7470   if(getNumberOfComponents()!=1)
7471     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7472   int nbTuples=getNumberOfTuples();
7473   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7474   int nbOfRanges=ranges->getNumberOfTuples();
7475   const int *rangesPtr=ranges->getConstPointer();
7476   int *retPtr=ret->getPointer();
7477   const int *inPtr=getConstPointer();
7478   for(int i=0;i<nbTuples;i++,retPtr++)
7479     {
7480       int val=inPtr[i];
7481       bool found=false;
7482       for(int j=0;j<nbOfRanges && !found;j++)
7483         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7484           { *retPtr=val-rangesPtr[2*j]; found=true; }
7485       if(found)
7486         continue;
7487       else
7488         {
7489           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7490           throw INTERP_KERNEL::Exception(oss.str().c_str());
7491         }
7492     }
7493   return ret.retn();
7494 }
7495
7496 /*!
7497  * \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).
7498  * 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).
7499  * 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 !
7500  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7501  * This method does nothing if number of tuples is lower of equal to 1.
7502  *
7503  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7504  *
7505  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
7506  */
7507 void DataArrayInt::sortEachPairToMakeALinkedList()
7508 {
7509   checkAllocated();
7510   if(getNumberOfComponents()!=2)
7511     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7512   int nbOfTuples(getNumberOfTuples());
7513   if(nbOfTuples<=1)
7514     return ;
7515   int *conn(getPointer());
7516   for(int i=1;i<nbOfTuples;i++,conn+=2)
7517     {
7518       if(i>1)
7519         {
7520           if(conn[2]==conn[3])
7521             {
7522               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7523               throw INTERP_KERNEL::Exception(oss.str().c_str());
7524             }
7525           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
7526             std::swap(conn[2],conn[3]);
7527           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
7528           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
7529             {
7530               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
7531               throw INTERP_KERNEL::Exception(oss.str().c_str());
7532             }
7533         }
7534       else
7535         {
7536           if(conn[0]==conn[1] || conn[2]==conn[3])
7537             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
7538           int tmp[4];
7539           std::set<int> s;
7540           s.insert(conn,conn+4);
7541           if(s.size()!=3)
7542             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
7543           if(std::count(conn,conn+4,conn[0])==2)
7544             {
7545               tmp[0]=conn[1];
7546               tmp[1]=conn[0];
7547               tmp[2]=conn[0];
7548               if(conn[2]==conn[0])
7549                 { tmp[3]=conn[3]; }
7550               else
7551                 { tmp[3]=conn[2];}
7552               std::copy(tmp,tmp+4,conn);
7553             }
7554           else
7555             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
7556               if(conn[1]==conn[3])
7557                 std::swap(conn[2],conn[3]);
7558             }
7559         }
7560     }
7561 }
7562
7563 /*!
7564  * \a this is expected to be a correctly linked list of pairs.
7565  * 
7566  * \sa DataArrayInt::sortEachPairToMakeALinkedList
7567  */
7568 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
7569 {
7570   checkAllocated();
7571   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
7572   int nbTuples(getNumberOfTuples());
7573   if(nbTuples<1)
7574     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
7575   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
7576   const int *thisPtr(begin());
7577   int *retPtr(ret->getPointer());
7578   retPtr[0]=thisPtr[0];
7579   for(int i=0;i<nbTuples;i++)
7580     {
7581       retPtr[i+1]=thisPtr[2*i+1];
7582       if(i<nbTuples-1)
7583         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
7584           {
7585             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 ?";
7586             throw INTERP_KERNEL::Exception(oss.str());
7587           }
7588     }
7589   return ret;
7590 }
7591
7592 /*!
7593  * 
7594  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
7595  *             \a nbTimes  should be at least equal to 1.
7596  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
7597  * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
7598  */
7599 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
7600 {
7601   checkAllocated();
7602   if(getNumberOfComponents()!=1)
7603     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
7604   if(nbTimes<1)
7605     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
7606   int nbTuples=getNumberOfTuples();
7607   const int *inPtr=getConstPointer();
7608   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
7609   int *retPtr=ret->getPointer();
7610   for(int i=0;i<nbTuples;i++,inPtr++)
7611     {
7612       int val=*inPtr;
7613       for(int j=0;j<nbTimes;j++,retPtr++)
7614         *retPtr=val;
7615     }
7616   ret->copyStringInfoFrom(*this);
7617   return ret.retn();
7618 }
7619
7620 /*!
7621  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
7622  * But the number of components can be different from one.
7623  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
7624  */
7625 DataArrayInt *DataArrayInt::getDifferentValues() const
7626 {
7627   checkAllocated();
7628   std::set<int> ret;
7629   ret.insert(begin(),end());
7630   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
7631   std::copy(ret.begin(),ret.end(),ret2->getPointer());
7632   return ret2.retn();
7633 }
7634
7635 /*!
7636  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
7637  * them it tells which tuple id have this id.
7638  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
7639  * This method returns two arrays having same size.
7640  * 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.
7641  * 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]]
7642  */
7643 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
7644 {
7645   checkAllocated();
7646   if(getNumberOfComponents()!=1)
7647     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
7648   int id=0;
7649   std::map<int,int> m,m2,m3;
7650   for(const int *w=begin();w!=end();w++)
7651     m[*w]++;
7652   differentIds.resize(m.size());
7653   std::vector<DataArrayInt *> ret(m.size());
7654   std::vector<int *> retPtr(m.size());
7655   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
7656     {
7657       m2[(*it).first]=id;
7658       ret[id]=DataArrayInt::New();
7659       ret[id]->alloc((*it).second,1);
7660       retPtr[id]=ret[id]->getPointer();
7661       differentIds[id]=(*it).first;
7662     }
7663   id=0;
7664   for(const int *w=begin();w!=end();w++,id++)
7665     {
7666       retPtr[m2[*w]][m3[*w]++]=id;
7667     }
7668   return ret;
7669 }
7670
7671 /*!
7672  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
7673  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
7674  *
7675  * \param [in] nbOfSlices - number of slices expected.
7676  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
7677  * 
7678  * \sa DataArray::GetSlice
7679  * \throw If \a this is not allocated or not with exactly one component.
7680  * \throw If an element in \a this if < 0.
7681  */
7682 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
7683 {
7684   if(!isAllocated() || getNumberOfComponents()!=1)
7685     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
7686   if(nbOfSlices<=0)
7687     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
7688   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
7689   int sumPerSlc(sum/nbOfSlices),pos(0);
7690   const int *w(begin());
7691   std::vector< std::pair<int,int> > ret(nbOfSlices);
7692   for(int i=0;i<nbOfSlices;i++)
7693     {
7694       std::pair<int,int> p(pos,-1);
7695       int locSum(0);
7696       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
7697       if(i!=nbOfSlices-1)
7698         p.second=pos;
7699       else
7700         p.second=nbOfTuples;
7701       ret[i]=p;
7702     }
7703   return ret;
7704 }
7705
7706 /*!
7707  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
7708  * valid cases.
7709  * 1.  The arrays have same number of tuples and components. Then each value of
7710  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
7711  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
7712  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
7713  *   component. Then
7714  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
7715  * 3.  The arrays have same number of components and one array, say _a2_, has one
7716  *   tuple. Then
7717  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
7718  *
7719  * Info on components is copied either from the first array (in the first case) or from
7720  * the array with maximal number of elements (getNbOfElems()).
7721  *  \param [in] a1 - an array to sum up.
7722  *  \param [in] a2 - another array to sum up.
7723  *  \return DataArrayInt * - the new instance of DataArrayInt.
7724  *          The caller is to delete this result array using decrRef() as it is no more
7725  *          needed.
7726  *  \throw If either \a a1 or \a a2 is NULL.
7727  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
7728  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
7729  *         none of them has number of tuples or components equal to 1.
7730  */
7731 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
7732 {
7733   if(!a1 || !a2)
7734     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
7735   int nbOfTuple=a1->getNumberOfTuples();
7736   int nbOfTuple2=a2->getNumberOfTuples();
7737   int nbOfComp=a1->getNumberOfComponents();
7738   int nbOfComp2=a2->getNumberOfComponents();
7739   MCAuto<DataArrayInt> ret=0;
7740   if(nbOfTuple==nbOfTuple2)
7741     {
7742       if(nbOfComp==nbOfComp2)
7743         {
7744           ret=DataArrayInt::New();
7745           ret->alloc(nbOfTuple,nbOfComp);
7746           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
7747           ret->copyStringInfoFrom(*a1);
7748         }
7749       else
7750         {
7751           int nbOfCompMin,nbOfCompMax;
7752           const DataArrayInt *aMin, *aMax;
7753           if(nbOfComp>nbOfComp2)
7754             {
7755               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
7756               aMin=a2; aMax=a1;
7757             }
7758           else
7759             {
7760               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
7761               aMin=a1; aMax=a2;
7762             }
7763           if(nbOfCompMin==1)
7764             {
7765               ret=DataArrayInt::New();
7766               ret->alloc(nbOfTuple,nbOfCompMax);
7767               const int *aMinPtr=aMin->getConstPointer();
7768               const int *aMaxPtr=aMax->getConstPointer();
7769               int *res=ret->getPointer();
7770               for(int i=0;i<nbOfTuple;i++)
7771                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
7772               ret->copyStringInfoFrom(*aMax);
7773             }
7774           else
7775             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
7776         }
7777     }
7778   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
7779     {
7780       if(nbOfComp==nbOfComp2)
7781         {
7782           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
7783           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
7784           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
7785           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
7786           ret=DataArrayInt::New();
7787           ret->alloc(nbOfTupleMax,nbOfComp);
7788           int *res=ret->getPointer();
7789           for(int i=0;i<nbOfTupleMax;i++)
7790             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
7791           ret->copyStringInfoFrom(*aMax);
7792         }
7793       else
7794         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
7795     }
7796   else
7797     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
7798   return ret.retn();
7799 }
7800
7801 /*!
7802  * Adds values of another DataArrayInt to values of \a this one. There are 3
7803  * valid cases.
7804  * 1.  The arrays have same number of tuples and components. Then each value of
7805  *   \a other array is added to the corresponding value of \a this array, i.e.:
7806  *   _a_ [ i, j ] += _other_ [ i, j ].
7807  * 2.  The arrays have same number of tuples and \a other array has one component. Then
7808  *   _a_ [ i, j ] += _other_ [ i, 0 ].
7809  * 3.  The arrays have same number of components and \a other array has one tuple. Then
7810  *   _a_ [ i, j ] += _a2_ [ 0, j ].
7811  *
7812  *  \param [in] other - an array to add to \a this one.
7813  *  \throw If \a other is NULL.
7814  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
7815  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
7816  *         \a other has number of both tuples and components not equal to 1.
7817  */
7818 void DataArrayInt::addEqual(const DataArrayInt *other)
7819 {
7820   if(!other)
7821     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
7822   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
7823   checkAllocated(); other->checkAllocated();
7824   int nbOfTuple=getNumberOfTuples();
7825   int nbOfTuple2=other->getNumberOfTuples();
7826   int nbOfComp=getNumberOfComponents();
7827   int nbOfComp2=other->getNumberOfComponents();
7828   if(nbOfTuple==nbOfTuple2)
7829     {
7830       if(nbOfComp==nbOfComp2)
7831         {
7832           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
7833         }
7834       else if(nbOfComp2==1)
7835         {
7836           int *ptr=getPointer();
7837           const int *ptrc=other->getConstPointer();
7838           for(int i=0;i<nbOfTuple;i++)
7839             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
7840         }
7841       else
7842         throw INTERP_KERNEL::Exception(msg);
7843     }
7844   else if(nbOfTuple2==1)
7845     {
7846       if(nbOfComp2==nbOfComp)
7847         {
7848           int *ptr=getPointer();
7849           const int *ptrc=other->getConstPointer();
7850           for(int i=0;i<nbOfTuple;i++)
7851             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
7852         }
7853       else
7854         throw INTERP_KERNEL::Exception(msg);
7855     }
7856   else
7857     throw INTERP_KERNEL::Exception(msg);
7858   declareAsNew();
7859 }
7860
7861 /*!
7862  * Subtract values of another DataArrayInt from values of \a this one. There are 3
7863  * valid cases.
7864  * 1.  The arrays have same number of tuples and components. Then each value of
7865  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
7866  *   _a_ [ i, j ] -= _other_ [ i, j ].
7867  * 2.  The arrays have same number of tuples and \a other array has one component. Then
7868  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
7869  * 3.  The arrays have same number of components and \a other array has one tuple. Then
7870  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
7871  *
7872  *  \param [in] other - an array to subtract from \a this one.
7873  *  \throw If \a other is NULL.
7874  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
7875  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
7876  *         \a other has number of both tuples and components not equal to 1.
7877  */
7878 void DataArrayInt::substractEqual(const DataArrayInt *other)
7879 {
7880   if(!other)
7881     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
7882   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
7883   checkAllocated(); other->checkAllocated();
7884   int nbOfTuple=getNumberOfTuples();
7885   int nbOfTuple2=other->getNumberOfTuples();
7886   int nbOfComp=getNumberOfComponents();
7887   int nbOfComp2=other->getNumberOfComponents();
7888   if(nbOfTuple==nbOfTuple2)
7889     {
7890       if(nbOfComp==nbOfComp2)
7891         {
7892           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
7893         }
7894       else if(nbOfComp2==1)
7895         {
7896           int *ptr=getPointer();
7897           const int *ptrc=other->getConstPointer();
7898           for(int i=0;i<nbOfTuple;i++)
7899             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
7900         }
7901       else
7902         throw INTERP_KERNEL::Exception(msg);
7903     }
7904   else if(nbOfTuple2==1)
7905     {
7906       int *ptr=getPointer();
7907       const int *ptrc=other->getConstPointer();
7908       for(int i=0;i<nbOfTuple;i++)
7909         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
7910     }
7911   else
7912     throw INTERP_KERNEL::Exception(msg);
7913   declareAsNew();
7914 }
7915
7916 /*!
7917  * Divide values of \a this array by values of another DataArrayInt. There are 3
7918  * valid cases.
7919  * 1.  The arrays have same number of tuples and components. Then each value of
7920  *    \a this array is divided by the corresponding value of \a other one, i.e.:
7921  *   _a_ [ i, j ] /= _other_ [ i, j ].
7922  * 2.  The arrays have same number of tuples and \a other array has one component. Then
7923  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
7924  * 3.  The arrays have same number of components and \a other array has one tuple. Then
7925  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
7926  *
7927  *  \warning No check of division by zero is performed!
7928  *  \param [in] other - an array to divide \a this one by.
7929  *  \throw If \a other is NULL.
7930  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
7931  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
7932  *         \a other has number of both tuples and components not equal to 1.
7933  */
7934 void DataArrayInt::divideEqual(const DataArrayInt *other)
7935 {
7936   if(!other)
7937     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
7938   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
7939   checkAllocated(); other->checkAllocated();
7940   int nbOfTuple=getNumberOfTuples();
7941   int nbOfTuple2=other->getNumberOfTuples();
7942   int nbOfComp=getNumberOfComponents();
7943   int nbOfComp2=other->getNumberOfComponents();
7944   if(nbOfTuple==nbOfTuple2)
7945     {
7946       if(nbOfComp==nbOfComp2)
7947         {
7948           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
7949         }
7950       else if(nbOfComp2==1)
7951         {
7952           int *ptr=getPointer();
7953           const int *ptrc=other->getConstPointer();
7954           for(int i=0;i<nbOfTuple;i++)
7955             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
7956         }
7957       else
7958         throw INTERP_KERNEL::Exception(msg);
7959     }
7960   else if(nbOfTuple2==1)
7961     {
7962       if(nbOfComp2==nbOfComp)
7963         {
7964           int *ptr=getPointer();
7965           const int *ptrc=other->getConstPointer();
7966           for(int i=0;i<nbOfTuple;i++)
7967             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
7968         }
7969       else
7970         throw INTERP_KERNEL::Exception(msg);
7971     }
7972   else
7973     throw INTERP_KERNEL::Exception(msg);
7974   declareAsNew();
7975 }
7976
7977
7978 /*!
7979  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
7980  * valid cases.
7981  * 1.  The arrays have same number of tuples and components. Then each value of
7982  *   the result array (_a_) is a division of the corresponding values of \a a1 and
7983  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
7984  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
7985  *   component. Then
7986  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
7987  * 3.  The arrays have same number of components and one array, say _a2_, has one
7988  *   tuple. Then
7989  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
7990  *
7991  * Info on components is copied either from the first array (in the first case) or from
7992  * the array with maximal number of elements (getNbOfElems()).
7993  *  \warning No check of division by zero is performed!
7994  *  \param [in] a1 - a dividend array.
7995  *  \param [in] a2 - a divisor array.
7996  *  \return DataArrayInt * - the new instance of DataArrayInt.
7997  *          The caller is to delete this result array using decrRef() as it is no more
7998  *          needed.
7999  *  \throw If either \a a1 or \a a2 is NULL.
8000  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8001  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8002  *         none of them has number of tuples or components equal to 1.
8003  */
8004 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8005 {
8006   if(!a1 || !a2)
8007     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8008   int nbOfTuple1=a1->getNumberOfTuples();
8009   int nbOfTuple2=a2->getNumberOfTuples();
8010   int nbOfComp1=a1->getNumberOfComponents();
8011   int nbOfComp2=a2->getNumberOfComponents();
8012   if(nbOfTuple2==nbOfTuple1)
8013     {
8014       if(nbOfComp1==nbOfComp2)
8015         {
8016           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8017           ret->alloc(nbOfTuple2,nbOfComp1);
8018           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8019           ret->copyStringInfoFrom(*a1);
8020           return ret.retn();
8021         }
8022       else if(nbOfComp2==1)
8023         {
8024           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8025           ret->alloc(nbOfTuple1,nbOfComp1);
8026           const int *a2Ptr=a2->getConstPointer();
8027           const int *a1Ptr=a1->getConstPointer();
8028           int *res=ret->getPointer();
8029           for(int i=0;i<nbOfTuple1;i++)
8030             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8031           ret->copyStringInfoFrom(*a1);
8032           return ret.retn();
8033         }
8034       else
8035         {
8036           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8037           return 0;
8038         }
8039     }
8040   else if(nbOfTuple2==1)
8041     {
8042       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8043       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8044       ret->alloc(nbOfTuple1,nbOfComp1);
8045       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8046       int *pt=ret->getPointer();
8047       for(int i=0;i<nbOfTuple1;i++)
8048         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8049       ret->copyStringInfoFrom(*a1);
8050       return ret.retn();
8051     }
8052   else
8053     {
8054       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8055       return 0;
8056     }
8057 }
8058
8059 /*!
8060  * Modify \a this array so that each value becomes a modulus of division of this value by
8061  * a value of another DataArrayInt. There are 3 valid cases.
8062  * 1.  The arrays have same number of tuples and components. Then each value of
8063  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8064  *   _a_ [ i, j ] %= _other_ [ i, j ].
8065  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8066  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8067  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8068  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8069  *
8070  *  \warning No check of division by zero is performed!
8071  *  \param [in] other - a divisor array.
8072  *  \throw If \a other is NULL.
8073  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8074  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8075  *         \a other has number of both tuples and components not equal to 1.
8076  */
8077 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8078 {
8079   if(!other)
8080     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8081   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8082   checkAllocated(); other->checkAllocated();
8083   int nbOfTuple=getNumberOfTuples();
8084   int nbOfTuple2=other->getNumberOfTuples();
8085   int nbOfComp=getNumberOfComponents();
8086   int nbOfComp2=other->getNumberOfComponents();
8087   if(nbOfTuple==nbOfTuple2)
8088     {
8089       if(nbOfComp==nbOfComp2)
8090         {
8091           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8092         }
8093       else if(nbOfComp2==1)
8094         {
8095           if(nbOfComp2==nbOfComp)
8096             {
8097               int *ptr=getPointer();
8098               const int *ptrc=other->getConstPointer();
8099               for(int i=0;i<nbOfTuple;i++)
8100                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8101             }
8102           else
8103             throw INTERP_KERNEL::Exception(msg);
8104         }
8105       else
8106         throw INTERP_KERNEL::Exception(msg);
8107     }
8108   else if(nbOfTuple2==1)
8109     {
8110       int *ptr=getPointer();
8111       const int *ptrc=other->getConstPointer();
8112       for(int i=0;i<nbOfTuple;i++)
8113         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8114     }
8115   else
8116     throw INTERP_KERNEL::Exception(msg);
8117   declareAsNew();
8118 }
8119
8120 /*!
8121  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8122  * valid cases.
8123  *
8124  *  \param [in] a1 - an array to pow up.
8125  *  \param [in] a2 - another array to sum up.
8126  *  \return DataArrayInt * - the new instance of DataArrayInt.
8127  *          The caller is to delete this result array using decrRef() as it is no more
8128  *          needed.
8129  *  \throw If either \a a1 or \a a2 is NULL.
8130  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8131  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8132  *  \throw If there is a negative value in \a a2.
8133  */
8134 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8135 {
8136   if(!a1 || !a2)
8137     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8138   int nbOfTuple=a1->getNumberOfTuples();
8139   int nbOfTuple2=a2->getNumberOfTuples();
8140   int nbOfComp=a1->getNumberOfComponents();
8141   int nbOfComp2=a2->getNumberOfComponents();
8142   if(nbOfTuple!=nbOfTuple2)
8143     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8144   if(nbOfComp!=1 || nbOfComp2!=1)
8145     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8146   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8147   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8148   int *ptr=ret->getPointer();
8149   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8150     {
8151       if(*ptr2>=0)
8152         {
8153           int tmp=1;
8154           for(int j=0;j<*ptr2;j++)
8155             tmp*=*ptr1;
8156           *ptr=tmp;
8157         }
8158       else
8159         {
8160           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8161           throw INTERP_KERNEL::Exception(oss.str().c_str());
8162         }
8163     }
8164   return ret.retn();
8165 }
8166
8167 /*!
8168  * Apply pow on values of another DataArrayInt to values of \a this one.
8169  *
8170  *  \param [in] other - an array to pow to \a this one.
8171  *  \throw If \a other is NULL.
8172  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8173  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8174  *  \throw If there is a negative value in \a other.
8175  */
8176 void DataArrayInt::powEqual(const DataArrayInt *other)
8177 {
8178   if(!other)
8179     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8180   int nbOfTuple=getNumberOfTuples();
8181   int nbOfTuple2=other->getNumberOfTuples();
8182   int nbOfComp=getNumberOfComponents();
8183   int nbOfComp2=other->getNumberOfComponents();
8184   if(nbOfTuple!=nbOfTuple2)
8185     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8186   if(nbOfComp!=1 || nbOfComp2!=1)
8187     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8188   int *ptr=getPointer();
8189   const int *ptrc=other->begin();
8190   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8191     {
8192       if(*ptrc>=0)
8193         {
8194           int tmp=1;
8195           for(int j=0;j<*ptrc;j++)
8196             tmp*=*ptr;
8197           *ptr=tmp;
8198         }
8199       else
8200         {
8201           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8202           throw INTERP_KERNEL::Exception(oss.str().c_str());
8203         }
8204     }
8205   declareAsNew();
8206 }
8207
8208 /*!
8209  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8210  * This map, if applied to \a start array, would make it sorted. For example, if
8211  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8212  * [5,6,0,3,2,7,1,4].
8213  *  \param [in] start - pointer to the first element of the array for which the
8214  *         permutation map is computed.
8215  *  \param [in] end - pointer specifying the end of the array \a start, so that
8216  *         the last value of \a start is \a end[ -1 ].
8217  *  \return int * - the result permutation array that the caller is to delete as it is no
8218  *         more needed.
8219  *  \throw If there are equal values in the input array.
8220  */
8221 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
8222 {
8223   std::size_t sz=std::distance(start,end);
8224   int *ret=(int *)malloc(sz*sizeof(int));
8225   int *work=new int[sz];
8226   std::copy(start,end,work);
8227   std::sort(work,work+sz);
8228   if(std::unique(work,work+sz)!=work+sz)
8229     {
8230       delete [] work;
8231       free(ret);
8232       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
8233     }
8234   std::map<int,int> m;
8235   for(int *workPt=work;workPt!=work+sz;workPt++)
8236     m[*workPt]=(int)std::distance(work,workPt);
8237   int *iter2=ret;
8238   for(const int *iter=start;iter!=end;iter++,iter2++)
8239     *iter2=m[*iter];
8240   delete [] work;
8241   return ret;
8242 }
8243
8244 /*!
8245  * Returns a new DataArrayInt containing an arithmetic progression
8246  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
8247  * function.
8248  *  \param [in] begin - the start value of the result sequence.
8249  *  \param [in] end - limiting value, so that every value of the result array is less than
8250  *              \a end.
8251  *  \param [in] step - specifies the increment or decrement.
8252  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8253  *          array using decrRef() as it is no more needed.
8254  *  \throw If \a step == 0.
8255  *  \throw If \a end < \a begin && \a step > 0.
8256  *  \throw If \a end > \a begin && \a step < 0.
8257  */
8258 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
8259 {
8260   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
8261   MCAuto<DataArrayInt> ret=DataArrayInt::New();
8262   ret->alloc(nbOfTuples,1);
8263   int *ptr=ret->getPointer();
8264   if(step>0)
8265     {
8266       for(int i=begin;i<end;i+=step,ptr++)
8267         *ptr=i;
8268     }
8269   else
8270     {
8271       for(int i=begin;i>end;i+=step,ptr++)
8272         *ptr=i;
8273     }
8274   return ret.retn();
8275 }
8276
8277 /*!
8278  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8279  * Server side.
8280  */
8281 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
8282 {
8283   tinyInfo.resize(2);
8284   if(isAllocated())
8285     {
8286       tinyInfo[0]=getNumberOfTuples();
8287       tinyInfo[1]=getNumberOfComponents();
8288     }
8289   else
8290     {
8291       tinyInfo[0]=-1;
8292       tinyInfo[1]=-1;
8293     }
8294 }
8295
8296 /*!
8297  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8298  * Server side.
8299  */
8300 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
8301 {
8302   if(isAllocated())
8303     {
8304       int nbOfCompo=getNumberOfComponents();
8305       tinyInfo.resize(nbOfCompo+1);
8306       tinyInfo[0]=getName();
8307       for(int i=0;i<nbOfCompo;i++)
8308         tinyInfo[i+1]=getInfoOnComponent(i);
8309     }
8310   else
8311     {
8312       tinyInfo.resize(1);
8313       tinyInfo[0]=getName();
8314     }
8315 }
8316
8317 /*!
8318  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8319  * This method returns if a feeding is needed.
8320  */
8321 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
8322 {
8323   int nbOfTuple=tinyInfoI[0];
8324   int nbOfComp=tinyInfoI[1];
8325   if(nbOfTuple!=-1 || nbOfComp!=-1)
8326     {
8327       alloc(nbOfTuple,nbOfComp);
8328       return true;
8329     }
8330   return false;
8331 }
8332
8333 /*!
8334  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8335  * This method returns if a feeding is needed.
8336  */
8337 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
8338 {
8339   setName(tinyInfoS[0]);
8340   if(isAllocated())
8341     {
8342       int nbOfCompo=tinyInfoI[1];
8343       for(int i=0;i<nbOfCompo;i++)
8344         setInfoOnComponent(i,tinyInfoS[i+1]);
8345     }
8346 }
8347
8348 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
8349 {
8350 }
8351
8352 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
8353 {
8354 }
8355
8356 std::string DataArrayIntTuple::repr() const
8357 {
8358   std::ostringstream oss; oss << "(";
8359   for(int i=0;i<_nb_of_compo-1;i++)
8360     oss << _pt[i] << ", ";
8361   oss << _pt[_nb_of_compo-1] << ")";
8362   return oss.str();
8363 }
8364
8365 int DataArrayIntTuple::intValue() const
8366 {
8367   return this->zeValue();
8368 }
8369
8370 /*!
8371  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
8372  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
8373  * 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
8374  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
8375  */
8376 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
8377 {
8378   return this->buildDA(nbOfTuples,nbOfCompo);
8379 }