]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDCoupling/MEDCouplingMemArray.cxx
Salome HOME
On the road
[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  * Apply a linear function to a given component of \a this array, so that
2776  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2777  *  \param [in] a - the first coefficient of the function.
2778  *  \param [in] b - the second coefficient of the function.
2779  *  \param [in] compoId - the index of component to modify.
2780  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2781  */
2782 void DataArrayDouble::applyLin(double a, double b, int compoId)
2783 {
2784   checkAllocated();
2785   double *ptr(getPointer()+compoId);
2786   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2787   if(compoId<0 || compoId>=nbOfComp)
2788     {
2789       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2790       throw INTERP_KERNEL::Exception(oss.str().c_str());
2791     }
2792   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2793     *ptr=a*(*ptr)+b;
2794   declareAsNew();
2795 }
2796
2797 /*!
2798  * Apply a linear function to all elements of \a this array, so that
2799  * an element _x_ becomes \f$ a * x + b \f$.
2800  *  \param [in] a - the first coefficient of the function.
2801  *  \param [in] b - the second coefficient of the function.
2802  *  \throw If \a this is not allocated.
2803  */
2804 void DataArrayDouble::applyLin(double a, double b)
2805 {
2806   checkAllocated();
2807   double *ptr=getPointer();
2808   std::size_t nbOfElems=getNbOfElems();
2809   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2810     *ptr=a*(*ptr)+b;
2811   declareAsNew();
2812 }
2813
2814 /*!
2815  * Modify all elements of \a this array, so that
2816  * an element _x_ becomes \f$ numerator / x \f$.
2817  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2818  *           array, all elements processed before detection of the zero element remain
2819  *           modified.
2820  *  \param [in] numerator - the numerator used to modify array elements.
2821  *  \throw If \a this is not allocated.
2822  *  \throw If there is an element equal to 0.0 in \a this array.
2823  */
2824 void DataArrayDouble::applyInv(double numerator)
2825 {
2826   checkAllocated();
2827   double *ptr=getPointer();
2828   std::size_t nbOfElems=getNbOfElems();
2829   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2830     {
2831       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2832         {
2833           *ptr=numerator/(*ptr);
2834         }
2835       else
2836         {
2837           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2838           oss << " !";
2839           throw INTERP_KERNEL::Exception(oss.str().c_str());
2840         }
2841     }
2842   declareAsNew();
2843 }
2844
2845 /*!
2846  * Returns a full copy of \a this array except that sign of all elements is reversed.
2847  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2848  *          same number of tuples and component as \a this array.
2849  *          The caller is to delete this result array using decrRef() as it is no more
2850  *          needed.
2851  *  \throw If \a this is not allocated.
2852  */
2853 DataArrayDouble *DataArrayDouble::negate() const
2854 {
2855   checkAllocated();
2856   DataArrayDouble *newArr=DataArrayDouble::New();
2857   int nbOfTuples=getNumberOfTuples();
2858   int nbOfComp=getNumberOfComponents();
2859   newArr->alloc(nbOfTuples,nbOfComp);
2860   const double *cptr=getConstPointer();
2861   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2862   newArr->copyStringInfoFrom(*this);
2863   return newArr;
2864 }
2865
2866 /*!
2867  * Modify all elements of \a this array, so that
2868  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2869  * all values in \a this have to be >= 0 if val is \b not integer.
2870  *  \param [in] val - the value used to apply pow on all array elements.
2871  *  \throw If \a this is not allocated.
2872  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2873  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2874  *           modified.
2875  */
2876 void DataArrayDouble::applyPow(double val)
2877 {
2878   checkAllocated();
2879   double *ptr=getPointer();
2880   std::size_t nbOfElems=getNbOfElems();
2881   int val2=(int)val;
2882   bool isInt=((double)val2)==val;
2883   if(!isInt)
2884     {
2885       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2886         {
2887           if(*ptr>=0)
2888             *ptr=pow(*ptr,val);
2889           else
2890             {
2891               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2892               throw INTERP_KERNEL::Exception(oss.str().c_str());
2893             }
2894         }
2895     }
2896   else
2897     {
2898       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2899         *ptr=pow(*ptr,val2);
2900     }
2901   declareAsNew();
2902 }
2903
2904 /*!
2905  * Modify all elements of \a this array, so that
2906  * an element _x_ becomes \f$ val ^ x \f$.
2907  *  \param [in] val - the value used to apply pow on all array elements.
2908  *  \throw If \a this is not allocated.
2909  *  \throw If \a val < 0.
2910  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2911  *           array, all elements processed before detection of the zero element remain
2912  *           modified.
2913  */
2914 void DataArrayDouble::applyRPow(double val)
2915 {
2916   checkAllocated();
2917   if(val<0.)
2918     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2919   double *ptr=getPointer();
2920   std::size_t nbOfElems=getNbOfElems();
2921   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2922     *ptr=pow(val,*ptr);
2923   declareAsNew();
2924 }
2925
2926 /*!
2927  * Returns a new DataArrayDouble created from \a this one by applying \a
2928  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2929  * For more info see \ref MEDCouplingArrayApplyFunc
2930  *  \param [in] nbOfComp - number of components in the result array.
2931  *  \param [in] func - the \a FunctionToEvaluate declared as 
2932  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2933  *              where \a pos points to the first component of a tuple of \a this array
2934  *              and \a res points to the first component of a tuple of the result array.
2935  *              Note that length (number of components) of \a pos can differ from
2936  *              that of \a res.
2937  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2938  *          same number of tuples as \a this array.
2939  *          The caller is to delete this result array using decrRef() as it is no more
2940  *          needed.
2941  *  \throw If \a this is not allocated.
2942  *  \throw If \a func returns \a false.
2943  */
2944 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2945 {
2946   checkAllocated();
2947   DataArrayDouble *newArr=DataArrayDouble::New();
2948   int nbOfTuples=getNumberOfTuples();
2949   int oldNbOfComp=getNumberOfComponents();
2950   newArr->alloc(nbOfTuples,nbOfComp);
2951   const double *ptr=getConstPointer();
2952   double *ptrToFill=newArr->getPointer();
2953   for(int i=0;i<nbOfTuples;i++)
2954     {
2955       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2956         {
2957           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2958           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2959           oss << ") : Evaluation of function failed !";
2960           newArr->decrRef();
2961           throw INTERP_KERNEL::Exception(oss.str().c_str());
2962         }
2963     }
2964   return newArr;
2965 }
2966
2967 /*!
2968  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2969  * tuple of \a this array. Textual data is not copied.
2970  * For more info see \ref MEDCouplingArrayApplyFunc1.
2971  *  \param [in] nbOfComp - number of components in the result array.
2972  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2973  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2974  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2975  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2976  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2977  *          same number of tuples as \a this array and \a nbOfComp components.
2978  *          The caller is to delete this result array using decrRef() as it is no more
2979  *          needed.
2980  *  \throw If \a this is not allocated.
2981  *  \throw If computing \a func fails.
2982  */
2983 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2984 {
2985   INTERP_KERNEL::ExprParser expr(func);
2986   expr.parse();
2987   std::set<std::string> vars;
2988   expr.getTrueSetOfVars(vars);
2989   std::vector<std::string> varsV(vars.begin(),vars.end());
2990   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2991 }
2992
2993 /*!
2994  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2995  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2996  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2997  *
2998  * For more info see \ref MEDCouplingArrayApplyFunc0.
2999  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3000  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3001  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3002  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3003  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3004  *          same number of tuples and components as \a this array.
3005  *          The caller is to delete this result array using decrRef() as it is no more
3006  *          needed.
3007  *  \sa applyFuncOnThis
3008  *  \throw If \a this is not allocated.
3009  *  \throw If computing \a func fails.
3010  */
3011 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3012 {
3013   int nbOfComp(getNumberOfComponents());
3014   if(nbOfComp<=0)
3015     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3016   checkAllocated();
3017   int nbOfTuples(getNumberOfTuples());
3018   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3019   newArr->alloc(nbOfTuples,nbOfComp);
3020   INTERP_KERNEL::ExprParser expr(func);
3021   expr.parse();
3022   std::set<std::string> vars;
3023   expr.getTrueSetOfVars(vars);
3024   if((int)vars.size()>1)
3025     {
3026       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 : ";
3027       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3028       throw INTERP_KERNEL::Exception(oss.str().c_str());
3029     }
3030   if(vars.empty())
3031     {
3032       expr.prepareFastEvaluator();
3033       newArr->rearrange(1);
3034       newArr->fillWithValue(expr.evaluateDouble());
3035       newArr->rearrange(nbOfComp);
3036       return newArr.retn();
3037     }
3038   std::vector<std::string> vars2(vars.begin(),vars.end());
3039   double buff,*ptrToFill(newArr->getPointer());
3040   const double *ptr(begin());
3041   std::vector<double> stck;
3042   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3043   expr.prepareFastEvaluator();
3044   if(!isSafe)
3045     {
3046       for(int i=0;i<nbOfTuples;i++)
3047         {
3048           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3049             {
3050               buff=*ptr;
3051               expr.evaluateDoubleInternal(stck);
3052               *ptrToFill=stck.back();
3053               stck.pop_back();
3054             }
3055         }
3056     }
3057   else
3058     {
3059       for(int i=0;i<nbOfTuples;i++)
3060         {
3061           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3062             {
3063               buff=*ptr;
3064               try
3065               {
3066                   expr.evaluateDoubleInternalSafe(stck);
3067               }
3068               catch(INTERP_KERNEL::Exception& e)
3069               {
3070                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3071                   oss << buff;
3072                   oss << ") : Evaluation of function failed !" << e.what();
3073                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3074               }
3075               *ptrToFill=stck.back();
3076               stck.pop_back();
3077             }
3078         }
3079     }
3080   return newArr.retn();
3081 }
3082
3083 /*!
3084  * This method is a non const method that modify the array in \a this.
3085  * This method only works on one component array. It means that function \a func must
3086  * contain at most one variable.
3087  * This method is a specialization of applyFunc method with one parameter on one component array.
3088  *
3089  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3090  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3091  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3092  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3093  *
3094  * \sa applyFunc
3095  */
3096 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3097 {
3098   int nbOfComp(getNumberOfComponents());
3099   if(nbOfComp<=0)
3100     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3101   checkAllocated();
3102   int nbOfTuples(getNumberOfTuples());
3103   INTERP_KERNEL::ExprParser expr(func);
3104   expr.parse();
3105   std::set<std::string> vars;
3106   expr.getTrueSetOfVars(vars);
3107   if((int)vars.size()>1)
3108     {
3109       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 : ";
3110       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3111       throw INTERP_KERNEL::Exception(oss.str().c_str());
3112     }
3113   if(vars.empty())
3114     {
3115       expr.prepareFastEvaluator();
3116       std::vector<std::string> compInfo(getInfoOnComponents());
3117       rearrange(1);
3118       fillWithValue(expr.evaluateDouble());
3119       rearrange(nbOfComp);
3120       setInfoOnComponents(compInfo);
3121       return ;
3122     }
3123   std::vector<std::string> vars2(vars.begin(),vars.end());
3124   double buff,*ptrToFill(getPointer());
3125   const double *ptr(begin());
3126   std::vector<double> stck;
3127   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3128   expr.prepareFastEvaluator();
3129   if(!isSafe)
3130     {
3131       for(int i=0;i<nbOfTuples;i++)
3132         {
3133           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3134             {
3135               buff=*ptr;
3136               expr.evaluateDoubleInternal(stck);
3137               *ptrToFill=stck.back();
3138               stck.pop_back();
3139             }
3140         }
3141     }
3142   else
3143     {
3144       for(int i=0;i<nbOfTuples;i++)
3145         {
3146           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3147             {
3148               buff=*ptr;
3149               try
3150               {
3151                   expr.evaluateDoubleInternalSafe(stck);
3152               }
3153               catch(INTERP_KERNEL::Exception& e)
3154               {
3155                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3156                   oss << buff;
3157                   oss << ") : Evaluation of function failed !" << e.what();
3158                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3159               }
3160               *ptrToFill=stck.back();
3161               stck.pop_back();
3162             }
3163         }
3164     }
3165 }
3166
3167 /*!
3168  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3169  * tuple of \a this array. Textual data is not copied.
3170  * For more info see \ref MEDCouplingArrayApplyFunc2.
3171  *  \param [in] nbOfComp - number of components in the result array.
3172  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3173  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3174  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3175  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3176  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3177  *          same number of tuples as \a this array.
3178  *          The caller is to delete this result array using decrRef() as it is no more
3179  *          needed.
3180  *  \throw If \a this is not allocated.
3181  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3182  *  \throw If computing \a func fails.
3183  */
3184 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3185 {
3186   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3187 }
3188
3189 /*!
3190  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3191  * tuple of \a this array. Textual data is not copied.
3192  * For more info see \ref MEDCouplingArrayApplyFunc3.
3193  *  \param [in] nbOfComp - number of components in the result array.
3194  *  \param [in] varsOrder - sequence of vars defining their order.
3195  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3196  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3197  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3198  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3199  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3200  *          same number of tuples as \a this array.
3201  *          The caller is to delete this result array using decrRef() as it is no more
3202  *          needed.
3203  *  \throw If \a this is not allocated.
3204  *  \throw If \a func contains vars not in \a varsOrder.
3205  *  \throw If computing \a func fails.
3206  */
3207 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3208 {
3209   if(nbOfComp<=0)
3210     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3211   std::vector<std::string> varsOrder2(varsOrder);
3212   int oldNbOfComp(getNumberOfComponents());
3213   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3214     varsOrder2.push_back(std::string());
3215   checkAllocated();
3216   int nbOfTuples(getNumberOfTuples());
3217   INTERP_KERNEL::ExprParser expr(func);
3218   expr.parse();
3219   std::set<std::string> vars;
3220   expr.getTrueSetOfVars(vars);
3221   if((int)vars.size()>oldNbOfComp)
3222     {
3223       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3224       oss << vars.size() << " variables : ";
3225       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3226       throw INTERP_KERNEL::Exception(oss.str().c_str());
3227     }
3228   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3229   newArr->alloc(nbOfTuples,nbOfComp);
3230   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3231   double *buffPtr(buff),*ptrToFill;
3232   std::vector<double> stck;
3233   for(int iComp=0;iComp<nbOfComp;iComp++)
3234     {
3235       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3236       expr.prepareFastEvaluator();
3237       const double *ptr(getConstPointer());
3238       ptrToFill=newArr->getPointer()+iComp;
3239       if(!isSafe)
3240         {
3241           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3242             {
3243               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3244               expr.evaluateDoubleInternal(stck);
3245               *ptrToFill=stck.back();
3246               stck.pop_back();
3247             }
3248         }
3249       else
3250         {
3251           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3252             {
3253               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3254               try
3255               {
3256                   expr.evaluateDoubleInternalSafe(stck);
3257                   *ptrToFill=stck.back();
3258                   stck.pop_back();
3259               }
3260               catch(INTERP_KERNEL::Exception& e)
3261               {
3262                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3263                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3264                   oss << ") : Evaluation of function failed !" << e.what();
3265                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3266               }
3267             }
3268         }
3269     }
3270   return newArr.retn();
3271 }
3272
3273 void DataArrayDouble::applyFuncFast32(const std::string& func)
3274 {
3275   checkAllocated();
3276   INTERP_KERNEL::ExprParser expr(func);
3277   expr.parse();
3278   char *funcStr=expr.compileX86();
3279   MYFUNCPTR funcPtr;
3280   *((void **)&funcPtr)=funcStr;//he he...
3281   //
3282   double *ptr=getPointer();
3283   int nbOfComp=getNumberOfComponents();
3284   int nbOfTuples=getNumberOfTuples();
3285   int nbOfElems=nbOfTuples*nbOfComp;
3286   for(int i=0;i<nbOfElems;i++,ptr++)
3287     *ptr=funcPtr(*ptr);
3288   declareAsNew();
3289 }
3290
3291 void DataArrayDouble::applyFuncFast64(const std::string& func)
3292 {
3293   checkAllocated();
3294   INTERP_KERNEL::ExprParser expr(func);
3295   expr.parse();
3296   char *funcStr=expr.compileX86_64();
3297   MYFUNCPTR funcPtr;
3298   *((void **)&funcPtr)=funcStr;//he he...
3299   //
3300   double *ptr=getPointer();
3301   int nbOfComp=getNumberOfComponents();
3302   int nbOfTuples=getNumberOfTuples();
3303   int nbOfElems=nbOfTuples*nbOfComp;
3304   for(int i=0;i<nbOfElems;i++,ptr++)
3305     *ptr=funcPtr(*ptr);
3306   declareAsNew();
3307 }
3308
3309 /*!
3310  * \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.
3311  */
3312 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3313 {
3314   checkAllocated();
3315   if(getNumberOfComponents()!=3)
3316     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3317   int nbTuples(getNumberOfTuples());
3318   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3319   ret->alloc(nbTuples,3);
3320   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3321   return ret;
3322 }
3323
3324 DataArrayDoubleIterator *DataArrayDouble::iterator()
3325 {
3326   return new DataArrayDoubleIterator(this);
3327 }
3328
3329 /*!
3330  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3331  * array whose values are within a given range. Textual data is not copied.
3332  *  \param [in] vmin - a lowest acceptable value (included).
3333  *  \param [in] vmax - a greatest acceptable value (included).
3334  *  \return DataArrayInt * - the new instance of DataArrayInt.
3335  *          The caller is to delete this result array using decrRef() as it is no more
3336  *          needed.
3337  *  \throw If \a this->getNumberOfComponents() != 1.
3338  *
3339  *  \sa DataArrayDouble::findIdsNotInRange
3340  *
3341  *  \if ENABLE_EXAMPLES
3342  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3343  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3344  *  \endif
3345  */
3346 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3347 {
3348   checkAllocated();
3349   if(getNumberOfComponents()!=1)
3350     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3351   const double *cptr(begin());
3352   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3353   int nbOfTuples(getNumberOfTuples());
3354   for(int i=0;i<nbOfTuples;i++,cptr++)
3355     if(*cptr>=vmin && *cptr<=vmax)
3356       ret->pushBackSilent(i);
3357   return ret.retn();
3358 }
3359
3360 /*!
3361  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3362  * array whose values are not within a given range. Textual data is not copied.
3363  *  \param [in] vmin - a lowest not acceptable value (excluded).
3364  *  \param [in] vmax - a greatest not acceptable value (excluded).
3365  *  \return DataArrayInt * - the new instance of DataArrayInt.
3366  *          The caller is to delete this result array using decrRef() as it is no more
3367  *          needed.
3368  *  \throw If \a this->getNumberOfComponents() != 1.
3369  *
3370  *  \sa DataArrayDouble::findIdsInRange
3371  */
3372 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3373 {
3374   checkAllocated();
3375   if(getNumberOfComponents()!=1)
3376     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3377   const double *cptr(begin());
3378   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3379   int nbOfTuples(getNumberOfTuples());
3380   for(int i=0;i<nbOfTuples;i++,cptr++)
3381     if(*cptr<vmin || *cptr>vmax)
3382       ret->pushBackSilent(i);
3383   return ret.retn();
3384 }
3385
3386 /*!
3387  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3388  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3389  * the number of component in the result array is same as that of each of given arrays.
3390  * Info on components is copied from the first of the given arrays. Number of components
3391  * in the given arrays must be  the same.
3392  *  \param [in] a1 - an array to include in the result array.
3393  *  \param [in] a2 - another array to include in the result array.
3394  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3395  *          The caller is to delete this result array using decrRef() as it is no more
3396  *          needed.
3397  *  \throw If both \a a1 and \a a2 are NULL.
3398  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3399  */
3400 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3401 {
3402   std::vector<const DataArrayDouble *> tmp(2);
3403   tmp[0]=a1; tmp[1]=a2;
3404   return Aggregate(tmp);
3405 }
3406
3407 /*!
3408  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3409  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3410  * the number of component in the result array is same as that of each of given arrays.
3411  * Info on components is copied from the first of the given arrays. Number of components
3412  * in the given arrays must be  the same.
3413  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3414  * not the object itself.
3415  *  \param [in] arr - a sequence of arrays to include in the result array.
3416  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3417  *          The caller is to delete this result array using decrRef() as it is no more
3418  *          needed.
3419  *  \throw If all arrays within \a arr are NULL.
3420  *  \throw If getNumberOfComponents() of arrays within \a arr.
3421  */
3422 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3423 {
3424   std::vector<const DataArrayDouble *> a;
3425   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3426     if(*it4)
3427       a.push_back(*it4);
3428   if(a.empty())
3429     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3430   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3431   int nbOfComp=(*it)->getNumberOfComponents();
3432   int nbt=(*it++)->getNumberOfTuples();
3433   for(int i=1;it!=a.end();it++,i++)
3434     {
3435       if((*it)->getNumberOfComponents()!=nbOfComp)
3436         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3437       nbt+=(*it)->getNumberOfTuples();
3438     }
3439   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3440   ret->alloc(nbt,nbOfComp);
3441   double *pt=ret->getPointer();
3442   for(it=a.begin();it!=a.end();it++)
3443     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3444   ret->copyStringInfoFrom(*(a[0]));
3445   return ret.retn();
3446 }
3447
3448 /*!
3449  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3450  * of components in the result array is a sum of the number of components of given arrays
3451  * and (2) the number of tuples in the result array is same as that of each of given
3452  * arrays. In other words the i-th tuple of result array includes all components of
3453  * i-th tuples of all given arrays.
3454  * Number of tuples in the given arrays must be  the same.
3455  *  \param [in] a1 - an array to include in the result array.
3456  *  \param [in] a2 - another array to include in the result array.
3457  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3458  *          The caller is to delete this result array using decrRef() as it is no more
3459  *          needed.
3460  *  \throw If both \a a1 and \a a2 are NULL.
3461  *  \throw If any given array is not allocated.
3462  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3463  */
3464 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3465 {
3466   std::vector<const DataArrayDouble *> arr(2);
3467   arr[0]=a1; arr[1]=a2;
3468   return Meld(arr);
3469 }
3470
3471 /*!
3472  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3473  * of components in the result array is a sum of the number of components of given arrays
3474  * and (2) the number of tuples in the result array is same as that of each of given
3475  * arrays. In other words the i-th tuple of result array includes all components of
3476  * i-th tuples of all given arrays.
3477  * Number of tuples in the given arrays must be  the same.
3478  *  \param [in] arr - a sequence of arrays to include in the result array.
3479  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3480  *          The caller is to delete this result array using decrRef() as it is no more
3481  *          needed.
3482  *  \throw If all arrays within \a arr are NULL.
3483  *  \throw If any given array is not allocated.
3484  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3485  */
3486 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3487 {
3488   std::vector<const DataArrayDouble *> a;
3489   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3490     if(*it4)
3491       a.push_back(*it4);
3492   if(a.empty())
3493     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3494   std::vector<const DataArrayDouble *>::const_iterator it;
3495   for(it=a.begin();it!=a.end();it++)
3496     (*it)->checkAllocated();
3497   it=a.begin();
3498   int nbOfTuples=(*it)->getNumberOfTuples();
3499   std::vector<int> nbc(a.size());
3500   std::vector<const double *> pts(a.size());
3501   nbc[0]=(*it)->getNumberOfComponents();
3502   pts[0]=(*it++)->getConstPointer();
3503   for(int i=1;it!=a.end();it++,i++)
3504     {
3505       if(nbOfTuples!=(*it)->getNumberOfTuples())
3506         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3507       nbc[i]=(*it)->getNumberOfComponents();
3508       pts[i]=(*it)->getConstPointer();
3509     }
3510   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3511   DataArrayDouble *ret=DataArrayDouble::New();
3512   ret->alloc(nbOfTuples,totalNbOfComp);
3513   double *retPtr=ret->getPointer();
3514   for(int i=0;i<nbOfTuples;i++)
3515     for(int j=0;j<(int)a.size();j++)
3516       {
3517         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3518         pts[j]+=nbc[j];
3519       }
3520   int k=0;
3521   for(int i=0;i<(int)a.size();i++)
3522     for(int j=0;j<nbc[i];j++,k++)
3523       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3524   return ret;
3525 }
3526
3527 /*!
3528  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3529  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3530  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3531  * Info on components and name is copied from the first of the given arrays.
3532  * Number of tuples and components in the given arrays must be the same.
3533  *  \param [in] a1 - a given array.
3534  *  \param [in] a2 - another given array.
3535  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3536  *          The caller is to delete this result array using decrRef() as it is no more
3537  *          needed.
3538  *  \throw If either \a a1 or \a a2 is NULL.
3539  *  \throw If any given array is not allocated.
3540  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3541  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3542  */
3543 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3544 {
3545   if(!a1 || !a2)
3546     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3547   a1->checkAllocated();
3548   a2->checkAllocated();
3549   int nbOfComp=a1->getNumberOfComponents();
3550   if(nbOfComp!=a2->getNumberOfComponents())
3551     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3552   int nbOfTuple=a1->getNumberOfTuples();
3553   if(nbOfTuple!=a2->getNumberOfTuples())
3554     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3555   DataArrayDouble *ret=DataArrayDouble::New();
3556   ret->alloc(nbOfTuple,1);
3557   double *retPtr=ret->getPointer();
3558   const double *a1Ptr=a1->getConstPointer();
3559   const double *a2Ptr=a2->getConstPointer();
3560   for(int i=0;i<nbOfTuple;i++)
3561     {
3562       double sum=0.;
3563       for(int j=0;j<nbOfComp;j++)
3564         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3565       retPtr[i]=sum;
3566     }
3567   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3568   ret->setName(a1->getName());
3569   return ret;
3570 }
3571
3572 /*!
3573  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3574  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3575  * product of two vectors defined by the i-th tuples of given arrays.
3576  * Info on components is copied from the first of the given arrays.
3577  * Number of tuples in the given arrays must be the same.
3578  * Number of components in the given arrays must be 3.
3579  *  \param [in] a1 - a given array.
3580  *  \param [in] a2 - another given array.
3581  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3582  *          The caller is to delete this result array using decrRef() as it is no more
3583  *          needed.
3584  *  \throw If either \a a1 or \a a2 is NULL.
3585  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3586  *  \throw If \a a1->getNumberOfComponents() != 3
3587  *  \throw If \a a2->getNumberOfComponents() != 3
3588  */
3589 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3590 {
3591   if(!a1 || !a2)
3592     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3593   int nbOfComp=a1->getNumberOfComponents();
3594   if(nbOfComp!=a2->getNumberOfComponents())
3595     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3596   if(nbOfComp!=3)
3597     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3598   int nbOfTuple=a1->getNumberOfTuples();
3599   if(nbOfTuple!=a2->getNumberOfTuples())
3600     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3601   DataArrayDouble *ret=DataArrayDouble::New();
3602   ret->alloc(nbOfTuple,3);
3603   double *retPtr=ret->getPointer();
3604   const double *a1Ptr=a1->getConstPointer();
3605   const double *a2Ptr=a2->getConstPointer();
3606   for(int i=0;i<nbOfTuple;i++)
3607     {
3608       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3609       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3610       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3611     }
3612   ret->copyStringInfoFrom(*a1);
3613   return ret;
3614 }
3615
3616 /*!
3617  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3618  * Info on components is copied from the first of the given arrays.
3619  * Number of tuples and components in the given arrays must be the same.
3620  *  \param [in] a1 - an array to compare values with another one.
3621  *  \param [in] a2 - another array to compare values with the first one.
3622  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3623  *          The caller is to delete this result array using decrRef() as it is no more
3624  *          needed.
3625  *  \throw If either \a a1 or \a a2 is NULL.
3626  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3627  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3628  */
3629 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3630 {
3631   if(!a1 || !a2)
3632     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3633   int nbOfComp=a1->getNumberOfComponents();
3634   if(nbOfComp!=a2->getNumberOfComponents())
3635     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3636   int nbOfTuple=a1->getNumberOfTuples();
3637   if(nbOfTuple!=a2->getNumberOfTuples())
3638     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3639   DataArrayDouble *ret=DataArrayDouble::New();
3640   ret->alloc(nbOfTuple,nbOfComp);
3641   double *retPtr=ret->getPointer();
3642   const double *a1Ptr=a1->getConstPointer();
3643   const double *a2Ptr=a2->getConstPointer();
3644   int nbElem=nbOfTuple*nbOfComp;
3645   for(int i=0;i<nbElem;i++)
3646     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3647   ret->copyStringInfoFrom(*a1);
3648   return ret;
3649 }
3650
3651 /*!
3652  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3653  * Info on components is copied from the first of the given arrays.
3654  * Number of tuples and components in the given arrays must be the same.
3655  *  \param [in] a1 - an array to compare values with another one.
3656  *  \param [in] a2 - another array to compare values with the first one.
3657  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3658  *          The caller is to delete this result array using decrRef() as it is no more
3659  *          needed.
3660  *  \throw If either \a a1 or \a a2 is NULL.
3661  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3662  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3663  */
3664 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3665 {
3666   if(!a1 || !a2)
3667     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3668   int nbOfComp=a1->getNumberOfComponents();
3669   if(nbOfComp!=a2->getNumberOfComponents())
3670     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3671   int nbOfTuple=a1->getNumberOfTuples();
3672   if(nbOfTuple!=a2->getNumberOfTuples())
3673     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3674   DataArrayDouble *ret=DataArrayDouble::New();
3675   ret->alloc(nbOfTuple,nbOfComp);
3676   double *retPtr=ret->getPointer();
3677   const double *a1Ptr=a1->getConstPointer();
3678   const double *a2Ptr=a2->getConstPointer();
3679   int nbElem=nbOfTuple*nbOfComp;
3680   for(int i=0;i<nbElem;i++)
3681     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3682   ret->copyStringInfoFrom(*a1);
3683   return ret;
3684 }
3685
3686 /*!
3687  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3688  * valid cases.
3689  * 1.  The arrays have same number of tuples and components. Then each value of
3690  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3691  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3692  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3693  *   component. Then
3694  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3695  * 3.  The arrays have same number of components and one array, say _a2_, has one
3696  *   tuple. Then
3697  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3698  *
3699  * Info on components is copied either from the first array (in the first case) or from
3700  * the array with maximal number of elements (getNbOfElems()).
3701  *  \param [in] a1 - an array to sum up.
3702  *  \param [in] a2 - another array to sum up.
3703  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3704  *          The caller is to delete this result array using decrRef() as it is no more
3705  *          needed.
3706  *  \throw If either \a a1 or \a a2 is NULL.
3707  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3708  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3709  *         none of them has number of tuples or components equal to 1.
3710  */
3711 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3712 {
3713   if(!a1 || !a2)
3714     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3715   int nbOfTuple=a1->getNumberOfTuples();
3716   int nbOfTuple2=a2->getNumberOfTuples();
3717   int nbOfComp=a1->getNumberOfComponents();
3718   int nbOfComp2=a2->getNumberOfComponents();
3719   MCAuto<DataArrayDouble> ret=0;
3720   if(nbOfTuple==nbOfTuple2)
3721     {
3722       if(nbOfComp==nbOfComp2)
3723         {
3724           ret=DataArrayDouble::New();
3725           ret->alloc(nbOfTuple,nbOfComp);
3726           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3727           ret->copyStringInfoFrom(*a1);
3728         }
3729       else
3730         {
3731           int nbOfCompMin,nbOfCompMax;
3732           const DataArrayDouble *aMin, *aMax;
3733           if(nbOfComp>nbOfComp2)
3734             {
3735               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3736               aMin=a2; aMax=a1;
3737             }
3738           else
3739             {
3740               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3741               aMin=a1; aMax=a2;
3742             }
3743           if(nbOfCompMin==1)
3744             {
3745               ret=DataArrayDouble::New();
3746               ret->alloc(nbOfTuple,nbOfCompMax);
3747               const double *aMinPtr=aMin->getConstPointer();
3748               const double *aMaxPtr=aMax->getConstPointer();
3749               double *res=ret->getPointer();
3750               for(int i=0;i<nbOfTuple;i++)
3751                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3752               ret->copyStringInfoFrom(*aMax);
3753             }
3754           else
3755             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3756         }
3757     }
3758   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3759     {
3760       if(nbOfComp==nbOfComp2)
3761         {
3762           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3763           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3764           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3765           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3766           ret=DataArrayDouble::New();
3767           ret->alloc(nbOfTupleMax,nbOfComp);
3768           double *res=ret->getPointer();
3769           for(int i=0;i<nbOfTupleMax;i++)
3770             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3771           ret->copyStringInfoFrom(*aMax);
3772         }
3773       else
3774         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3775     }
3776   else
3777     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3778   return ret.retn();
3779 }
3780
3781 /*!
3782  * Adds values of another DataArrayDouble to 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 added to 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 add to \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::addEqual(const DataArrayDouble *other)
3799 {
3800   if(!other)
3801     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3802   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
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::plus<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::plus<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::plus<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  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3844  * valid cases.
3845  * 1.  The arrays have same number of tuples and components. Then each value of
3846  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3847  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3848  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3849  *   component. Then
3850  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3851  * 3.  The arrays have same number of components and one array, say _a2_, has one
3852  *   tuple. Then
3853  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3854  *
3855  * Info on components is copied either from the first array (in the first case) or from
3856  * the array with maximal number of elements (getNbOfElems()).
3857  *  \param [in] a1 - an array to subtract from.
3858  *  \param [in] a2 - an array to subtract.
3859  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3860  *          The caller is to delete this result array using decrRef() as it is no more
3861  *          needed.
3862  *  \throw If either \a a1 or \a a2 is NULL.
3863  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3864  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3865  *         none of them has number of tuples or components equal to 1.
3866  */
3867 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3868 {
3869   if(!a1 || !a2)
3870     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3871   int nbOfTuple1=a1->getNumberOfTuples();
3872   int nbOfTuple2=a2->getNumberOfTuples();
3873   int nbOfComp1=a1->getNumberOfComponents();
3874   int nbOfComp2=a2->getNumberOfComponents();
3875   if(nbOfTuple2==nbOfTuple1)
3876     {
3877       if(nbOfComp1==nbOfComp2)
3878         {
3879           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3880           ret->alloc(nbOfTuple2,nbOfComp1);
3881           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3882           ret->copyStringInfoFrom(*a1);
3883           return ret.retn();
3884         }
3885       else if(nbOfComp2==1)
3886         {
3887           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3888           ret->alloc(nbOfTuple1,nbOfComp1);
3889           const double *a2Ptr=a2->getConstPointer();
3890           const double *a1Ptr=a1->getConstPointer();
3891           double *res=ret->getPointer();
3892           for(int i=0;i<nbOfTuple1;i++)
3893             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3894           ret->copyStringInfoFrom(*a1);
3895           return ret.retn();
3896         }
3897       else
3898         {
3899           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3900           return 0;
3901         }
3902     }
3903   else if(nbOfTuple2==1)
3904     {
3905       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3906       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3907       ret->alloc(nbOfTuple1,nbOfComp1);
3908       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3909       double *pt=ret->getPointer();
3910       for(int i=0;i<nbOfTuple1;i++)
3911         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3912       ret->copyStringInfoFrom(*a1);
3913       return ret.retn();
3914     }
3915   else
3916     {
3917       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3918       return 0;
3919     }
3920 }
3921
3922 /*!
3923  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3924  * valid cases.
3925  * 1.  The arrays have same number of tuples and components. Then each value of
3926  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3927  *   _a_ [ i, j ] -= _other_ [ i, j ].
3928  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3929  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3930  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3931  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3932  *
3933  *  \param [in] other - an array to subtract from \a this one.
3934  *  \throw If \a other is NULL.
3935  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3936  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3937  *         \a other has number of both tuples and components not equal to 1.
3938  */
3939 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3940 {
3941   if(!other)
3942     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3943   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3944   checkAllocated();
3945   other->checkAllocated();
3946   int nbOfTuple=getNumberOfTuples();
3947   int nbOfTuple2=other->getNumberOfTuples();
3948   int nbOfComp=getNumberOfComponents();
3949   int nbOfComp2=other->getNumberOfComponents();
3950   if(nbOfTuple==nbOfTuple2)
3951     {
3952       if(nbOfComp==nbOfComp2)
3953         {
3954           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3955         }
3956       else if(nbOfComp2==1)
3957         {
3958           double *ptr=getPointer();
3959           const double *ptrc=other->getConstPointer();
3960           for(int i=0;i<nbOfTuple;i++)
3961             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3962         }
3963       else
3964         throw INTERP_KERNEL::Exception(msg);
3965     }
3966   else if(nbOfTuple2==1)
3967     {
3968       if(nbOfComp2==nbOfComp)
3969         {
3970           double *ptr=getPointer();
3971           const double *ptrc=other->getConstPointer();
3972           for(int i=0;i<nbOfTuple;i++)
3973             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3974         }
3975       else
3976         throw INTERP_KERNEL::Exception(msg);
3977     }
3978   else
3979     throw INTERP_KERNEL::Exception(msg);
3980   declareAsNew();
3981 }
3982
3983 /*!
3984  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3985  * valid cases.
3986  * 1.  The arrays have same number of tuples and components. Then each value of
3987  *   the result array (_a_) is a product of the corresponding values of \a a1 and
3988  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3989  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3990  *   component. Then
3991  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3992  * 3.  The arrays have same number of components and one array, say _a2_, has one
3993  *   tuple. Then
3994  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3995  *
3996  * Info on components is copied either from the first array (in the first case) or from
3997  * the array with maximal number of elements (getNbOfElems()).
3998  *  \param [in] a1 - a factor array.
3999  *  \param [in] a2 - another factor array.
4000  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4001  *          The caller is to delete this result array using decrRef() as it is no more
4002  *          needed.
4003  *  \throw If either \a a1 or \a a2 is NULL.
4004  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4005  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4006  *         none of them has number of tuples or components equal to 1.
4007  */
4008 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4009 {
4010   if(!a1 || !a2)
4011     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4012   int nbOfTuple=a1->getNumberOfTuples();
4013   int nbOfTuple2=a2->getNumberOfTuples();
4014   int nbOfComp=a1->getNumberOfComponents();
4015   int nbOfComp2=a2->getNumberOfComponents();
4016   MCAuto<DataArrayDouble> ret=0;
4017   if(nbOfTuple==nbOfTuple2)
4018     {
4019       if(nbOfComp==nbOfComp2)
4020         {
4021           ret=DataArrayDouble::New();
4022           ret->alloc(nbOfTuple,nbOfComp);
4023           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4024           ret->copyStringInfoFrom(*a1);
4025         }
4026       else
4027         {
4028           int nbOfCompMin,nbOfCompMax;
4029           const DataArrayDouble *aMin, *aMax;
4030           if(nbOfComp>nbOfComp2)
4031             {
4032               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4033               aMin=a2; aMax=a1;
4034             }
4035           else
4036             {
4037               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4038               aMin=a1; aMax=a2;
4039             }
4040           if(nbOfCompMin==1)
4041             {
4042               ret=DataArrayDouble::New();
4043               ret->alloc(nbOfTuple,nbOfCompMax);
4044               const double *aMinPtr=aMin->getConstPointer();
4045               const double *aMaxPtr=aMax->getConstPointer();
4046               double *res=ret->getPointer();
4047               for(int i=0;i<nbOfTuple;i++)
4048                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4049               ret->copyStringInfoFrom(*aMax);
4050             }
4051           else
4052             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4053         }
4054     }
4055   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4056     {
4057       if(nbOfComp==nbOfComp2)
4058         {
4059           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4060           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4061           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4062           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4063           ret=DataArrayDouble::New();
4064           ret->alloc(nbOfTupleMax,nbOfComp);
4065           double *res=ret->getPointer();
4066           for(int i=0;i<nbOfTupleMax;i++)
4067             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4068           ret->copyStringInfoFrom(*aMax);
4069         }
4070       else
4071         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4072     }
4073   else
4074     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4075   return ret.retn();
4076 }
4077
4078 /*!
4079  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4080  * valid cases.
4081  * 1.  The arrays have same number of tuples and components. Then each value of
4082  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4083  *   _this_ [ i, j ] *= _other_ [ i, j ].
4084  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4085  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4086  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4087  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4088  *
4089  *  \param [in] other - an array to multiply to \a this one.
4090  *  \throw If \a other is NULL.
4091  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4092  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4093  *         \a other has number of both tuples and components not equal to 1.
4094  */
4095 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4096 {
4097   if(!other)
4098     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4099   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4100   checkAllocated();
4101   other->checkAllocated();
4102   int nbOfTuple=getNumberOfTuples();
4103   int nbOfTuple2=other->getNumberOfTuples();
4104   int nbOfComp=getNumberOfComponents();
4105   int nbOfComp2=other->getNumberOfComponents();
4106   if(nbOfTuple==nbOfTuple2)
4107     {
4108       if(nbOfComp==nbOfComp2)
4109         {
4110           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4111         }
4112       else if(nbOfComp2==1)
4113         {
4114           double *ptr=getPointer();
4115           const double *ptrc=other->getConstPointer();
4116           for(int i=0;i<nbOfTuple;i++)
4117             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4118         }
4119       else
4120         throw INTERP_KERNEL::Exception(msg);
4121     }
4122   else if(nbOfTuple2==1)
4123     {
4124       if(nbOfComp2==nbOfComp)
4125         {
4126           double *ptr=getPointer();
4127           const double *ptrc=other->getConstPointer();
4128           for(int i=0;i<nbOfTuple;i++)
4129             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4130         }
4131       else
4132         throw INTERP_KERNEL::Exception(msg);
4133     }
4134   else
4135     throw INTERP_KERNEL::Exception(msg);
4136   declareAsNew();
4137 }
4138
4139 /*!
4140  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4141  * valid cases.
4142  * 1.  The arrays have same number of tuples and components. Then each value of
4143  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4144  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4145  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4146  *   component. Then
4147  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4148  * 3.  The arrays have same number of components and one array, say _a2_, has one
4149  *   tuple. Then
4150  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4151  *
4152  * Info on components is copied either from the first array (in the first case) or from
4153  * the array with maximal number of elements (getNbOfElems()).
4154  *  \warning No check of division by zero is performed!
4155  *  \param [in] a1 - a numerator array.
4156  *  \param [in] a2 - a denominator array.
4157  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4158  *          The caller is to delete this result array using decrRef() as it is no more
4159  *          needed.
4160  *  \throw If either \a a1 or \a a2 is NULL.
4161  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4162  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4163  *         none of them has number of tuples or components equal to 1.
4164  */
4165 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4166 {
4167   if(!a1 || !a2)
4168     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4169   int nbOfTuple1=a1->getNumberOfTuples();
4170   int nbOfTuple2=a2->getNumberOfTuples();
4171   int nbOfComp1=a1->getNumberOfComponents();
4172   int nbOfComp2=a2->getNumberOfComponents();
4173   if(nbOfTuple2==nbOfTuple1)
4174     {
4175       if(nbOfComp1==nbOfComp2)
4176         {
4177           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4178           ret->alloc(nbOfTuple2,nbOfComp1);
4179           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4180           ret->copyStringInfoFrom(*a1);
4181           return ret.retn();
4182         }
4183       else if(nbOfComp2==1)
4184         {
4185           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4186           ret->alloc(nbOfTuple1,nbOfComp1);
4187           const double *a2Ptr=a2->getConstPointer();
4188           const double *a1Ptr=a1->getConstPointer();
4189           double *res=ret->getPointer();
4190           for(int i=0;i<nbOfTuple1;i++)
4191             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4192           ret->copyStringInfoFrom(*a1);
4193           return ret.retn();
4194         }
4195       else
4196         {
4197           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4198           return 0;
4199         }
4200     }
4201   else if(nbOfTuple2==1)
4202     {
4203       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4204       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4205       ret->alloc(nbOfTuple1,nbOfComp1);
4206       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4207       double *pt=ret->getPointer();
4208       for(int i=0;i<nbOfTuple1;i++)
4209         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4210       ret->copyStringInfoFrom(*a1);
4211       return ret.retn();
4212     }
4213   else
4214     {
4215       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4216       return 0;
4217     }
4218 }
4219
4220 /*!
4221  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4222  * valid cases.
4223  * 1.  The arrays have same number of tuples and components. Then each value of
4224  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4225  *   _a_ [ i, j ] /= _other_ [ i, j ].
4226  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4227  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4228  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4229  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4230  *
4231  *  \warning No check of division by zero is performed!
4232  *  \param [in] other - an array to divide \a this one by.
4233  *  \throw If \a other is NULL.
4234  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4235  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4236  *         \a other has number of both tuples and components not equal to 1.
4237  */
4238 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4239 {
4240   if(!other)
4241     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4242   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4243   checkAllocated();
4244   other->checkAllocated();
4245   int nbOfTuple=getNumberOfTuples();
4246   int nbOfTuple2=other->getNumberOfTuples();
4247   int nbOfComp=getNumberOfComponents();
4248   int nbOfComp2=other->getNumberOfComponents();
4249   if(nbOfTuple==nbOfTuple2)
4250     {
4251       if(nbOfComp==nbOfComp2)
4252         {
4253           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4254         }
4255       else if(nbOfComp2==1)
4256         {
4257           double *ptr=getPointer();
4258           const double *ptrc=other->getConstPointer();
4259           for(int i=0;i<nbOfTuple;i++)
4260             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4261         }
4262       else
4263         throw INTERP_KERNEL::Exception(msg);
4264     }
4265   else if(nbOfTuple2==1)
4266     {
4267       if(nbOfComp2==nbOfComp)
4268         {
4269           double *ptr=getPointer();
4270           const double *ptrc=other->getConstPointer();
4271           for(int i=0;i<nbOfTuple;i++)
4272             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4273         }
4274       else
4275         throw INTERP_KERNEL::Exception(msg);
4276     }
4277   else
4278     throw INTERP_KERNEL::Exception(msg);
4279   declareAsNew();
4280 }
4281
4282 /*!
4283  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4284  * valid cases.
4285  *
4286  *  \param [in] a1 - an array to pow up.
4287  *  \param [in] a2 - another array to sum up.
4288  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4289  *          The caller is to delete this result array using decrRef() as it is no more
4290  *          needed.
4291  *  \throw If either \a a1 or \a a2 is NULL.
4292  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4293  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4294  *  \throw If there is a negative value in \a a1.
4295  */
4296 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4297 {
4298   if(!a1 || !a2)
4299     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4300   int nbOfTuple=a1->getNumberOfTuples();
4301   int nbOfTuple2=a2->getNumberOfTuples();
4302   int nbOfComp=a1->getNumberOfComponents();
4303   int nbOfComp2=a2->getNumberOfComponents();
4304   if(nbOfTuple!=nbOfTuple2)
4305     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4306   if(nbOfComp!=1 || nbOfComp2!=1)
4307     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4308   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4309   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4310   double *ptr=ret->getPointer();
4311   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4312     {
4313       if(*ptr1>=0)
4314         {
4315           *ptr=pow(*ptr1,*ptr2);
4316         }
4317       else
4318         {
4319           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4320           throw INTERP_KERNEL::Exception(oss.str().c_str());
4321         }
4322     }
4323   return ret.retn();
4324 }
4325
4326 /*!
4327  * Apply pow on values of another DataArrayDouble to values of \a this one.
4328  *
4329  *  \param [in] other - an array to pow to \a this one.
4330  *  \throw If \a other is NULL.
4331  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4332  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4333  *  \throw If there is a negative value in \a this.
4334  */
4335 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4336 {
4337   if(!other)
4338     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4339   int nbOfTuple=getNumberOfTuples();
4340   int nbOfTuple2=other->getNumberOfTuples();
4341   int nbOfComp=getNumberOfComponents();
4342   int nbOfComp2=other->getNumberOfComponents();
4343   if(nbOfTuple!=nbOfTuple2)
4344     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4345   if(nbOfComp!=1 || nbOfComp2!=1)
4346     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4347   double *ptr=getPointer();
4348   const double *ptrc=other->begin();
4349   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4350     {
4351       if(*ptr>=0)
4352         *ptr=pow(*ptr,*ptrc);
4353       else
4354         {
4355           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4356           throw INTERP_KERNEL::Exception(oss.str().c_str());
4357         }
4358     }
4359   declareAsNew();
4360 }
4361
4362 /*!
4363  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4364  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4365  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4366  *
4367  * \throw if \a this is not allocated.
4368  * \throw if \a this has not exactly one component.
4369  */
4370 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4371 {
4372   checkAllocated();
4373   if(getNumberOfComponents()!=1)
4374     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4375   int nbt(getNumberOfTuples());
4376   std::vector<bool> ret(nbt);
4377   const double *pt(begin());
4378   for(int i=0;i<nbt;i++)
4379     {
4380       if(fabs(pt[i])<eps)
4381         ret[i]=false;
4382       else if(fabs(pt[i]-1.)<eps)
4383         ret[i]=true;
4384       else
4385         {
4386           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4387           throw INTERP_KERNEL::Exception(oss.str().c_str());
4388         }
4389     }
4390   return ret;
4391 }
4392
4393 /*!
4394  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4395  * Server side.
4396  */
4397 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4398 {
4399   tinyInfo.resize(2);
4400   if(isAllocated())
4401     {
4402       tinyInfo[0]=getNumberOfTuples();
4403       tinyInfo[1]=getNumberOfComponents();
4404     }
4405   else
4406     {
4407       tinyInfo[0]=-1;
4408       tinyInfo[1]=-1;
4409     }
4410 }
4411
4412 /*!
4413  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4414  * Server side.
4415  */
4416 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4417 {
4418   if(isAllocated())
4419     {
4420       int nbOfCompo=getNumberOfComponents();
4421       tinyInfo.resize(nbOfCompo+1);
4422       tinyInfo[0]=getName();
4423       for(int i=0;i<nbOfCompo;i++)
4424         tinyInfo[i+1]=getInfoOnComponent(i);
4425     }
4426   else
4427     {
4428       tinyInfo.resize(1);
4429       tinyInfo[0]=getName();
4430     }
4431 }
4432
4433 /*!
4434  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4435  * This method returns if a feeding is needed.
4436  */
4437 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4438 {
4439   int nbOfTuple=tinyInfoI[0];
4440   int nbOfComp=tinyInfoI[1];
4441   if(nbOfTuple!=-1 || nbOfComp!=-1)
4442     {
4443       alloc(nbOfTuple,nbOfComp);
4444       return true;
4445     }
4446   return false;
4447 }
4448
4449 /*!
4450  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4451  */
4452 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4453 {
4454   setName(tinyInfoS[0]);
4455   if(isAllocated())
4456     {
4457       int nbOfCompo=getNumberOfComponents();
4458       for(int i=0;i<nbOfCompo;i++)
4459         setInfoOnComponent(i,tinyInfoS[i+1]);
4460     }
4461 }
4462
4463 /*!
4464  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4465  * around an axe ( \a center, \a vect) and with angle \a angle.
4466  */
4467 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4468 {
4469   if(!center || !vect)
4470     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4471   double sina(sin(angle));
4472   double cosa(cos(angle));
4473   double vectorNorm[3];
4474   double matrix[9];
4475   double matrixTmp[9];
4476   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4477   if(norm<std::numeric_limits<double>::min())
4478     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4479   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4480   //rotation matrix computation
4481   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;
4482   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4483   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4484   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4485   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4486   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4487   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4488   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4489   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4490   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4491   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4492   //rotation matrix computed.
4493   double tmp[3];
4494   for(int i=0; i<nbNodes; i++)
4495     {
4496       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4497       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4498       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4499       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4500     }
4501 }
4502
4503 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4504 {
4505   double matrix[9],matrix2[9],matrix3[9];
4506   double vect[3],crossVect[3];
4507   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4508   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4509   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4510   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4511   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4512   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4513   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4514   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4515   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4516   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4517   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4518   for(int i=0;i<3;i++)
4519     for(int j=0;j<3;j++)
4520       {
4521         double val(0.);
4522         for(int k=0;k<3;k++)
4523           val+=matrix[3*i+k]*matrix2[3*k+j];
4524         matrix3[3*i+j]=val;
4525       }
4526   //rotation matrix computed.
4527   double tmp[3];
4528   for(int i=0; i<nbNodes; i++)
4529     {
4530       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4531       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4532       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4533       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4534     }
4535 }
4536
4537 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4538 {
4539   double vect[3],crossVect[3];
4540   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4541   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4542   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4543   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4544   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4545   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4546   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4547   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4548 }
4549
4550 /*!
4551  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4552  * around the center point \a center and with angle \a angle.
4553  */
4554 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4555 {
4556   double cosa=cos(angle);
4557   double sina=sin(angle);
4558   double matrix[4];
4559   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4560   double tmp[2];
4561   for(int i=0; i<nbNodes; i++)
4562     {
4563       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4564       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4565       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4566     }
4567 }
4568
4569 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
4570 {
4571 }
4572
4573 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
4574 {
4575 }
4576
4577
4578 std::string DataArrayDoubleTuple::repr() const
4579 {
4580   std::ostringstream oss; oss.precision(17); oss << "(";
4581   for(int i=0;i<_nb_of_compo-1;i++)
4582     oss << _pt[i] << ", ";
4583   oss << _pt[_nb_of_compo-1] << ")";
4584   return oss.str();
4585 }
4586
4587 double DataArrayDoubleTuple::doubleValue() const
4588 {
4589   return this->zeValue();
4590 }
4591
4592 /*!
4593  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4594  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4595  * 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
4596  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4597  */
4598 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4599 {
4600   return this->buildDA(nbOfTuples,nbOfCompo);
4601 }
4602
4603 /*!
4604  * Returns a new instance of DataArrayInt. The caller is to delete this array
4605  * using decrRef() as it is no more needed. 
4606  */
4607 DataArrayInt *DataArrayInt::New()
4608 {
4609   return new DataArrayInt;
4610 }
4611
4612 /*!
4613  * Returns the only one value in \a this, if and only if number of elements
4614  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4615  *  \return double - the sole value stored in \a this array.
4616  *  \throw If at least one of conditions stated above is not fulfilled.
4617  */
4618 int DataArrayInt::intValue() const
4619 {
4620   if(isAllocated())
4621     {
4622       if(getNbOfElems()==1)
4623         {
4624           return *getConstPointer();
4625         }
4626       else
4627         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4628     }
4629   else
4630     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4631 }
4632
4633 /*!
4634  * Returns an integer value characterizing \a this array, which is useful for a quick
4635  * comparison of many instances of DataArrayInt.
4636  *  \return int - the hash value.
4637  *  \throw If \a this is not allocated.
4638  */
4639 int DataArrayInt::getHashCode() const
4640 {
4641   checkAllocated();
4642   std::size_t nbOfElems=getNbOfElems();
4643   int ret=nbOfElems*65536;
4644   int delta=3;
4645   if(nbOfElems>48)
4646     delta=nbOfElems/8;
4647   int ret0=0;
4648   const int *pt=begin();
4649   for(std::size_t i=0;i<nbOfElems;i+=delta)
4650     ret0+=pt[i] & 0x1FFF;
4651   return ret+ret0;
4652 }
4653
4654 /*!
4655  * Returns a full copy of \a this. For more info on copying data arrays see
4656  * \ref MEDCouplingArrayBasicsCopyDeep.
4657  *  \return DataArrayInt * - a new instance of DataArrayInt.
4658  */
4659 DataArrayInt *DataArrayInt::deepCopy() const
4660 {
4661   return new DataArrayInt(*this);
4662 }
4663
4664 /*!
4665  * Returns either a \a deep or \a shallow copy of this array. For more info see
4666  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4667  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4668  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4669  *          == \a true) or \a this instance (if \a dCpy == \a false).
4670  */
4671 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4672 {
4673   return DataArrayTemplateClassic<int>::PerformCopyOrIncrRef(dCpy,*this);
4674 }
4675
4676 /*!
4677  * Assign zero to all values in \a this array. To know more on filling arrays see
4678  * \ref MEDCouplingArrayFill.
4679  * \throw If \a this is not allocated.
4680  */
4681 void DataArrayInt::fillWithZero()
4682 {
4683   fillWithValue(0);
4684 }
4685
4686 /*!
4687  * Set all values in \a this array so that the i-th element equals to \a init + i
4688  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4689  *  \param [in] init - value to assign to the first element of array.
4690  *  \throw If \a this->getNumberOfComponents() != 1
4691  *  \throw If \a this is not allocated.
4692  */
4693 void DataArrayInt::iota(int init)
4694 {
4695   checkAllocated();
4696   if(getNumberOfComponents()!=1)
4697     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4698   int *ptr=getPointer();
4699   int ntuples=getNumberOfTuples();
4700   for(int i=0;i<ntuples;i++)
4701     ptr[i]=init+i;
4702   declareAsNew();
4703 }
4704
4705 /*!
4706  * Returns a textual and human readable representation of \a this instance of
4707  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4708  * \return std::string - text describing \a this DataArrayInt.
4709  * 
4710  * \sa reprNotTooLong, reprZip
4711  */
4712 std::string DataArrayInt::repr() const
4713 {
4714   std::ostringstream ret;
4715   reprStream(ret);
4716   return ret.str();
4717 }
4718
4719 std::string DataArrayInt::reprZip() const
4720 {
4721   std::ostringstream ret;
4722   reprZipStream(ret);
4723   return ret.str();
4724 }
4725
4726 /*!
4727  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4728  * printed out to avoid to consume too much space in interpretor.
4729  * \sa repr
4730  */
4731 std::string DataArrayInt::reprNotTooLong() const
4732 {
4733   std::ostringstream ret;
4734   reprNotTooLongStream(ret);
4735   return ret.str();
4736 }
4737
4738 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4739 {
4740   static const char SPACE[4]={' ',' ',' ',' '};
4741   checkAllocated();
4742   std::string idt(indent,' ');
4743   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4744   if(byteArr)
4745     {
4746       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4747       if(std::string(type)=="Int32")
4748         {
4749           const char *data(reinterpret_cast<const char *>(begin()));
4750           std::size_t sz(getNbOfElems()*sizeof(int));
4751           byteArr->insertAtTheEnd(data,data+sz);
4752           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4753         }
4754       else if(std::string(type)=="Int8")
4755         {
4756           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4757           std::copy(begin(),end(),(char *)tmp);
4758           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4759           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4760         }
4761       else if(std::string(type)=="UInt8")
4762         {
4763           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4764           std::copy(begin(),end(),(unsigned char *)tmp);
4765           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4766           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4767         }
4768       else
4769         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4770     }
4771   else
4772     {
4773       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4774       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4775     }
4776   ofs << std::endl << idt << "</DataArray>\n";
4777 }
4778
4779 void DataArrayInt::reprStream(std::ostream& stream) const
4780 {
4781   stream << "Name of int array : \"" << _name << "\"\n";
4782   reprWithoutNameStream(stream);
4783 }
4784
4785 void DataArrayInt::reprZipStream(std::ostream& stream) const
4786 {
4787   stream << "Name of int array : \"" << _name << "\"\n";
4788   reprZipWithoutNameStream(stream);
4789 }
4790
4791 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4792 {
4793   stream << "Name of int array : \"" << _name << "\"\n";
4794   reprNotTooLongWithoutNameStream(stream);
4795 }
4796
4797 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4798 {
4799   DataArray::reprWithoutNameStream(stream);
4800   _mem.repr(getNumberOfComponents(),stream);
4801 }
4802
4803 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4804 {
4805   DataArray::reprWithoutNameStream(stream);
4806   _mem.reprZip(getNumberOfComponents(),stream);
4807 }
4808
4809 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4810 {
4811   DataArray::reprWithoutNameStream(stream);
4812   stream.precision(17);
4813   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4814 }
4815
4816 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4817 {
4818   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4819   const int *data=getConstPointer();
4820   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4821   if(nbTuples*nbComp>=1)
4822     {
4823       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4824       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4825       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4826       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4827     }
4828   else
4829     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4830   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4831 }
4832
4833 /*!
4834  * Method that gives a quick overvien of \a this for python.
4835  */
4836 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4837 {
4838   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4839   stream << "DataArrayInt C++ instance at " << this << ". ";
4840   if(isAllocated())
4841     {
4842       int nbOfCompo=(int)_info_on_compo.size();
4843       if(nbOfCompo>=1)
4844         {
4845           int nbOfTuples=getNumberOfTuples();
4846           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4847           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4848         }
4849       else
4850         stream << "Number of components : 0.";
4851     }
4852   else
4853     stream << "*** No data allocated ****";
4854 }
4855
4856 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4857 {
4858   const int *data=begin();
4859   int nbOfTuples=getNumberOfTuples();
4860   int nbOfCompo=(int)_info_on_compo.size();
4861   std::ostringstream oss2; oss2 << "[";
4862   std::string oss2Str(oss2.str());
4863   bool isFinished=true;
4864   for(int i=0;i<nbOfTuples && isFinished;i++)
4865     {
4866       if(nbOfCompo>1)
4867         {
4868           oss2 << "(";
4869           for(int j=0;j<nbOfCompo;j++,data++)
4870             {
4871               oss2 << *data;
4872               if(j!=nbOfCompo-1) oss2 << ", ";
4873             }
4874           oss2 << ")";
4875         }
4876       else
4877         oss2 << *data++;
4878       if(i!=nbOfTuples-1) oss2 << ", ";
4879       std::string oss3Str(oss2.str());
4880       if(oss3Str.length()<maxNbOfByteInRepr)
4881         oss2Str=oss3Str;
4882       else
4883         isFinished=false;
4884     }
4885   stream << oss2Str;
4886   if(!isFinished)
4887     stream << "... ";
4888   stream << "]";
4889 }
4890
4891 /*!
4892  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4893  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4894  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4895  *         to \a this array.
4896  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4897  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4898  *  \throw If \a this->getNumberOfComponents() != 1
4899  *  \throw If any value of \a this can't be used as a valid index for 
4900  *         [\a indArrBg, \a indArrEnd).
4901  *
4902  *  \sa changeValue
4903  */
4904 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4905 {
4906   checkAllocated();
4907   if(getNumberOfComponents()!=1)
4908     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4909   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4910   for(int i=0;i<nbOfTuples;i++,pt++)
4911     {
4912       if(*pt>=0 && *pt<nbElemsIn)
4913         *pt=indArrBg[*pt];
4914       else
4915         {
4916           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4917           throw INTERP_KERNEL::Exception(oss.str().c_str());
4918         }
4919     }
4920   declareAsNew();
4921 }
4922
4923 /*!
4924  * Computes distribution of values of \a this one-dimensional array between given value
4925  * ranges (casts). This method is typically useful for entity number spliting by types,
4926  * for example. 
4927  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4928  *           check of this is be done. If not, the result is not warranted. 
4929  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4930  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4931  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4932  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4933  *         should be more than every value in \a this array.
4934  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4935  *              the last value of \a arrBg is \a arrEnd[ -1 ].
4936  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4937  *         (same number of tuples and components), the caller is to delete 
4938  *         using decrRef() as it is no more needed.
4939  *         This array contains indices of ranges for every value of \a this array. I.e.
4940  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
4941  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
4942  *         this in which cast it holds.
4943  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4944  *         array, the caller is to delete using decrRef() as it is no more needed.
4945  *         This array contains ranks of values of \a this array within ranges
4946  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4947  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4948  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
4949  *         for each tuple its rank inside its cast. The rank is computed as difference
4950  *         between the value and the lowest value of range.
4951  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4952  *         ranges (casts) to which at least one value of \a this array belongs.
4953  *         Or, in other words, this param contains the casts that \a this contains.
4954  *         The caller is to delete this array using decrRef() as it is no more needed.
4955  *
4956  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4957  *            the output of this method will be : 
4958  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4959  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4960  * - \a castsPresent  : [0,1]
4961  *
4962  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4963  * range #1 and its rank within this range is 2; etc.
4964  *
4965  *  \throw If \a this->getNumberOfComponents() != 1.
4966  *  \throw If \a arrEnd - arrBg < 2.
4967  *  \throw If any value of \a this is not less than \a arrEnd[-1].
4968  */
4969 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4970                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4971 {
4972   checkAllocated();
4973   if(getNumberOfComponents()!=1)
4974     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4975   int nbOfTuples=getNumberOfTuples();
4976   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4977   if(nbOfCast<2)
4978     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4979   nbOfCast--;
4980   const int *work=getConstPointer();
4981   typedef std::reverse_iterator<const int *> rintstart;
4982   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4983   rintstart end2(arrBg);
4984   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4985   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4986   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4987   ret1->alloc(nbOfTuples,1);
4988   ret2->alloc(nbOfTuples,1);
4989   int *ret1Ptr=ret1->getPointer();
4990   int *ret2Ptr=ret2->getPointer();
4991   std::set<std::size_t> castsDetected;
4992   for(int i=0;i<nbOfTuples;i++)
4993     {
4994       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4995       std::size_t pos=std::distance(bg,res);
4996       std::size_t pos2=nbOfCast-pos;
4997       if(pos2<nbOfCast)
4998         {
4999           ret1Ptr[i]=(int)pos2;
5000           ret2Ptr[i]=work[i]-arrBg[pos2];
5001           castsDetected.insert(pos2);
5002         }
5003       else
5004         {
5005           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5006           throw INTERP_KERNEL::Exception(oss.str().c_str());
5007         }
5008     }
5009   ret3->alloc((int)castsDetected.size(),1);
5010   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5011   castArr=ret1.retn();
5012   rankInsideCast=ret2.retn();
5013   castsPresent=ret3.retn();
5014 }
5015
5016 /*!
5017  * 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 ).
5018  * 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 ).
5019  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5020  *
5021  * \param [out] strt - the start of the range (included) if true is returned.
5022  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5023  * \param [out] stteepp - the step of the range if true is returned.
5024  * \return the verdict of the check.
5025  *
5026  * \sa DataArray::GetNumberOfItemGivenBES
5027  */
5028 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5029 {
5030   checkAllocated();
5031   if(getNumberOfComponents()!=1)
5032     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5033   int nbTuples(getNumberOfTuples());
5034   if(nbTuples==0)
5035     { strt=0; sttoopp=0; stteepp=1; return true; }
5036   const int *pt(begin());
5037   strt=*pt; 
5038   if(nbTuples==1)
5039     { sttoopp=strt+1; stteepp=1; return true; }
5040   strt=*pt; sttoopp=pt[nbTuples-1];
5041   if(strt==sttoopp)
5042     return false;
5043   if(sttoopp>strt)
5044     {
5045       sttoopp++;
5046       int a(sttoopp-1-strt),tmp(strt);
5047       if(a%(nbTuples-1)!=0)
5048         return false;
5049       stteepp=a/(nbTuples-1);
5050       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5051         if(pt[i]!=tmp)
5052           return false;
5053       return true;
5054     }
5055   else
5056     {
5057       sttoopp--;
5058       int a(strt-sttoopp-1),tmp(strt);
5059       if(a%(nbTuples-1)!=0)
5060         return false;
5061       stteepp=-(a/(nbTuples-1));
5062       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5063         if(pt[i]!=tmp)
5064           return false;
5065       return true;
5066     }
5067 }
5068
5069 /*!
5070  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5071  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5072  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5073  * new value in place \a indArr[ \a v ] is i.
5074  *  \param [in] indArrBg - the array holding indices within the result array to assign
5075  *         indices of values of \a this array pointing to values of \a indArrBg.
5076  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5077  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5078  *  \return DataArrayInt * - the new instance of DataArrayInt.
5079  *          The caller is to delete this result array using decrRef() as it is no more
5080  *          needed.
5081  *  \throw If \a this->getNumberOfComponents() != 1.
5082  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5083  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5084  */
5085 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5086 {
5087   checkAllocated();
5088   if(getNumberOfComponents()!=1)
5089     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5090   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5091   int nbOfTuples=getNumberOfTuples();
5092   const int *pt=getConstPointer();
5093   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5094   ret->alloc(nbOfTuples,1);
5095   ret->fillWithValue(-1);
5096   int *tmp=ret->getPointer();
5097   for(int i=0;i<nbOfTuples;i++,pt++)
5098     {
5099       if(*pt>=0 && *pt<nbElemsIn)
5100         {
5101           int pos=indArrBg[*pt];
5102           if(pos>=0 && pos<nbOfTuples)
5103             tmp[pos]=i;
5104           else
5105             {
5106               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5107               throw INTERP_KERNEL::Exception(oss.str().c_str());
5108             }
5109         }
5110       else
5111         {
5112           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5113           throw INTERP_KERNEL::Exception(oss.str().c_str());
5114         }
5115     }
5116   return ret.retn();
5117 }
5118
5119 /*!
5120  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5121  * from values of \a this array, which is supposed to contain a renumbering map in 
5122  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5123  * To know how to use the renumbering maps see \ref numbering.
5124  *  \param [in] newNbOfElem - the number of tuples in the result array.
5125  *  \return DataArrayInt * - the new instance of DataArrayInt.
5126  *          The caller is to delete this result array using decrRef() as it is no more
5127  *          needed.
5128  * 
5129  *  \if ENABLE_EXAMPLES
5130  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5131  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5132  *  \endif
5133  */
5134 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5135 {
5136   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5137   ret->alloc(newNbOfElem,1);
5138   int nbOfOldNodes=getNumberOfTuples();
5139   const int *old2New=getConstPointer();
5140   int *pt=ret->getPointer();
5141   for(int i=0;i!=nbOfOldNodes;i++)
5142     {
5143       int newp(old2New[i]);
5144       if(newp!=-1)
5145         {
5146           if(newp>=0 && newp<newNbOfElem)
5147             pt[newp]=i;
5148           else
5149             {
5150               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5151               throw INTERP_KERNEL::Exception(oss.str().c_str());
5152             }
5153         }
5154     }
5155   return ret.retn();
5156 }
5157
5158 /*!
5159  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5160  * 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]
5161  */
5162 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5163 {
5164   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5165   ret->alloc(newNbOfElem,1);
5166   int nbOfOldNodes=getNumberOfTuples();
5167   const int *old2New=getConstPointer();
5168   int *pt=ret->getPointer();
5169   for(int i=nbOfOldNodes-1;i>=0;i--)
5170     {
5171       int newp(old2New[i]);
5172       if(newp!=-1)
5173         {
5174           if(newp>=0 && newp<newNbOfElem)
5175             pt[newp]=i;
5176           else
5177             {
5178               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5179               throw INTERP_KERNEL::Exception(oss.str().c_str());
5180             }
5181         }
5182     }
5183   return ret.retn();
5184 }
5185
5186 /*!
5187  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5188  * from values of \a this array, which is supposed to contain a renumbering map in 
5189  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5190  * To know how to use the renumbering maps see \ref numbering.
5191  *  \param [in] newNbOfElem - the number of tuples in the result array.
5192  *  \return DataArrayInt * - the new instance of DataArrayInt.
5193  *          The caller is to delete this result array using decrRef() as it is no more
5194  *          needed.
5195  * 
5196  *  \if ENABLE_EXAMPLES
5197  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5198  *
5199  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5200  *  \endif
5201  */
5202 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5203 {
5204   checkAllocated();
5205   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5206   ret->alloc(oldNbOfElem,1);
5207   const int *new2Old=getConstPointer();
5208   int *pt=ret->getPointer();
5209   std::fill(pt,pt+oldNbOfElem,-1);
5210   int nbOfNewElems=getNumberOfTuples();
5211   for(int i=0;i<nbOfNewElems;i++)
5212     {
5213       int v(new2Old[i]);
5214       if(v>=0 && v<oldNbOfElem)
5215         pt[v]=i;
5216       else
5217         {
5218           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5219           throw INTERP_KERNEL::Exception(oss.str().c_str());
5220         }
5221     }
5222   return ret.retn();
5223 }
5224
5225 /*!
5226  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5227  * mismatch is given.
5228  * 
5229  * \param [in] other the instance to be compared with \a this
5230  * \param [out] reason In case of inequality returns the reason.
5231  * \sa DataArrayInt::isEqual
5232  */
5233 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5234 {
5235   if(!areInfoEqualsIfNotWhy(other,reason))
5236     return false;
5237   return _mem.isEqual(other._mem,0,reason);
5238 }
5239
5240 /*!
5241  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5242  * \ref MEDCouplingArrayBasicsCompare.
5243  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5244  *  \return bool - \a true if the two arrays are equal, \a false else.
5245  */
5246 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5247 {
5248   std::string tmp;
5249   return isEqualIfNotWhy(other,tmp);
5250 }
5251
5252 /*!
5253  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5254  * \ref MEDCouplingArrayBasicsCompare.
5255  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5256  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5257  */
5258 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5259 {
5260   std::string tmp;
5261   return _mem.isEqual(other._mem,0,tmp);
5262 }
5263
5264 /*!
5265  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5266  * performed on sorted value sequences.
5267  * For more info see\ref MEDCouplingArrayBasicsCompare.
5268  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5269  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5270  */
5271 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5272 {
5273   MCAuto<DataArrayInt> a=deepCopy();
5274   MCAuto<DataArrayInt> b=other.deepCopy();
5275   a->sort();
5276   b->sort();
5277   return a->isEqualWithoutConsideringStr(*b);
5278 }
5279
5280 /*!
5281  * This method compares content of input vector \a v and \a this.
5282  * 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.
5283  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5284  *
5285  * \param [in] v - the vector of 'flags' to be compared with \a this.
5286  *
5287  * \throw If \a this is not sorted ascendingly.
5288  * \throw If \a this has not exactly one component.
5289  * \throw If \a this is not allocated.
5290  */
5291 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5292 {
5293   checkAllocated();
5294   if(getNumberOfComponents()!=1)
5295     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5296   const int *w(begin()),*end2(end());
5297   int refVal=-std::numeric_limits<int>::max();
5298   int i=0;
5299   std::vector<bool>::const_iterator it(v.begin());
5300   for(;it!=v.end();it++,i++)
5301     {
5302       if(*it)
5303         {
5304           if(w!=end2)
5305             {
5306               if(*w++==i)
5307                 {
5308                   if(i>refVal)
5309                     refVal=i;
5310                   else
5311                     {
5312                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5313                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5314                     }
5315                 }
5316               else
5317                 return false;
5318             }
5319           else
5320             return false;
5321         }
5322     }
5323   return w==end2;
5324 }
5325
5326 /*!
5327  * 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
5328  * put True to the corresponding entry in \a vec.
5329  * \a vec is expected to be with the same size than the number of tuples of \a this.
5330  *
5331  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5332  */
5333 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5334 {
5335   checkAllocated();
5336   if(getNumberOfComponents()!=1)
5337     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5338   int nbOfTuples(getNumberOfTuples());
5339   if(nbOfTuples!=(int)vec.size())
5340     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5341   const int *pt(begin());
5342   for(int i=0;i<nbOfTuples;i++)
5343     if(pt[i]==val)
5344       vec[i]=true;
5345 }
5346
5347 /*!
5348  * 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
5349  * put True to the corresponding entry in \a vec.
5350  * \a vec is expected to be with the same size than the number of tuples of \a this.
5351  * 
5352  *  \sa DataArrayInt::switchOnTupleEqualTo.
5353  */
5354 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5355 {
5356   checkAllocated();
5357   if(getNumberOfComponents()!=1)
5358     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5359   int nbOfTuples(getNumberOfTuples());
5360   if(nbOfTuples!=(int)vec.size())
5361     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5362   const int *pt(begin());
5363   for(int i=0;i<nbOfTuples;i++)
5364     if(pt[i]!=val)
5365       vec[i]=true;
5366 }
5367
5368 /*!
5369  * Computes for each tuple the sum of number of components values in the tuple and return it.
5370  * 
5371  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5372  *          same number of tuples as \a this array and one component.
5373  *          The caller is to delete this result array using decrRef() as it is no more
5374  *          needed.
5375  *  \throw If \a this is not allocated.
5376  */
5377 DataArrayInt *DataArrayInt::sumPerTuple() const
5378 {
5379   checkAllocated();
5380   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5381   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5382   ret->alloc(nbOfTuple,1);
5383   const int *src(getConstPointer());
5384   int *dest(ret->getPointer());
5385   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5386     *dest=std::accumulate(src,src+nbOfComp,0);
5387   return ret.retn();
5388 }
5389
5390 /*!
5391  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5392  * If not an exception is thrown.
5393  *  \param [in] increasing - if \a true, the array values should be increasing.
5394  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5395  *         increasing arg.
5396  *  \throw If \a this->getNumberOfComponents() != 1.
5397  *  \throw If \a this is not allocated.
5398  */
5399 void DataArrayInt::checkMonotonic(bool increasing) const
5400 {
5401   if(!isMonotonic(increasing))
5402     {
5403       if (increasing)
5404         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5405       else
5406         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5407     }
5408 }
5409
5410 /*!
5411  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5412  *  \param [in] increasing - if \a true, array values should be increasing.
5413  *  \return bool - \a true if values change in accordance with \a increasing arg.
5414  *  \throw If \a this->getNumberOfComponents() != 1.
5415  *  \throw If \a this is not allocated.
5416  */
5417 bool DataArrayInt::isMonotonic(bool increasing) const
5418 {
5419   checkAllocated();
5420   if(getNumberOfComponents()!=1)
5421     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5422   int nbOfElements=getNumberOfTuples();
5423   const int *ptr=getConstPointer();
5424   if(nbOfElements==0)
5425     return true;
5426   int ref=ptr[0];
5427   if(increasing)
5428     {
5429       for(int i=1;i<nbOfElements;i++)
5430         {
5431           if(ptr[i]>=ref)
5432             ref=ptr[i];
5433           else
5434             return false;
5435         }
5436     }
5437   else
5438     {
5439       for(int i=1;i<nbOfElements;i++)
5440         {
5441           if(ptr[i]<=ref)
5442             ref=ptr[i];
5443           else
5444             return false;
5445         }
5446     }
5447   return true;
5448 }
5449
5450 /*!
5451  * This method check that array consistently INCREASING or DECREASING in value.
5452  */
5453 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5454 {
5455   checkAllocated();
5456   if(getNumberOfComponents()!=1)
5457     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5458   int nbOfElements=getNumberOfTuples();
5459   const int *ptr=getConstPointer();
5460   if(nbOfElements==0)
5461     return true;
5462   int ref=ptr[0];
5463   if(increasing)
5464     {
5465       for(int i=1;i<nbOfElements;i++)
5466         {
5467           if(ptr[i]>ref)
5468             ref=ptr[i];
5469           else
5470             return false;
5471         }
5472     }
5473   else
5474     {
5475       for(int i=1;i<nbOfElements;i++)
5476         {
5477           if(ptr[i]<ref)
5478             ref=ptr[i];
5479           else
5480             return false;
5481         }
5482     }
5483   return true;
5484 }
5485
5486 /*!
5487  * This method check that array consistently INCREASING or DECREASING in value.
5488  */
5489 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5490 {
5491   if(!isStrictlyMonotonic(increasing))
5492     {
5493       if (increasing)
5494         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5495       else
5496         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5497     }
5498 }
5499
5500 /*!
5501  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5502  * one-dimensional arrays that must be of the same length. The result array describes
5503  * correspondence between \a this and \a other arrays, so that 
5504  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5505  * not possible because some element in \a other is not in \a this, an exception is thrown.
5506  *  \param [in] other - an array to compute permutation to.
5507  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5508  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5509  * no more needed.
5510  *  \throw If \a this->getNumberOfComponents() != 1.
5511  *  \throw If \a other->getNumberOfComponents() != 1.
5512  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5513  *  \throw If \a other includes a value which is not in \a this array.
5514  * 
5515  *  \if ENABLE_EXAMPLES
5516  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5517  *
5518  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5519  *  \endif
5520  */
5521 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5522 {
5523   checkAllocated();
5524   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5525     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5526   int nbTuple=getNumberOfTuples();
5527   other.checkAllocated();
5528   if(nbTuple!=other.getNumberOfTuples())
5529     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5530   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5531   ret->alloc(nbTuple,1);
5532   ret->fillWithValue(-1);
5533   const int *pt=getConstPointer();
5534   std::map<int,int> mm;
5535   for(int i=0;i<nbTuple;i++)
5536     mm[pt[i]]=i;
5537   pt=other.getConstPointer();
5538   int *retToFill=ret->getPointer();
5539   for(int i=0;i<nbTuple;i++)
5540     {
5541       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5542       if(it==mm.end())
5543         {
5544           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5545           throw INTERP_KERNEL::Exception(oss.str().c_str());
5546         }
5547       retToFill[i]=(*it).second;
5548     }
5549   return ret.retn();
5550 }
5551
5552 /*!
5553  * Elements of \a partOfThis are expected to be included in \a this.
5554  * The returned array \a ret is so that this[ret]==partOfThis
5555  *
5556  * 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]
5557  * the return array will contain [3,2,5,7].
5558  *
5559  * \a this is expected to be a 1 compo allocated array.
5560  * \param [in] partOfThis - A 1 compo allocated array
5561  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5562  * \throw if two same element is present twice in \a this
5563  * \throw if an element in \a partOfThis is \b NOT in \a this.
5564  */
5565 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5566 {
5567   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5568     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5569   checkAllocated(); partOfThis.checkAllocated();
5570   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5571   const int *thisPt(begin()),*pt(partOfThis.begin());
5572   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5573   ret->alloc(nbTuples,1);
5574   int *retPt(ret->getPointer());
5575   std::map<int,int> m;
5576   for(int i=0;i<thisNbTuples;i++,thisPt++)
5577     m[*thisPt]=i;
5578   if(m.size()!=thisNbTuples)
5579     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5580   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5581     {
5582       std::map<int,int>::const_iterator it(m.find(*pt));
5583       if(it!=m.end())
5584         *retPt=(*it).second;
5585       else
5586         {
5587           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5588           throw INTERP_KERNEL::Exception(oss.str());
5589         }
5590     }
5591   return ret.retn();
5592 }
5593
5594 void DataArrayInt::aggregate(const DataArrayInt *other)
5595 {
5596   if(!other)
5597     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5598   if(getNumberOfComponents()!=other->getNumberOfComponents())
5599     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5600   _mem.insertAtTheEnd(other->begin(),other->end());
5601 }
5602
5603 /*!
5604  * Returns a new DataArrayInt holding the same values as \a this array but differently
5605  * arranged in memory. If \a this array holds 2 components of 3 values:
5606  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5607  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5608  *  \warning Do not confuse this method with transpose()!
5609  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5610  *          is to delete using decrRef() as it is no more needed.
5611  *  \throw If \a this is not allocated.
5612  */
5613 DataArrayInt *DataArrayInt::fromNoInterlace() const
5614 {
5615   checkAllocated();
5616   if(_mem.isNull())
5617     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5618   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5619   DataArrayInt *ret=DataArrayInt::New();
5620   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5621   return ret;
5622 }
5623
5624 /*!
5625  * Returns a new DataArrayInt holding the same values as \a this array but differently
5626  * arranged in memory. If \a this array holds 2 components of 3 values:
5627  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5628  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5629  *  \warning Do not confuse this method with transpose()!
5630  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5631  *          is to delete using decrRef() as it is no more needed.
5632  *  \throw If \a this is not allocated.
5633  */
5634 DataArrayInt *DataArrayInt::toNoInterlace() const
5635 {
5636   checkAllocated();
5637   if(_mem.isNull())
5638     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5639   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5640   DataArrayInt *ret=DataArrayInt::New();
5641   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5642   return ret;
5643 }
5644
5645 /*!
5646  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5647  * This map, if applied to \a this array, would make it sorted. For example, if
5648  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5649  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5650  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5651  * This method is useful for renumbering (in MED file for example). For more info
5652  * on renumbering see \ref numbering.
5653  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5654  *          array using decrRef() as it is no more needed.
5655  *  \throw If \a this is not allocated.
5656  *  \throw If \a this->getNumberOfComponents() != 1.
5657  *  \throw If there are equal values in \a this array.
5658  */
5659 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5660 {
5661   checkAllocated();
5662   if(getNumberOfComponents()!=1)
5663     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5664   int nbTuples=getNumberOfTuples();
5665   const int *pt=getConstPointer();
5666   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5667   DataArrayInt *ret=DataArrayInt::New();
5668   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5669   return ret;
5670 }
5671
5672 /*!
5673  * 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
5674  * input array \a ids2.
5675  * \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.
5676  * 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
5677  * inversely.
5678  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5679  *
5680  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5681  *          array using decrRef() as it is no more needed.
5682  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5683  * 
5684  */
5685 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5686 {
5687   if(!ids1 || !ids2)
5688     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5689   if(!ids1->isAllocated() || !ids2->isAllocated())
5690     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5691   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5692     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5693   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5694     {
5695       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 !";
5696       throw INTERP_KERNEL::Exception(oss.str().c_str());
5697     }
5698   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5699   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5700   p1->sort(true); p2->sort(true);
5701   if(!p1->isEqualWithoutConsideringStr(*p2))
5702     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5703   p1=ids1->checkAndPreparePermutation();
5704   p2=ids2->checkAndPreparePermutation();
5705   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5706   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5707   return p2.retn();
5708 }
5709
5710 /*!
5711  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5712  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5713  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5714  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5715  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5716  * The first of out arrays returns indices of elements of \a this array, grouped by their
5717  * place in the set \a B. The second out array is the index of the first one; it shows how
5718  * many elements of \a A are mapped into each element of \a B. <br>
5719  * For more info on
5720  * mapping and its usage in renumbering see \ref numbering. <br>
5721  * \b Example:
5722  * - \a this: [0,3,2,3,2,2,1,2]
5723  * - \a targetNb: 4
5724  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5725  * - \a arrI: [0,1,2,6,8]
5726  *
5727  * This result means: <br>
5728  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5729  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5730  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5731  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5732  * \a arrI[ 2+1 ]]); <br> etc.
5733  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5734  *         than the maximal value of \a A.
5735  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5736  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5737  *         this array using decrRef() as it is no more needed.
5738  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5739  *         elements of \a this. The caller is to delete this array using decrRef() as it
5740  *         is no more needed.
5741  *  \throw If \a this is not allocated.
5742  *  \throw If \a this->getNumberOfComponents() != 1.
5743  *  \throw If any value in \a this is more or equal to \a targetNb.
5744  */
5745 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5746 {
5747   checkAllocated();
5748   if(getNumberOfComponents()!=1)
5749     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5750   int nbOfTuples=getNumberOfTuples();
5751   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5752   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5753   retI->alloc(targetNb+1,1);
5754   const int *input=getConstPointer();
5755   std::vector< std::vector<int> > tmp(targetNb);
5756   for(int i=0;i<nbOfTuples;i++)
5757     {
5758       int tmp2=input[i];
5759       if(tmp2>=0 && tmp2<targetNb)
5760         tmp[tmp2].push_back(i);
5761       else
5762         {
5763           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5764           throw INTERP_KERNEL::Exception(oss.str().c_str());
5765         }
5766     }
5767   int *retIPtr=retI->getPointer();
5768   *retIPtr=0;
5769   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5770     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5771   if(nbOfTuples!=retI->getIJ(targetNb,0))
5772     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5773   ret->alloc(nbOfTuples,1);
5774   int *retPtr=ret->getPointer();
5775   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5776     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5777   arr=ret.retn();
5778   arrI=retI.retn();
5779 }
5780
5781
5782 /*!
5783  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5784  * from a zip representation of a surjective format (returned e.g. by
5785  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5786  * for example). The result array minimizes the permutation. <br>
5787  * For more info on renumbering see \ref numbering. <br>
5788  * \b Example: <br>
5789  * - \a nbOfOldTuples: 10 
5790  * - \a arr          : [0,3, 5,7,9]
5791  * - \a arrIBg       : [0,2,5]
5792  * - \a newNbOfTuples: 7
5793  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5794  *
5795  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5796  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5797  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5798  *         (indices of) equal values. Its every element (except the last one) points to
5799  *         the first element of a group of equal values.
5800  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5801  *          arrIBg is \a arrIEnd[ -1 ].
5802  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5803  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5804  *          array using decrRef() as it is no more needed.
5805  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5806  */
5807 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5808 {
5809   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5810   ret->alloc(nbOfOldTuples,1);
5811   int *pt=ret->getPointer();
5812   std::fill(pt,pt+nbOfOldTuples,-1);
5813   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5814   const int *cIPtr=arrIBg;
5815   for(int i=0;i<nbOfGrps;i++)
5816     pt[arr[cIPtr[i]]]=-(i+2);
5817   int newNb=0;
5818   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5819     {
5820       if(pt[iNode]<0)
5821         {
5822           if(pt[iNode]==-1)
5823             pt[iNode]=newNb++;
5824           else
5825             {
5826               int grpId=-(pt[iNode]+2);
5827               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5828                 {
5829                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5830                     pt[arr[j]]=newNb;
5831                   else
5832                     {
5833                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5834                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5835                     }
5836                 }
5837               newNb++;
5838             }
5839         }
5840     }
5841   newNbOfTuples=newNb;
5842   return ret.retn();
5843 }
5844
5845 /*!
5846  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5847  * which if applied to \a this array would make it sorted ascendingly.
5848  * For more info on renumbering see \ref numbering. <br>
5849  * \b Example: <br>
5850  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5851  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5852  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5853  *
5854  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5855  *          array using decrRef() as it is no more needed.
5856  *  \throw If \a this is not allocated.
5857  *  \throw If \a this->getNumberOfComponents() != 1.
5858  */
5859 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5860 {
5861   checkAllocated();
5862   if(getNumberOfComponents()!=1)
5863     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5864   int nbOfTuples=getNumberOfTuples();
5865   const int *pt=getConstPointer();
5866   std::map<int,int> m;
5867   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5868   ret->alloc(nbOfTuples,1);
5869   int *opt=ret->getPointer();
5870   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5871     {
5872       int val=*pt;
5873       std::map<int,int>::iterator it=m.find(val);
5874       if(it!=m.end())
5875         {
5876           *opt=(*it).second;
5877           (*it).second++;
5878         }
5879       else
5880         {
5881           *opt=0;
5882           m.insert(std::pair<int,int>(val,1));
5883         }
5884     }
5885   int sum=0;
5886   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5887     {
5888       int vt=(*it).second;
5889       (*it).second=sum;
5890       sum+=vt;
5891     }
5892   pt=getConstPointer();
5893   opt=ret->getPointer();
5894   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5895     *opt+=m[*pt];
5896   //
5897   return ret.retn();
5898 }
5899
5900 /*!
5901  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5902  * iota(). This method is particularly useful for DataArrayInt instances that represent
5903  * a renumbering array, to check if there is a real need in renumbering.
5904  * This method checks than \a this can be considered as an identity mapping
5905  * of a set having \a sizeExpected elements into itself.
5906  *
5907  *  \param [in] sizeExpected - The number of elements expected.
5908  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5909  *  \throw If \a this is not allocated.
5910  *  \throw If \a this->getNumberOfComponents() != 1.
5911  */
5912 bool DataArrayInt::isIota(int sizeExpected) const
5913 {
5914   checkAllocated();
5915   if(getNumberOfComponents()!=1)
5916     return false;
5917   int nbOfTuples(getNumberOfTuples());
5918   if(nbOfTuples!=sizeExpected)
5919     return false;
5920   const int *pt=getConstPointer();
5921   for(int i=0;i<nbOfTuples;i++,pt++)
5922     if(*pt!=i)
5923       return false;
5924   return true;
5925 }
5926
5927 /*!
5928  * Checks if all values in \a this array are equal to \a val.
5929  *  \param [in] val - value to check equality of array values to.
5930  *  \return bool - \a true if all values are \a val.
5931  *  \throw If \a this is not allocated.
5932  *  \throw If \a this->getNumberOfComponents() != 1
5933  */
5934 bool DataArrayInt::isUniform(int val) const
5935 {
5936   checkAllocated();
5937   if(getNumberOfComponents()!=1)
5938     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5939   int nbOfTuples=getNumberOfTuples();
5940   const int *w=getConstPointer();
5941   const int *end2=w+nbOfTuples;
5942   for(;w!=end2;w++)
5943     if(*w!=val)
5944       return false;
5945   return true;
5946 }
5947
5948 /*!
5949  * Checks if all values in \a this array are unique.
5950  *  \return bool - \a true if condition above is true
5951  *  \throw If \a this is not allocated.
5952  *  \throw If \a this->getNumberOfComponents() != 1
5953  */
5954 bool DataArrayInt::hasUniqueValues() const
5955 {
5956   checkAllocated();
5957   if(getNumberOfComponents()!=1)
5958     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5959   int nbOfTuples(getNumberOfTuples());
5960   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
5961   if (s.size() != nbOfTuples)
5962     return false;
5963   return true;
5964 }
5965
5966 /*!
5967  * Appends components of another array to components of \a this one, tuple by tuple.
5968  * So that the number of tuples of \a this array remains the same and the number of 
5969  * components increases.
5970  *  \param [in] other - the DataArrayInt to append to \a this one.
5971  *  \throw If \a this is not allocated.
5972  *  \throw If \a this and \a other arrays have different number of tuples.
5973  *
5974  *  \if ENABLE_EXAMPLES
5975  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
5976  *
5977  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
5978  *  \endif
5979  */
5980 void DataArrayInt::meldWith(const DataArrayInt *other)
5981 {
5982   if(!other)
5983     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
5984   checkAllocated();
5985   other->checkAllocated();
5986   int nbOfTuples=getNumberOfTuples();
5987   if(nbOfTuples!=other->getNumberOfTuples())
5988     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
5989   int nbOfComp1=getNumberOfComponents();
5990   int nbOfComp2=other->getNumberOfComponents();
5991   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
5992   int *w=newArr;
5993   const int *inp1=getConstPointer();
5994   const int *inp2=other->getConstPointer();
5995   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
5996     {
5997       w=std::copy(inp1,inp1+nbOfComp1,w);
5998       w=std::copy(inp2,inp2+nbOfComp2,w);
5999     }
6000   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6001   std::vector<int> compIds(nbOfComp2);
6002   for(int i=0;i<nbOfComp2;i++)
6003     compIds[i]=nbOfComp1+i;
6004   copyPartOfStringInfoFrom2(compIds,*other);
6005 }
6006
6007 /*!
6008  * Copy all components in a specified order from another DataArrayInt.
6009  * The specified components become the first ones in \a this array.
6010  * Both numerical and textual data is copied. The number of tuples in \a this and
6011  * the other array can be different.
6012  *  \param [in] a - the array to copy data from.
6013  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6014  *              to be copied.
6015  *  \throw If \a a is NULL.
6016  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6017  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6018  *
6019  *  \if ENABLE_EXAMPLES
6020  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6021  *  \endif
6022  */
6023 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6024 {
6025   if(!a)
6026     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6027   checkAllocated();
6028   a->checkAllocated();
6029   copyPartOfStringInfoFrom2(compoIds,*a);
6030   std::size_t partOfCompoSz=compoIds.size();
6031   int nbOfCompo=getNumberOfComponents();
6032   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6033   const int *ac=a->getConstPointer();
6034   int *nc=getPointer();
6035   for(int i=0;i<nbOfTuples;i++)
6036     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6037       nc[nbOfCompo*i+compoIds[j]]=*ac;
6038 }
6039
6040 /*!
6041  * Assign pointer to one array to a pointer to another appay. Reference counter of
6042  * \a arrayToSet is incremented / decremented.
6043  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6044  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6045  */
6046 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6047 {
6048   if(newArray!=arrayToSet)
6049     {
6050       if(arrayToSet)
6051         arrayToSet->decrRef();
6052       arrayToSet=newArray;
6053       if(arrayToSet)
6054         arrayToSet->incrRef();
6055     }
6056 }
6057
6058 DataArrayIntIterator *DataArrayInt::iterator()
6059 {
6060   return new DataArrayIntIterator(this);
6061 }
6062
6063 /*!
6064  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6065  * given one. The ids are sorted in the ascending order.
6066  *  \param [in] val - the value to find within \a this.
6067  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6068  *          array using decrRef() as it is no more needed.
6069  *  \throw If \a this is not allocated.
6070  *  \throw If \a this->getNumberOfComponents() != 1.
6071  *  \sa DataArrayInt::findIdsEqualTuple
6072  */
6073 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6074 {
6075   checkAllocated();
6076   if(getNumberOfComponents()!=1)
6077     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6078   const int *cptr(getConstPointer());
6079   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6080   int nbOfTuples=getNumberOfTuples();
6081   for(int i=0;i<nbOfTuples;i++,cptr++)
6082     if(*cptr==val)
6083       ret->pushBackSilent(i);
6084   return ret.retn();
6085 }
6086
6087 /*!
6088  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6089  * equal to a given one. 
6090  *  \param [in] val - the value to ignore within \a this.
6091  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6092  *          array using decrRef() as it is no more needed.
6093  *  \throw If \a this is not allocated.
6094  *  \throw If \a this->getNumberOfComponents() != 1.
6095  */
6096 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6097 {
6098   checkAllocated();
6099   if(getNumberOfComponents()!=1)
6100     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6101   const int *cptr(getConstPointer());
6102   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6103   int nbOfTuples=getNumberOfTuples();
6104   for(int i=0;i<nbOfTuples;i++,cptr++)
6105     if(*cptr!=val)
6106       ret->pushBackSilent(i);
6107   return ret.retn();
6108 }
6109
6110 /*!
6111  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6112  * This method is an extension of  DataArrayInt::findIdsEqual method.
6113  *
6114  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6115  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6116  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6117  *          array using decrRef() as it is no more needed.
6118  *  \throw If \a this is not allocated.
6119  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6120  * \throw If \a this->getNumberOfComponents() is equal to 0.
6121  * \sa DataArrayInt::findIdsEqual
6122  */
6123 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6124 {
6125   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6126   checkAllocated();
6127   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6128     {
6129       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6130       throw INTERP_KERNEL::Exception(oss.str().c_str());
6131     }
6132   if(nbOfCompoExp==0)
6133     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6134   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6135   const int *bg(begin()),*end2(end()),*work(begin());
6136   while(work!=end2)
6137     {
6138       work=std::search(work,end2,tupleBg,tupleEnd);
6139       if(work!=end2)
6140         {
6141           std::size_t pos(std::distance(bg,work));
6142           if(pos%nbOfCompoExp==0)
6143             ret->pushBackSilent(pos/nbOfCompoExp);
6144           work++;
6145         }
6146     }
6147   return ret.retn();
6148 }
6149
6150 /*!
6151  * Assigns \a newValue to all elements holding \a oldValue within \a this
6152  * one-dimensional array.
6153  *  \param [in] oldValue - the value to replace.
6154  *  \param [in] newValue - the value to assign.
6155  *  \return int - number of replacements performed.
6156  *  \throw If \a this is not allocated.
6157  *  \throw If \a this->getNumberOfComponents() != 1.
6158  */
6159 int DataArrayInt::changeValue(int oldValue, int newValue)
6160 {
6161   checkAllocated();
6162   if(getNumberOfComponents()!=1)
6163     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6164   if(oldValue==newValue)
6165     return 0;
6166   int *start(getPointer()),*end2(start+getNbOfElems());
6167   int ret(0);
6168   for(int *val=start;val!=end2;val++)
6169     {
6170       if(*val==oldValue)
6171         {
6172           *val=newValue;
6173           ret++;
6174         }
6175     }
6176   if(ret>0)
6177     declareAsNew();
6178   return ret;
6179 }
6180
6181 /*!
6182  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6183  * one of given values.
6184  *  \param [in] valsBg - an array of values to find within \a this array.
6185  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6186  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6187  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6188  *          array using decrRef() as it is no more needed.
6189  *  \throw If \a this->getNumberOfComponents() != 1.
6190  */
6191 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6192 {
6193   if(getNumberOfComponents()!=1)
6194     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6195   std::set<int> vals2(valsBg,valsEnd);
6196   const int *cptr(getConstPointer());
6197   std::vector<int> res;
6198   int nbOfTuples(getNumberOfTuples());
6199   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6200   for(int i=0;i<nbOfTuples;i++,cptr++)
6201     if(vals2.find(*cptr)!=vals2.end())
6202       ret->pushBackSilent(i);
6203   return ret.retn();
6204 }
6205
6206 /*!
6207  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6208  * equal to any of given values.
6209  *  \param [in] valsBg - an array of values to ignore within \a this array.
6210  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6211  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6212  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6213  *          array using decrRef() as it is no more needed.
6214  *  \throw If \a this->getNumberOfComponents() != 1.
6215  */
6216 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6217 {
6218   if(getNumberOfComponents()!=1)
6219     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6220   std::set<int> vals2(valsBg,valsEnd);
6221   const int *cptr=getConstPointer();
6222   std::vector<int> res;
6223   int nbOfTuples=getNumberOfTuples();
6224   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6225   for(int i=0;i<nbOfTuples;i++,cptr++)
6226     if(vals2.find(*cptr)==vals2.end())
6227       ret->pushBackSilent(i);
6228   return ret.retn();
6229 }
6230
6231 /*!
6232  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6233  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6234  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6235  * If any the tuple id is returned. If not -1 is returned.
6236  * 
6237  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6238  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6239  *
6240  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6241  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6242  */
6243 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6244 {
6245   checkAllocated();
6246   int nbOfCompo=getNumberOfComponents();
6247   if(nbOfCompo==0)
6248     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6249   if(nbOfCompo!=(int)tupl.size())
6250     {
6251       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6252       throw INTERP_KERNEL::Exception(oss.str().c_str());
6253     }
6254   const int *cptr=getConstPointer();
6255   std::size_t nbOfVals=getNbOfElems();
6256   for(const int *work=cptr;work!=cptr+nbOfVals;)
6257     {
6258       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6259       if(work!=cptr+nbOfVals)
6260         {
6261           if(std::distance(cptr,work)%nbOfCompo!=0)
6262             work++;
6263           else
6264             return std::distance(cptr,work)/nbOfCompo;
6265         }
6266     }
6267   return -1;
6268 }
6269
6270 /*!
6271  * This method searches the sequence specified in input parameter \b vals in \b this.
6272  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6273  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6274  * \sa DataArrayInt::findIdFirstEqualTuple
6275  */
6276 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6277 {
6278   checkAllocated();
6279   int nbOfCompo=getNumberOfComponents();
6280   if(nbOfCompo!=1)
6281     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6282   const int *cptr=getConstPointer();
6283   std::size_t nbOfVals=getNbOfElems();
6284   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6285   if(loc!=cptr+nbOfVals)
6286     return std::distance(cptr,loc);
6287   return -1;
6288 }
6289
6290 /*!
6291  * This method expects to be called when number of components of this is equal to one.
6292  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6293  * If not any tuple contains \b value -1 is returned.
6294  * \sa DataArrayInt::presenceOfValue
6295  */
6296 int DataArrayInt::findIdFirstEqual(int value) const
6297 {
6298   checkAllocated();
6299   if(getNumberOfComponents()!=1)
6300     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6301   const int *cptr=getConstPointer();
6302   int nbOfTuples=getNumberOfTuples();
6303   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6304   if(ret!=cptr+nbOfTuples)
6305     return std::distance(cptr,ret);
6306   return -1;
6307 }
6308
6309 /*!
6310  * This method expects to be called when number of components of this is equal to one.
6311  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6312  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6313  * \sa DataArrayInt::presenceOfValue
6314  */
6315 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6316 {
6317   checkAllocated();
6318   if(getNumberOfComponents()!=1)
6319     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6320   std::set<int> vals2(vals.begin(),vals.end());
6321   const int *cptr=getConstPointer();
6322   int nbOfTuples=getNumberOfTuples();
6323   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6324     if(vals2.find(*w)!=vals2.end())
6325       return std::distance(cptr,w);
6326   return -1;
6327 }
6328
6329 /*!
6330  * This method returns the number of values in \a this that are equals to input parameter \a value.
6331  * This method only works for single component array.
6332  *
6333  * \return a value in [ 0, \c this->getNumberOfTuples() )
6334  *
6335  * \throw If \a this is not allocated
6336  *
6337  */
6338 int DataArrayInt::count(int value) const
6339 {
6340   int ret=0;
6341   checkAllocated();
6342   if(getNumberOfComponents()!=1)
6343     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6344   const int *vals=begin();
6345   int nbOfTuples=getNumberOfTuples();
6346   for(int i=0;i<nbOfTuples;i++,vals++)
6347     if(*vals==value)
6348       ret++;
6349   return ret;
6350 }
6351
6352 /*!
6353  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6354  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6355  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6356  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6357  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6358  * \sa DataArrayInt::findIdFirstEqualTuple
6359  */
6360 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6361 {
6362   return findIdFirstEqualTuple(tupl)!=-1;
6363 }
6364
6365
6366 /*!
6367  * Returns \a true if a given value is present within \a this one-dimensional array.
6368  *  \param [in] value - the value to find within \a this array.
6369  *  \return bool - \a true in case if \a value is present within \a this array.
6370  *  \throw If \a this is not allocated.
6371  *  \throw If \a this->getNumberOfComponents() != 1.
6372  *  \sa findIdFirstEqual()
6373  */
6374 bool DataArrayInt::presenceOfValue(int value) const
6375 {
6376   return findIdFirstEqual(value)!=-1;
6377 }
6378
6379 /*!
6380  * This method expects to be called when number of components of this is equal to one.
6381  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6382  * If not any tuple contains one of the values contained in 'vals' false is returned.
6383  * \sa DataArrayInt::findIdFirstEqual
6384  */
6385 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6386 {
6387   return findIdFirstEqual(vals)!=-1;
6388 }
6389
6390 /*!
6391  * Accumulates values of each component of \a this array.
6392  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6393  *         by the caller, that is filled by this method with sum value for each
6394  *         component.
6395  *  \throw If \a this is not allocated.
6396  */
6397 void DataArrayInt::accumulate(int *res) const
6398 {
6399   checkAllocated();
6400   const int *ptr=getConstPointer();
6401   int nbTuple=getNumberOfTuples();
6402   int nbComps=getNumberOfComponents();
6403   std::fill(res,res+nbComps,0);
6404   for(int i=0;i<nbTuple;i++)
6405     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6406 }
6407
6408 int DataArrayInt::accumulate(int compId) const
6409 {
6410   checkAllocated();
6411   const int *ptr=getConstPointer();
6412   int nbTuple=getNumberOfTuples();
6413   int nbComps=getNumberOfComponents();
6414   if(compId<0 || compId>=nbComps)
6415     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6416   int ret=0;
6417   for(int i=0;i<nbTuple;i++)
6418     ret+=ptr[i*nbComps+compId];
6419   return ret;
6420 }
6421
6422 /*!
6423  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6424  * The returned array will have same number of components than \a this and number of tuples equal to
6425  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6426  *
6427  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6428  *
6429  * \param [in] bgOfIndex - begin (included) of the input index array.
6430  * \param [in] endOfIndex - end (excluded) of the input index array.
6431  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6432  * 
6433  * \throw If bgOfIndex or end is NULL.
6434  * \throw If input index array is not ascendingly sorted.
6435  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6436  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6437  */
6438 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6439 {
6440   if(!bgOfIndex || !endOfIndex)
6441     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6442   checkAllocated();
6443   int nbCompo=getNumberOfComponents();
6444   int nbOfTuples=getNumberOfTuples();
6445   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6446   if(sz<1)
6447     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6448   sz--;
6449   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6450   const int *w=bgOfIndex;
6451   if(*w<0 || *w>=nbOfTuples)
6452     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6453   const int *srcPt=begin()+(*w)*nbCompo;
6454   int *tmp=ret->getPointer();
6455   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6456     {
6457       std::fill(tmp,tmp+nbCompo,0);
6458       if(w[1]>=w[0])
6459         {
6460           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6461             {
6462               if(j>=0 && j<nbOfTuples)
6463                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6464               else
6465                 {
6466                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6467                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6468                 }
6469             }
6470         }
6471       else
6472         {
6473           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6474           throw INTERP_KERNEL::Exception(oss.str().c_str());
6475         }
6476     }
6477   ret->copyStringInfoFrom(*this);
6478   return ret.retn();
6479 }
6480
6481 /*!
6482  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6483  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6484  * offsetA2</em> and (2)
6485  * the number of component in the result array is same as that of each of given arrays.
6486  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6487  * Info on components is copied from the first of the given arrays. Number of components
6488  * in the given arrays must be the same.
6489  *  \param [in] a1 - an array to include in the result array.
6490  *  \param [in] a2 - another array to include in the result array.
6491  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6492  *  \return DataArrayInt * - the new instance of DataArrayInt.
6493  *          The caller is to delete this result array using decrRef() as it is no more
6494  *          needed.
6495  *  \throw If either \a a1 or \a a2 is NULL.
6496  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6497  */
6498 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6499 {
6500   if(!a1 || !a2)
6501     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6502   int nbOfComp=a1->getNumberOfComponents();
6503   if(nbOfComp!=a2->getNumberOfComponents())
6504     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6505   int nbOfTuple1=a1->getNumberOfTuples();
6506   int nbOfTuple2=a2->getNumberOfTuples();
6507   DataArrayInt *ret=DataArrayInt::New();
6508   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6509   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6510   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6511   ret->copyStringInfoFrom(*a1);
6512   return ret;
6513 }
6514
6515 /*!
6516  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6517  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6518  * the number of component in the result array is same as that of each of given arrays.
6519  * Info on components is copied from the first of the given arrays. Number of components
6520  * in the given arrays must be  the same.
6521  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6522  * not the object itself.
6523  *  \param [in] arr - a sequence of arrays to include in the result array.
6524  *  \return DataArrayInt * - the new instance of DataArrayInt.
6525  *          The caller is to delete this result array using decrRef() as it is no more
6526  *          needed.
6527  *  \throw If all arrays within \a arr are NULL.
6528  *  \throw If getNumberOfComponents() of arrays within \a arr.
6529  */
6530 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6531 {
6532   std::vector<const DataArrayInt *> a;
6533   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6534     if(*it4)
6535       a.push_back(*it4);
6536   if(a.empty())
6537     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6538   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6539   int nbOfComp=(*it)->getNumberOfComponents();
6540   int nbt=(*it++)->getNumberOfTuples();
6541   for(int i=1;it!=a.end();it++,i++)
6542     {
6543       if((*it)->getNumberOfComponents()!=nbOfComp)
6544         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6545       nbt+=(*it)->getNumberOfTuples();
6546     }
6547   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6548   ret->alloc(nbt,nbOfComp);
6549   int *pt=ret->getPointer();
6550   for(it=a.begin();it!=a.end();it++)
6551     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6552   ret->copyStringInfoFrom(*(a[0]));
6553   return ret.retn();
6554 }
6555
6556 /*!
6557  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6558  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6559  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6560  * 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.
6561  * 
6562  * \return DataArrayInt * - a new object to be managed by the caller.
6563  */
6564 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6565 {
6566   int retSz=1;
6567   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6568     {
6569       if(*it4)
6570         {
6571           (*it4)->checkAllocated();
6572           if((*it4)->getNumberOfComponents()!=1)
6573             {
6574               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6575               throw INTERP_KERNEL::Exception(oss.str().c_str());
6576             }
6577           int nbTupl=(*it4)->getNumberOfTuples();
6578           if(nbTupl<1)
6579             {
6580               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6581               throw INTERP_KERNEL::Exception(oss.str().c_str());
6582             }
6583           if((*it4)->front()!=0)
6584             {
6585               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6586               throw INTERP_KERNEL::Exception(oss.str().c_str());
6587             }
6588           retSz+=nbTupl-1;
6589         }
6590       else
6591         {
6592           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6593           throw INTERP_KERNEL::Exception(oss.str().c_str());
6594         }
6595     }
6596   if(arrs.empty())
6597     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6598   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6599   ret->alloc(retSz,1);
6600   int *pt=ret->getPointer(); *pt++=0;
6601   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6602     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6603   ret->copyStringInfoFrom(*(arrs[0]));
6604   return ret.retn();
6605 }
6606
6607 /*!
6608  * Returns in a single walk in \a this the min value and the max value in \a this.
6609  * \a this is expected to be single component array.
6610  *
6611  * \param [out] minValue - the min value in \a this.
6612  * \param [out] maxValue - the max value in \a this.
6613  *
6614  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6615  */
6616 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6617 {
6618   checkAllocated();
6619   if(getNumberOfComponents()!=1)
6620     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6621   int nbTuples(getNumberOfTuples());
6622   const int *pt(begin());
6623   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6624   for(int i=0;i<nbTuples;i++,pt++)
6625     {
6626       if(*pt<minValue)
6627         minValue=*pt;
6628       if(*pt>maxValue)
6629         maxValue=*pt;
6630     }
6631 }
6632
6633 /*!
6634  * Converts every value of \a this array to its absolute value.
6635  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6636  * should be called instead.
6637  *
6638  * \throw If \a this is not allocated.
6639  * \sa DataArrayInt::computeAbs
6640  */
6641 void DataArrayInt::abs()
6642 {
6643   checkAllocated();
6644   int *ptr(getPointer());
6645   std::size_t nbOfElems(getNbOfElems());
6646   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6647   declareAsNew();
6648 }
6649
6650 /*!
6651  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6652  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6653  *
6654  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6655  *         same number of tuples and component as \a this array.
6656  *         The caller is to delete this result array using decrRef() as it is no more
6657  *         needed.
6658  * \throw If \a this is not allocated.
6659  * \sa DataArrayInt::abs
6660  */
6661 DataArrayInt *DataArrayInt::computeAbs() const
6662 {
6663   checkAllocated();
6664   DataArrayInt *newArr(DataArrayInt::New());
6665   int nbOfTuples(getNumberOfTuples());
6666   int nbOfComp(getNumberOfComponents());
6667   newArr->alloc(nbOfTuples,nbOfComp);
6668   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6669   newArr->copyStringInfoFrom(*this);
6670   return newArr;
6671 }
6672
6673 /*!
6674  * Apply a liner function to a given component of \a this array, so that
6675  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6676  *  \param [in] a - the first coefficient of the function.
6677  *  \param [in] b - the second coefficient of the function.
6678  *  \param [in] compoId - the index of component to modify.
6679  *  \throw If \a this is not allocated.
6680  */
6681 void DataArrayInt::applyLin(int a, int b, int compoId)
6682 {
6683   checkAllocated();
6684   int *ptr=getPointer()+compoId;
6685   int nbOfComp=getNumberOfComponents();
6686   int nbOfTuple=getNumberOfTuples();
6687   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6688     *ptr=a*(*ptr)+b;
6689   declareAsNew();
6690 }
6691
6692 /*!
6693  * Apply a liner function to all elements of \a this array, so that
6694  * an element _x_ becomes \f$ a * x + b \f$.
6695  *  \param [in] a - the first coefficient of the function.
6696  *  \param [in] b - the second coefficient of the function.
6697  *  \throw If \a this is not allocated.
6698  */
6699 void DataArrayInt::applyLin(int a, int b)
6700 {
6701   checkAllocated();
6702   int *ptr=getPointer();
6703   std::size_t nbOfElems=getNbOfElems();
6704   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6705     *ptr=a*(*ptr)+b;
6706   declareAsNew();
6707 }
6708
6709 /*!
6710  * Returns a full copy of \a this array except that sign of all elements is reversed.
6711  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6712  *          same number of tuples and component as \a this array.
6713  *          The caller is to delete this result array using decrRef() as it is no more
6714  *          needed.
6715  *  \throw If \a this is not allocated.
6716  */
6717 DataArrayInt *DataArrayInt::negate() const
6718 {
6719   checkAllocated();
6720   DataArrayInt *newArr=DataArrayInt::New();
6721   int nbOfTuples=getNumberOfTuples();
6722   int nbOfComp=getNumberOfComponents();
6723   newArr->alloc(nbOfTuples,nbOfComp);
6724   const int *cptr=getConstPointer();
6725   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6726   newArr->copyStringInfoFrom(*this);
6727   return newArr;
6728 }
6729
6730 /*!
6731  * Modify all elements of \a this array, so that
6732  * an element _x_ becomes \f$ numerator / x \f$.
6733  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6734  *           array, all elements processed before detection of the zero element remain
6735  *           modified.
6736  *  \param [in] numerator - the numerator used to modify array elements.
6737  *  \throw If \a this is not allocated.
6738  *  \throw If there is an element equal to 0 in \a this array.
6739  */
6740 void DataArrayInt::applyInv(int numerator)
6741 {
6742   checkAllocated();
6743   int *ptr=getPointer();
6744   std::size_t nbOfElems=getNbOfElems();
6745   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6746     {
6747       if(*ptr!=0)
6748         {
6749           *ptr=numerator/(*ptr);
6750         }
6751       else
6752         {
6753           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6754           oss << " !";
6755           throw INTERP_KERNEL::Exception(oss.str().c_str());
6756         }
6757     }
6758   declareAsNew();
6759 }
6760
6761 /*!
6762  * Modify all elements of \a this array, so that
6763  * an element _x_ becomes \f$ x / val \f$.
6764  *  \param [in] val - the denominator used to modify array elements.
6765  *  \throw If \a this is not allocated.
6766  *  \throw If \a val == 0.
6767  */
6768 void DataArrayInt::applyDivideBy(int val)
6769 {
6770   if(val==0)
6771     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6772   checkAllocated();
6773   int *ptr=getPointer();
6774   std::size_t nbOfElems=getNbOfElems();
6775   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6776   declareAsNew();
6777 }
6778
6779 /*!
6780  * Modify all elements of \a this array, so that
6781  * an element _x_ becomes  <em> x % val </em>.
6782  *  \param [in] val - the divisor used to modify array elements.
6783  *  \throw If \a this is not allocated.
6784  *  \throw If \a val <= 0.
6785  */
6786 void DataArrayInt::applyModulus(int val)
6787 {
6788   if(val<=0)
6789     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6790   checkAllocated();
6791   int *ptr=getPointer();
6792   std::size_t nbOfElems=getNbOfElems();
6793   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6794   declareAsNew();
6795 }
6796
6797 struct GreatEqual
6798 {
6799   GreatEqual(int v):_v(v) { }
6800   bool operator()(int v) const { return v>=_v; }
6801   int _v;
6802 };
6803
6804 struct GreaterThan
6805 {
6806   GreaterThan(int v):_v(v) { }
6807   bool operator()(int v) const { return v>_v; }
6808   int _v;
6809 };
6810
6811 struct LowerEqual
6812 {
6813   LowerEqual(int v):_v(v) { }
6814   bool operator()(int v) const { return v<=_v; }
6815   int _v;
6816 };
6817
6818 struct LowerThan
6819 {
6820   LowerThan(int v):_v(v) { }
6821   bool operator()(int v) const { return v<_v; }
6822   int _v;
6823 };
6824
6825 struct InRange
6826 {
6827   InRange(int a, int b):_a(a),_b(b) { }
6828   bool operator()(int v) const { return v>=_a && v<_b; }
6829   int _a,_b;
6830 };
6831
6832 /*!
6833  * This method works only on data array with one component.
6834  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6835  * this[*id] in [\b vmin,\b vmax)
6836  * 
6837  * \param [in] vmin begin of range. This value is included in range (included).
6838  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6839  * \return a newly allocated data array that the caller should deal with.
6840  *
6841  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6842  */
6843 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6844 {
6845   InRange ir(vmin,vmax);
6846   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6847   return ret.retn();
6848 }
6849
6850 struct NotInRange
6851 {
6852   NotInRange(int a, int b):_a(a),_b(b) { }
6853   bool operator()(int v) const { return v<_a || v>=_b; }
6854   int _a,_b;
6855 };
6856
6857 /*!
6858  * This method works only on data array with one component.
6859  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6860  * this[*id] \b not in [\b vmin,\b vmax)
6861  * 
6862  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6863  * \param [in] vmax end of range. This value is included in range (included).
6864  * \return a newly allocated data array that the caller should deal with.
6865  * 
6866  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6867  */
6868 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6869 {
6870   NotInRange nir(vmin,vmax);
6871   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
6872   return ret.retn();
6873 }
6874
6875 /*!
6876  * 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.
6877  *
6878  * \return a newly allocated data array that the caller should deal with.
6879  * \sa DataArrayInt::findIdsInRange
6880  */
6881 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6882 {
6883   LowerThan lt(0);
6884   MCAuto<DataArrayInt> ret(findIdsAdv(lt));
6885   return ret.retn();
6886 }
6887
6888 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
6889 {
6890   GreatEqual ge(val);
6891   return findIdsAdv(ge);
6892 }
6893
6894 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
6895 {
6896   GreaterThan gt(val);
6897   return findIdsAdv(gt);
6898 }
6899
6900 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
6901 {
6902   LowerEqual le(val);
6903   return findIdsAdv(le);
6904 }
6905
6906 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
6907 {
6908   LowerThan lt(val);
6909   return findIdsAdv(lt);
6910 }
6911
6912 /*!
6913  * This method works only on data array with one component.
6914  * 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.
6915  * 
6916  * \param [in] vmin begin of range. This value is included in range (included).
6917  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6918  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6919 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6920 {
6921   checkAllocated();
6922   if(getNumberOfComponents()!=1)
6923     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6924   int nbOfTuples=getNumberOfTuples();
6925   bool ret=true;
6926   const int *cptr=getConstPointer();
6927   for(int i=0;i<nbOfTuples;i++,cptr++)
6928     {
6929       if(*cptr>=vmin && *cptr<vmax)
6930         { ret=ret && *cptr==i; }
6931       else
6932         {
6933           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6934           throw INTERP_KERNEL::Exception(oss.str().c_str());
6935         }
6936     }
6937   return ret;
6938 }
6939
6940 /*!
6941  * Modify all elements of \a this array, so that
6942  * an element _x_ becomes <em> val % x </em>.
6943  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6944  *           array, all elements processed before detection of the zero element remain
6945  *           modified.
6946  *  \param [in] val - the divident used to modify array elements.
6947  *  \throw If \a this is not allocated.
6948  *  \throw If there is an element equal to or less than 0 in \a this array.
6949  */
6950 void DataArrayInt::applyRModulus(int val)
6951 {
6952   checkAllocated();
6953   int *ptr=getPointer();
6954   std::size_t nbOfElems=getNbOfElems();
6955   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6956     {
6957       if(*ptr>0)
6958         {
6959           *ptr=val%(*ptr);
6960         }
6961       else
6962         {
6963           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6964           oss << " !";
6965           throw INTERP_KERNEL::Exception(oss.str().c_str());
6966         }
6967     }
6968   declareAsNew();
6969 }
6970
6971 /*!
6972  * Modify all elements of \a this array, so that
6973  * an element _x_ becomes <em> val ^ x </em>.
6974  *  \param [in] val - the value used to apply pow on all array elements.
6975  *  \throw If \a this is not allocated.
6976  *  \throw If \a val < 0.
6977  */
6978 void DataArrayInt::applyPow(int val)
6979 {
6980   checkAllocated();
6981   if(val<0)
6982     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
6983   int *ptr=getPointer();
6984   std::size_t nbOfElems=getNbOfElems();
6985   if(val==0)
6986     {
6987       std::fill(ptr,ptr+nbOfElems,1);
6988       return ;
6989     }
6990   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6991     {
6992       int tmp=1;
6993       for(int j=0;j<val;j++)
6994         tmp*=*ptr;
6995       *ptr=tmp;
6996     }
6997   declareAsNew();
6998 }
6999
7000 /*!
7001  * Modify all elements of \a this array, so that
7002  * an element _x_ becomes \f$ val ^ x \f$.
7003  *  \param [in] val - the value used to apply pow on all array elements.
7004  *  \throw If \a this is not allocated.
7005  *  \throw If there is an element < 0 in \a this array.
7006  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7007  *           array, all elements processed before detection of the zero element remain
7008  *           modified.
7009  */
7010 void DataArrayInt::applyRPow(int val)
7011 {
7012   checkAllocated();
7013   int *ptr=getPointer();
7014   std::size_t nbOfElems=getNbOfElems();
7015   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7016     {
7017       if(*ptr>=0)
7018         {
7019           int tmp=1;
7020           for(int j=0;j<*ptr;j++)
7021             tmp*=val;
7022           *ptr=tmp;
7023         }
7024       else
7025         {
7026           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7027           oss << " !";
7028           throw INTERP_KERNEL::Exception(oss.str().c_str());
7029         }
7030     }
7031   declareAsNew();
7032 }
7033
7034 /*!
7035  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7036  * of components in the result array is a sum of the number of components of given arrays
7037  * and (2) the number of tuples in the result array is same as that of each of given
7038  * arrays. In other words the i-th tuple of result array includes all components of
7039  * i-th tuples of all given arrays.
7040  * Number of tuples in the given arrays must be the same.
7041  *  \param [in] a1 - an array to include in the result array.
7042  *  \param [in] a2 - another array to include in the result array.
7043  *  \return DataArrayInt * - the new instance of DataArrayInt.
7044  *          The caller is to delete this result array using decrRef() as it is no more
7045  *          needed.
7046  *  \throw If both \a a1 and \a a2 are NULL.
7047  *  \throw If any given array is not allocated.
7048  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7049  */
7050 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7051 {
7052   std::vector<const DataArrayInt *> arr(2);
7053   arr[0]=a1; arr[1]=a2;
7054   return Meld(arr);
7055 }
7056
7057 /*!
7058  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7059  * of components in the result array is a sum of the number of components of given arrays
7060  * and (2) the number of tuples in the result array is same as that of each of given
7061  * arrays. In other words the i-th tuple of result array includes all components of
7062  * i-th tuples of all given arrays.
7063  * Number of tuples in the given arrays must be  the same.
7064  *  \param [in] arr - a sequence of arrays to include in the result array.
7065  *  \return DataArrayInt * - the new instance of DataArrayInt.
7066  *          The caller is to delete this result array using decrRef() as it is no more
7067  *          needed.
7068  *  \throw If all arrays within \a arr are NULL.
7069  *  \throw If any given array is not allocated.
7070  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7071  */
7072 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7073 {
7074   std::vector<const DataArrayInt *> a;
7075   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7076     if(*it4)
7077       a.push_back(*it4);
7078   if(a.empty())
7079     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7080   std::vector<const DataArrayInt *>::const_iterator it;
7081   for(it=a.begin();it!=a.end();it++)
7082     (*it)->checkAllocated();
7083   it=a.begin();
7084   int nbOfTuples=(*it)->getNumberOfTuples();
7085   std::vector<int> nbc(a.size());
7086   std::vector<const int *> pts(a.size());
7087   nbc[0]=(*it)->getNumberOfComponents();
7088   pts[0]=(*it++)->getConstPointer();
7089   for(int i=1;it!=a.end();it++,i++)
7090     {
7091       if(nbOfTuples!=(*it)->getNumberOfTuples())
7092         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7093       nbc[i]=(*it)->getNumberOfComponents();
7094       pts[i]=(*it)->getConstPointer();
7095     }
7096   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7097   DataArrayInt *ret=DataArrayInt::New();
7098   ret->alloc(nbOfTuples,totalNbOfComp);
7099   int *retPtr=ret->getPointer();
7100   for(int i=0;i<nbOfTuples;i++)
7101     for(int j=0;j<(int)a.size();j++)
7102       {
7103         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7104         pts[j]+=nbc[j];
7105       }
7106   int k=0;
7107   for(int i=0;i<(int)a.size();i++)
7108     for(int j=0;j<nbc[i];j++,k++)
7109       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7110   return ret;
7111 }
7112
7113 /*!
7114  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7115  * The i-th item of the result array is an ID of a set of elements belonging to a
7116  * unique set of groups, which the i-th element is a part of. This set of elements
7117  * belonging to a unique set of groups is called \a family, so the result array contains
7118  * IDs of families each element belongs to.
7119  *
7120  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7121  * then there are 3 families:
7122  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7123  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7124  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7125  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7126  * stands for the element #3 which is in none of groups.
7127  *
7128  *  \param [in] groups - sequence of groups of element IDs.
7129  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7130  *         in \a groups.
7131  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7132  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7133  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7134  *         delete this array using decrRef() as it is no more needed.
7135  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7136  */
7137 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7138 {
7139   std::vector<const DataArrayInt *> groups2;
7140   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7141     if(*it4)
7142       groups2.push_back(*it4);
7143   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7144   ret->alloc(newNb,1);
7145   int *retPtr=ret->getPointer();
7146   std::fill(retPtr,retPtr+newNb,0);
7147   int fid=1;
7148   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7149     {
7150       const int *ptr=(*iter)->getConstPointer();
7151       std::size_t nbOfElem=(*iter)->getNbOfElems();
7152       int sfid=fid;
7153       for(int j=0;j<sfid;j++)
7154         {
7155           bool found=false;
7156           for(std::size_t i=0;i<nbOfElem;i++)
7157             {
7158               if(ptr[i]>=0 && ptr[i]<newNb)
7159                 {
7160                   if(retPtr[ptr[i]]==j)
7161                     {
7162                       retPtr[ptr[i]]=fid;
7163                       found=true;
7164                     }
7165                 }
7166               else
7167                 {
7168                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7169                   oss << ") !";
7170                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7171                 }
7172             }
7173           if(found)
7174             fid++;
7175         }
7176     }
7177   fidsOfGroups.clear();
7178   fidsOfGroups.resize(groups2.size());
7179   int grId=0;
7180   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7181     {
7182       std::set<int> tmp;
7183       const int *ptr=(*iter)->getConstPointer();
7184       std::size_t nbOfElem=(*iter)->getNbOfElems();
7185       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7186         tmp.insert(retPtr[*p]);
7187       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7188     }
7189   return ret.retn();
7190 }
7191
7192 /*!
7193  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7194  * arrays. The result array does not contain any duplicates and its values
7195  * are sorted in ascending order.
7196  *  \param [in] arr - sequence of DataArrayInt's to unite.
7197  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7198  *         array using decrRef() as it is no more needed.
7199  *  \throw If any \a arr[i] is not allocated.
7200  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7201  */
7202 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7203 {
7204   std::vector<const DataArrayInt *> a;
7205   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7206     if(*it4)
7207       a.push_back(*it4);
7208   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7209     {
7210       (*it)->checkAllocated();
7211       if((*it)->getNumberOfComponents()!=1)
7212         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7213     }
7214   //
7215   std::set<int> r;
7216   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7217     {
7218       const int *pt=(*it)->getConstPointer();
7219       int nbOfTuples=(*it)->getNumberOfTuples();
7220       r.insert(pt,pt+nbOfTuples);
7221     }
7222   DataArrayInt *ret=DataArrayInt::New();
7223   ret->alloc((int)r.size(),1);
7224   std::copy(r.begin(),r.end(),ret->getPointer());
7225   return ret;
7226 }
7227
7228 /*!
7229  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7230  * arrays. The result array does not contain any duplicates and its values
7231  * are sorted in ascending order.
7232  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7233  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7234  *         array using decrRef() as it is no more needed.
7235  *  \throw If any \a arr[i] is not allocated.
7236  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7237  */
7238 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7239 {
7240   std::vector<const DataArrayInt *> a;
7241   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7242     if(*it4)
7243       a.push_back(*it4);
7244   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7245     {
7246       (*it)->checkAllocated();
7247       if((*it)->getNumberOfComponents()!=1)
7248         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7249     }
7250   //
7251   std::set<int> r;
7252   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7253     {
7254       const int *pt=(*it)->getConstPointer();
7255       int nbOfTuples=(*it)->getNumberOfTuples();
7256       std::set<int> s1(pt,pt+nbOfTuples);
7257       if(it!=a.begin())
7258         {
7259           std::set<int> r2;
7260           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7261           r=r2;
7262         }
7263       else
7264         r=s1;
7265     }
7266   DataArrayInt *ret(DataArrayInt::New());
7267   ret->alloc((int)r.size(),1);
7268   std::copy(r.begin(),r.end(),ret->getPointer());
7269   return ret;
7270 }
7271
7272 /// @cond INTERNAL
7273 namespace MEDCouplingImpl
7274 {
7275   class OpSwitchedOn
7276   {
7277   public:
7278     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7279     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7280   private:
7281     int *_pt;
7282     int _cnt;
7283   };
7284
7285   class OpSwitchedOff
7286   {
7287   public:
7288     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7289     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7290   private:
7291     int *_pt;
7292     int _cnt;
7293   };
7294 }
7295 /// @endcond
7296
7297 /*!
7298  * This method returns the list of ids in ascending mode so that v[id]==true.
7299  */
7300 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7301 {
7302   int sz((int)std::count(v.begin(),v.end(),true));
7303   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7304   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7305   return ret.retn();
7306 }
7307
7308 /*!
7309  * This method returns the list of ids in ascending mode so that v[id]==false.
7310  */
7311 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7312 {
7313   int sz((int)std::count(v.begin(),v.end(),false));
7314   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7315   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7316   return ret.retn();
7317 }
7318
7319 /*!
7320  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7321  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7322  *
7323  * \param [in] v the input data structure to be translate into skyline format.
7324  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7325  * \param [out] dataIndex the second element of the skyline format.
7326  */
7327 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7328 {
7329   int sz((int)v.size());
7330   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7331   ret1->alloc(sz+1,1);
7332   int *pt(ret1->getPointer()); *pt=0;
7333   for(int i=0;i<sz;i++,pt++)
7334     pt[1]=pt[0]+(int)v[i].size();
7335   ret0->alloc(ret1->back(),1);
7336   pt=ret0->getPointer();
7337   for(int i=0;i<sz;i++)
7338     pt=std::copy(v[i].begin(),v[i].end(),pt);
7339   data=ret0.retn(); dataIndex=ret1.retn();
7340 }
7341
7342 /*!
7343  * Returns a new DataArrayInt which contains a complement of elements of \a this
7344  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7345  * \a nbOfElement) not present in \a this array.
7346  *  \param [in] nbOfElement - maximal size of the result array.
7347  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7348  *         array using decrRef() as it is no more needed.
7349  *  \throw If \a this is not allocated.
7350  *  \throw If \a this->getNumberOfComponents() != 1.
7351  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7352  *         nbOfElement ).
7353  */
7354 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7355 {
7356   checkAllocated();
7357   if(getNumberOfComponents()!=1)
7358     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7359   std::vector<bool> tmp(nbOfElement);
7360   const int *pt=getConstPointer();
7361   int nbOfTuples=getNumberOfTuples();
7362   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7363     if(*w>=0 && *w<nbOfElement)
7364       tmp[*w]=true;
7365     else
7366       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7367   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7368   DataArrayInt *ret=DataArrayInt::New();
7369   ret->alloc(nbOfRetVal,1);
7370   int j=0;
7371   int *retPtr=ret->getPointer();
7372   for(int i=0;i<nbOfElement;i++)
7373     if(!tmp[i])
7374       retPtr[j++]=i;
7375   return ret;
7376 }
7377
7378 /*!
7379  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7380  * from an \a other one-dimensional array.
7381  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7382  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7383  *         caller is to delete this array using decrRef() as it is no more needed.
7384  *  \throw If \a other is NULL.
7385  *  \throw If \a other is not allocated.
7386  *  \throw If \a other->getNumberOfComponents() != 1.
7387  *  \throw If \a this is not allocated.
7388  *  \throw If \a this->getNumberOfComponents() != 1.
7389  *  \sa DataArrayInt::buildSubstractionOptimized()
7390  */
7391 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7392 {
7393   if(!other)
7394     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7395   checkAllocated();
7396   other->checkAllocated();
7397   if(getNumberOfComponents()!=1)
7398     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7399   if(other->getNumberOfComponents()!=1)
7400     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7401   const int *pt=getConstPointer();
7402   int nbOfTuples=getNumberOfTuples();
7403   std::set<int> s1(pt,pt+nbOfTuples);
7404   pt=other->getConstPointer();
7405   nbOfTuples=other->getNumberOfTuples();
7406   std::set<int> s2(pt,pt+nbOfTuples);
7407   std::vector<int> r;
7408   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7409   DataArrayInt *ret=DataArrayInt::New();
7410   ret->alloc((int)r.size(),1);
7411   std::copy(r.begin(),r.end(),ret->getPointer());
7412   return ret;
7413 }
7414
7415 /*!
7416  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7417  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7418  * 
7419  * \param [in] other an array with one component and expected to be sorted ascendingly.
7420  * \ret list of ids in \a this but not in \a other.
7421  * \sa DataArrayInt::buildSubstraction
7422  */
7423 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7424 {
7425   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7426   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7427   checkAllocated(); other->checkAllocated();
7428   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7429   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7430   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7431   const int *work1(pt1Bg),*work2(pt2Bg);
7432   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7433   for(;work1!=pt1End;work1++)
7434     {
7435       if(work2!=pt2End && *work1==*work2)
7436         work2++;
7437       else
7438         ret->pushBackSilent(*work1);
7439     }
7440   return ret.retn();
7441 }
7442
7443
7444 /*!
7445  * Returns a new DataArrayInt which contains all elements of \a this and a given
7446  * one-dimensional arrays. The result array does not contain any duplicates
7447  * and its values are sorted in ascending order.
7448  *  \param [in] other - an array to unite with \a this one.
7449  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7450  *         array using decrRef() as it is no more needed.
7451  *  \throw If \a this or \a other is not allocated.
7452  *  \throw If \a this->getNumberOfComponents() != 1.
7453  *  \throw If \a other->getNumberOfComponents() != 1.
7454  */
7455 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7456 {
7457   std::vector<const DataArrayInt *>arrs(2);
7458   arrs[0]=this; arrs[1]=other;
7459   return BuildUnion(arrs);
7460 }
7461
7462
7463 /*!
7464  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7465  * one-dimensional arrays. The result array does not contain any duplicates
7466  * and its values are sorted in ascending order.
7467  *  \param [in] other - an array to intersect with \a this one.
7468  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7469  *         array using decrRef() as it is no more needed.
7470  *  \throw If \a this or \a other is not allocated.
7471  *  \throw If \a this->getNumberOfComponents() != 1.
7472  *  \throw If \a other->getNumberOfComponents() != 1.
7473  */
7474 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7475 {
7476   std::vector<const DataArrayInt *>arrs(2);
7477   arrs[0]=this; arrs[1]=other;
7478   return BuildIntersection(arrs);
7479 }
7480
7481 /*!
7482  * This method can be applied on allocated with one component DataArrayInt instance.
7483  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7484  * 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]
7485  * 
7486  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7487  * \throw if \a this is not allocated or if \a this has not exactly one component.
7488  * \sa DataArrayInt::buildUniqueNotSorted
7489  */
7490 DataArrayInt *DataArrayInt::buildUnique() const
7491 {
7492   checkAllocated();
7493   if(getNumberOfComponents()!=1)
7494     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7495   int nbOfTuples=getNumberOfTuples();
7496   MCAuto<DataArrayInt> tmp=deepCopy();
7497   int *data=tmp->getPointer();
7498   int *last=std::unique(data,data+nbOfTuples);
7499   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7500   ret->alloc(std::distance(data,last),1);
7501   std::copy(data,last,ret->getPointer());
7502   return ret.retn();
7503 }
7504
7505 /*!
7506  * This method can be applied on allocated with one component DataArrayInt instance.
7507  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7508  *
7509  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7510  *
7511  * \throw if \a this is not allocated or if \a this has not exactly one component.
7512  *
7513  * \sa DataArrayInt::buildUnique
7514  */
7515 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7516 {
7517   checkAllocated();
7518     if(getNumberOfComponents()!=1)
7519       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7520   int minVal,maxVal;
7521   getMinMaxValues(minVal,maxVal);
7522   std::vector<bool> b(maxVal-minVal+1,false);
7523   const int *ptBg(begin()),*endBg(end());
7524   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7525   for(const int *pt=ptBg;pt!=endBg;pt++)
7526     {
7527       if(!b[*pt-minVal])
7528         {
7529           ret->pushBackSilent(*pt);
7530           b[*pt-minVal]=true;
7531         }
7532     }
7533   ret->copyStringInfoFrom(*this);
7534   return ret.retn();
7535 }
7536
7537 /*!
7538  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7539  * "index" array. Such "index" array is returned for example by 
7540  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7541  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7542  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7543  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7544  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7545  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7546  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7547  *          The caller is to delete this array using decrRef() as it is no more needed. 
7548  *  \throw If \a this is not allocated.
7549  *  \throw If \a this->getNumberOfComponents() != 1.
7550  *  \throw If \a this->getNumberOfTuples() < 2.
7551  *
7552  *  \b Example: <br> 
7553  *         - this contains [1,3,6,7,7,9,15]
7554  *         - result array contains [2,3,1,0,2,6],
7555  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7556  *
7557  * \sa DataArrayInt::computeOffsetsFull
7558  */
7559 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7560 {
7561   checkAllocated();
7562   if(getNumberOfComponents()!=1)
7563     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7564   int nbOfTuples=getNumberOfTuples();
7565   if(nbOfTuples<2)
7566     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7567   const int *ptr=getConstPointer();
7568   DataArrayInt *ret=DataArrayInt::New();
7569   ret->alloc(nbOfTuples-1,1);
7570   int *out=ret->getPointer();
7571   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7572   return ret;
7573 }
7574
7575 /*!
7576  * Modifies \a this one-dimensional array so that value of each element \a x
7577  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7578  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7579  * and components remains the same.<br>
7580  * This method is useful for allToAllV in MPI with contiguous policy. This method
7581  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7582  * this one.
7583  *  \throw If \a this is not allocated.
7584  *  \throw If \a this->getNumberOfComponents() != 1.
7585  *
7586  *  \b Example: <br>
7587  *          - Before \a this contains [3,5,1,2,0,8]
7588  *          - After \a this contains  [0,3,8,9,11,11]<br>
7589  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7590  *          array is retained and thus there is no space to store the last element.
7591  */
7592 void DataArrayInt::computeOffsets()
7593 {
7594   checkAllocated();
7595   if(getNumberOfComponents()!=1)
7596     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7597   int nbOfTuples=getNumberOfTuples();
7598   if(nbOfTuples==0)
7599     return ;
7600   int *work=getPointer();
7601   int tmp=work[0];
7602   work[0]=0;
7603   for(int i=1;i<nbOfTuples;i++)
7604     {
7605       int tmp2=work[i];
7606       work[i]=work[i-1]+tmp;
7607       tmp=tmp2;
7608     }
7609   declareAsNew();
7610 }
7611
7612
7613 /*!
7614  * Modifies \a this one-dimensional array so that value of each element \a x
7615  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7616  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7617  * components remains the same and number of tuples is inceamented by one.<br>
7618  * This method is useful for allToAllV in MPI with contiguous policy. This method
7619  * differs from computeOffsets() in that the number of tuples is changed by this one.
7620  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7621  *  \throw If \a this is not allocated.
7622  *  \throw If \a this->getNumberOfComponents() != 1.
7623  *
7624  *  \b Example: <br>
7625  *          - Before \a this contains [3,5,1,2,0,8]
7626  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7627  * \sa DataArrayInt::deltaShiftIndex
7628  */
7629 void DataArrayInt::computeOffsetsFull()
7630 {
7631   checkAllocated();
7632   if(getNumberOfComponents()!=1)
7633     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7634   int nbOfTuples=getNumberOfTuples();
7635   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7636   const int *work=getConstPointer();
7637   ret[0]=0;
7638   for(int i=0;i<nbOfTuples;i++)
7639     ret[i+1]=work[i]+ret[i];
7640   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7641   declareAsNew();
7642 }
7643
7644 /*!
7645  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7646  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7647  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7648  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7649  * filling completely one of the ranges in \a this.
7650  *
7651  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7652  * \param [out] rangeIdsFetched the range ids fetched
7653  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7654  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7655  *
7656  * \sa DataArrayInt::computeOffsetsFull
7657  *
7658  *  \b Example: <br>
7659  *          - \a this : [0,3,7,9,15,18]
7660  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7661  *          - \a rangeIdsFetched result array: [0,2,4]
7662  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7663  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7664  * <br>
7665  */
7666 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7667 {
7668   if(!listOfIds)
7669     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7670   listOfIds->checkAllocated(); checkAllocated();
7671   if(listOfIds->getNumberOfComponents()!=1)
7672     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7673   if(getNumberOfComponents()!=1)
7674     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7675   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7676   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7677   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7678   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7679   while(tupPtr!=tupEnd && offPtr!=offEnd)
7680     {
7681       if(*tupPtr==*offPtr)
7682         {
7683           int i=offPtr[0];
7684           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7685           if(i==offPtr[1])
7686             {
7687               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7688               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7689               offPtr++;
7690             }
7691         }
7692       else
7693         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7694     }
7695   rangeIdsFetched=ret0.retn();
7696   idsInInputListThatFetch=ret1.retn();
7697 }
7698
7699 /*!
7700  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7701  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7702  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7703  * beginning within the "iota" array. And \a this is a one-dimensional array
7704  * considered as a selector of groups described by \a offsets to include into the result array.
7705  *  \throw If \a offsets is NULL.
7706  *  \throw If \a offsets is not allocated.
7707  *  \throw If \a offsets->getNumberOfComponents() != 1.
7708  *  \throw If \a offsets is not monotonically increasing.
7709  *  \throw If \a this is not allocated.
7710  *  \throw If \a this->getNumberOfComponents() != 1.
7711  *  \throw If any element of \a this is not a valid index for \a offsets array.
7712  *
7713  *  \b Example: <br>
7714  *          - \a this: [0,2,3]
7715  *          - \a offsets: [0,3,6,10,14,20]
7716  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7717  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7718  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7719  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7720  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7721  */
7722 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7723 {
7724   if(!offsets)
7725     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7726   checkAllocated();
7727   if(getNumberOfComponents()!=1)
7728     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7729   offsets->checkAllocated();
7730   if(offsets->getNumberOfComponents()!=1)
7731     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7732   int othNbTuples=offsets->getNumberOfTuples()-1;
7733   int nbOfTuples=getNumberOfTuples();
7734   int retNbOftuples=0;
7735   const int *work=getConstPointer();
7736   const int *offPtr=offsets->getConstPointer();
7737   for(int i=0;i<nbOfTuples;i++)
7738     {
7739       int val=work[i];
7740       if(val>=0 && val<othNbTuples)
7741         {
7742           int delta=offPtr[val+1]-offPtr[val];
7743           if(delta>=0)
7744             retNbOftuples+=delta;
7745           else
7746             {
7747               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7748               throw INTERP_KERNEL::Exception(oss.str().c_str());
7749             }
7750         }
7751       else
7752         {
7753           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7754           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7755           throw INTERP_KERNEL::Exception(oss.str().c_str());
7756         }
7757     }
7758   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7759   ret->alloc(retNbOftuples,1);
7760   int *retPtr=ret->getPointer();
7761   for(int i=0;i<nbOfTuples;i++)
7762     {
7763       int val=work[i];
7764       int start=offPtr[val];
7765       int off=offPtr[val+1]-start;
7766       for(int j=0;j<off;j++,retPtr++)
7767         *retPtr=start+j;
7768     }
7769   return ret.retn();
7770 }
7771
7772 /*!
7773  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7774  * scaled array (monotonically increasing).
7775 from that of \a this and \a
7776  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7777  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7778  * beginning within the "iota" array. And \a this is a one-dimensional array
7779  * considered as a selector of groups described by \a offsets to include into the result array.
7780  *  \throw If \a  is NULL.
7781  *  \throw If \a this is not allocated.
7782  *  \throw If \a this->getNumberOfComponents() != 1.
7783  *  \throw If \a this->getNumberOfTuples() == 0.
7784  *  \throw If \a this is not monotonically increasing.
7785  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7786  *
7787  *  \b Example: <br>
7788  *          - \a bg , \a stop and \a step : (0,5,2)
7789  *          - \a this: [0,3,6,10,14,20]
7790  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7791  */
7792 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7793 {
7794   if(!isAllocated())
7795     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7796   if(getNumberOfComponents()!=1)
7797     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7798   int nbOfTuples(getNumberOfTuples());
7799   if(nbOfTuples==0)
7800     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7801   const int *ids(begin());
7802   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7803   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7804     {
7805       if(pos>=0 && pos<nbOfTuples-1)
7806         {
7807           int delta(ids[pos+1]-ids[pos]);
7808           sz+=delta;
7809           if(delta<0)
7810             {
7811               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7812               throw INTERP_KERNEL::Exception(oss.str().c_str());
7813             }          
7814         }
7815       else
7816         {
7817           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7818           throw INTERP_KERNEL::Exception(oss.str().c_str());
7819         }
7820     }
7821   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7822   int *retPtr(ret->getPointer());
7823   pos=bg;
7824   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7825     {
7826       int delta(ids[pos+1]-ids[pos]);
7827       for(int j=0;j<delta;j++,retPtr++)
7828         *retPtr=pos;
7829     }
7830   return ret.retn();
7831 }
7832
7833 /*!
7834  * 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.
7835  * 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
7836  * in tuple **i** of returned DataArrayInt.
7837  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7838  *
7839  * 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)]
7840  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7841  * 
7842  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7843  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7844  * \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
7845  *        is thrown if no ranges in \a ranges contains value in \a this.
7846  * 
7847  * \sa DataArrayInt::findIdInRangeForEachTuple
7848  */
7849 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7850 {
7851   if(!ranges)
7852     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7853   if(ranges->getNumberOfComponents()!=2)
7854     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7855   checkAllocated();
7856   if(getNumberOfComponents()!=1)
7857     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7858   int nbTuples=getNumberOfTuples();
7859   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7860   int nbOfRanges=ranges->getNumberOfTuples();
7861   const int *rangesPtr=ranges->getConstPointer();
7862   int *retPtr=ret->getPointer();
7863   const int *inPtr=getConstPointer();
7864   for(int i=0;i<nbTuples;i++,retPtr++)
7865     {
7866       int val=inPtr[i];
7867       bool found=false;
7868       for(int j=0;j<nbOfRanges && !found;j++)
7869         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7870           { *retPtr=j; found=true; }
7871       if(found)
7872         continue;
7873       else
7874         {
7875           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7876           throw INTERP_KERNEL::Exception(oss.str().c_str());
7877         }
7878     }
7879   return ret.retn();
7880 }
7881
7882 /*!
7883  * 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.
7884  * 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
7885  * in tuple **i** of returned DataArrayInt.
7886  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7887  *
7888  * 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)]
7889  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7890  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7891  * 
7892  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7893  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7894  * \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
7895  *        is thrown if no ranges in \a ranges contains value in \a this.
7896  * \sa DataArrayInt::findRangeIdForEachTuple
7897  */
7898 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7899 {
7900   if(!ranges)
7901     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7902   if(ranges->getNumberOfComponents()!=2)
7903     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7904   checkAllocated();
7905   if(getNumberOfComponents()!=1)
7906     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7907   int nbTuples=getNumberOfTuples();
7908   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7909   int nbOfRanges=ranges->getNumberOfTuples();
7910   const int *rangesPtr=ranges->getConstPointer();
7911   int *retPtr=ret->getPointer();
7912   const int *inPtr=getConstPointer();
7913   for(int i=0;i<nbTuples;i++,retPtr++)
7914     {
7915       int val=inPtr[i];
7916       bool found=false;
7917       for(int j=0;j<nbOfRanges && !found;j++)
7918         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7919           { *retPtr=val-rangesPtr[2*j]; found=true; }
7920       if(found)
7921         continue;
7922       else
7923         {
7924           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7925           throw INTERP_KERNEL::Exception(oss.str().c_str());
7926         }
7927     }
7928   return ret.retn();
7929 }
7930
7931 /*!
7932  * \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).
7933  * 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).
7934  * 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 !
7935  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7936  * This method does nothing if number of tuples is lower of equal to 1.
7937  *
7938  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7939  *
7940  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
7941  */
7942 void DataArrayInt::sortEachPairToMakeALinkedList()
7943 {
7944   checkAllocated();
7945   if(getNumberOfComponents()!=2)
7946     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7947   int nbOfTuples(getNumberOfTuples());
7948   if(nbOfTuples<=1)
7949     return ;
7950   int *conn(getPointer());
7951   for(int i=1;i<nbOfTuples;i++,conn+=2)
7952     {
7953       if(i>1)
7954         {
7955           if(conn[2]==conn[3])
7956             {
7957               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7958               throw INTERP_KERNEL::Exception(oss.str().c_str());
7959             }
7960           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
7961             std::swap(conn[2],conn[3]);
7962           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
7963           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
7964             {
7965               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
7966               throw INTERP_KERNEL::Exception(oss.str().c_str());
7967             }
7968         }
7969       else
7970         {
7971           if(conn[0]==conn[1] || conn[2]==conn[3])
7972             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
7973           int tmp[4];
7974           std::set<int> s;
7975           s.insert(conn,conn+4);
7976           if(s.size()!=3)
7977             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
7978           if(std::count(conn,conn+4,conn[0])==2)
7979             {
7980               tmp[0]=conn[1];
7981               tmp[1]=conn[0];
7982               tmp[2]=conn[0];
7983               if(conn[2]==conn[0])
7984                 { tmp[3]=conn[3]; }
7985               else
7986                 { tmp[3]=conn[2];}
7987               std::copy(tmp,tmp+4,conn);
7988             }
7989           else
7990             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
7991               if(conn[1]==conn[3])
7992                 std::swap(conn[2],conn[3]);
7993             }
7994         }
7995     }
7996 }
7997
7998 /*!
7999  * \a this is expected to be a correctly linked list of pairs.
8000  * 
8001  * \sa DataArrayInt::sortEachPairToMakeALinkedList
8002  */
8003 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8004 {
8005   checkAllocated();
8006   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8007   int nbTuples(getNumberOfTuples());
8008   if(nbTuples<1)
8009     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8010   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8011   const int *thisPtr(begin());
8012   int *retPtr(ret->getPointer());
8013   retPtr[0]=thisPtr[0];
8014   for(int i=0;i<nbTuples;i++)
8015     {
8016       retPtr[i+1]=thisPtr[2*i+1];
8017       if(i<nbTuples-1)
8018         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8019           {
8020             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 ?";
8021             throw INTERP_KERNEL::Exception(oss.str());
8022           }
8023     }
8024   return ret;
8025 }
8026
8027 /*!
8028  * 
8029  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8030  *             \a nbTimes  should be at least equal to 1.
8031  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8032  * \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.
8033  */
8034 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8035 {
8036   checkAllocated();
8037   if(getNumberOfComponents()!=1)
8038     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8039   if(nbTimes<1)
8040     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8041   int nbTuples=getNumberOfTuples();
8042   const int *inPtr=getConstPointer();
8043   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8044   int *retPtr=ret->getPointer();
8045   for(int i=0;i<nbTuples;i++,inPtr++)
8046     {
8047       int val=*inPtr;
8048       for(int j=0;j<nbTimes;j++,retPtr++)
8049         *retPtr=val;
8050     }
8051   ret->copyStringInfoFrom(*this);
8052   return ret.retn();
8053 }
8054
8055 /*!
8056  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8057  * But the number of components can be different from one.
8058  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8059  */
8060 DataArrayInt *DataArrayInt::getDifferentValues() const
8061 {
8062   checkAllocated();
8063   std::set<int> ret;
8064   ret.insert(begin(),end());
8065   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8066   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8067   return ret2.retn();
8068 }
8069
8070 /*!
8071  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8072  * them it tells which tuple id have this id.
8073  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8074  * This method returns two arrays having same size.
8075  * 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.
8076  * 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]]
8077  */
8078 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8079 {
8080   checkAllocated();
8081   if(getNumberOfComponents()!=1)
8082     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8083   int id=0;
8084   std::map<int,int> m,m2,m3;
8085   for(const int *w=begin();w!=end();w++)
8086     m[*w]++;
8087   differentIds.resize(m.size());
8088   std::vector<DataArrayInt *> ret(m.size());
8089   std::vector<int *> retPtr(m.size());
8090   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8091     {
8092       m2[(*it).first]=id;
8093       ret[id]=DataArrayInt::New();
8094       ret[id]->alloc((*it).second,1);
8095       retPtr[id]=ret[id]->getPointer();
8096       differentIds[id]=(*it).first;
8097     }
8098   id=0;
8099   for(const int *w=begin();w!=end();w++,id++)
8100     {
8101       retPtr[m2[*w]][m3[*w]++]=id;
8102     }
8103   return ret;
8104 }
8105
8106 /*!
8107  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8108  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8109  *
8110  * \param [in] nbOfSlices - number of slices expected.
8111  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8112  * 
8113  * \sa DataArray::GetSlice
8114  * \throw If \a this is not allocated or not with exactly one component.
8115  * \throw If an element in \a this if < 0.
8116  */
8117 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8118 {
8119   if(!isAllocated() || getNumberOfComponents()!=1)
8120     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8121   if(nbOfSlices<=0)
8122     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8123   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8124   int sumPerSlc(sum/nbOfSlices),pos(0);
8125   const int *w(begin());
8126   std::vector< std::pair<int,int> > ret(nbOfSlices);
8127   for(int i=0;i<nbOfSlices;i++)
8128     {
8129       std::pair<int,int> p(pos,-1);
8130       int locSum(0);
8131       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8132       if(i!=nbOfSlices-1)
8133         p.second=pos;
8134       else
8135         p.second=nbOfTuples;
8136       ret[i]=p;
8137     }
8138   return ret;
8139 }
8140
8141 /*!
8142  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8143  * valid cases.
8144  * 1.  The arrays have same number of tuples and components. Then each value of
8145  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8146  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8147  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8148  *   component. Then
8149  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8150  * 3.  The arrays have same number of components and one array, say _a2_, has one
8151  *   tuple. Then
8152  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8153  *
8154  * Info on components is copied either from the first array (in the first case) or from
8155  * the array with maximal number of elements (getNbOfElems()).
8156  *  \param [in] a1 - an array to sum up.
8157  *  \param [in] a2 - another array to sum up.
8158  *  \return DataArrayInt * - the new instance of DataArrayInt.
8159  *          The caller is to delete this result array using decrRef() as it is no more
8160  *          needed.
8161  *  \throw If either \a a1 or \a a2 is NULL.
8162  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8163  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8164  *         none of them has number of tuples or components equal to 1.
8165  */
8166 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8167 {
8168   if(!a1 || !a2)
8169     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8170   int nbOfTuple=a1->getNumberOfTuples();
8171   int nbOfTuple2=a2->getNumberOfTuples();
8172   int nbOfComp=a1->getNumberOfComponents();
8173   int nbOfComp2=a2->getNumberOfComponents();
8174   MCAuto<DataArrayInt> ret=0;
8175   if(nbOfTuple==nbOfTuple2)
8176     {
8177       if(nbOfComp==nbOfComp2)
8178         {
8179           ret=DataArrayInt::New();
8180           ret->alloc(nbOfTuple,nbOfComp);
8181           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8182           ret->copyStringInfoFrom(*a1);
8183         }
8184       else
8185         {
8186           int nbOfCompMin,nbOfCompMax;
8187           const DataArrayInt *aMin, *aMax;
8188           if(nbOfComp>nbOfComp2)
8189             {
8190               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8191               aMin=a2; aMax=a1;
8192             }
8193           else
8194             {
8195               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8196               aMin=a1; aMax=a2;
8197             }
8198           if(nbOfCompMin==1)
8199             {
8200               ret=DataArrayInt::New();
8201               ret->alloc(nbOfTuple,nbOfCompMax);
8202               const int *aMinPtr=aMin->getConstPointer();
8203               const int *aMaxPtr=aMax->getConstPointer();
8204               int *res=ret->getPointer();
8205               for(int i=0;i<nbOfTuple;i++)
8206                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8207               ret->copyStringInfoFrom(*aMax);
8208             }
8209           else
8210             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8211         }
8212     }
8213   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8214     {
8215       if(nbOfComp==nbOfComp2)
8216         {
8217           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8218           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8219           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8220           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8221           ret=DataArrayInt::New();
8222           ret->alloc(nbOfTupleMax,nbOfComp);
8223           int *res=ret->getPointer();
8224           for(int i=0;i<nbOfTupleMax;i++)
8225             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8226           ret->copyStringInfoFrom(*aMax);
8227         }
8228       else
8229         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8230     }
8231   else
8232     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8233   return ret.retn();
8234 }
8235
8236 /*!
8237  * Adds values of another DataArrayInt to values of \a this one. There are 3
8238  * valid cases.
8239  * 1.  The arrays have same number of tuples and components. Then each value of
8240  *   \a other array is added to the corresponding value of \a this array, i.e.:
8241  *   _a_ [ i, j ] += _other_ [ i, j ].
8242  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8243  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8244  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8245  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8246  *
8247  *  \param [in] other - an array to add to \a this one.
8248  *  \throw If \a other is NULL.
8249  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8250  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8251  *         \a other has number of both tuples and components not equal to 1.
8252  */
8253 void DataArrayInt::addEqual(const DataArrayInt *other)
8254 {
8255   if(!other)
8256     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8257   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8258   checkAllocated(); other->checkAllocated();
8259   int nbOfTuple=getNumberOfTuples();
8260   int nbOfTuple2=other->getNumberOfTuples();
8261   int nbOfComp=getNumberOfComponents();
8262   int nbOfComp2=other->getNumberOfComponents();
8263   if(nbOfTuple==nbOfTuple2)
8264     {
8265       if(nbOfComp==nbOfComp2)
8266         {
8267           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8268         }
8269       else if(nbOfComp2==1)
8270         {
8271           int *ptr=getPointer();
8272           const int *ptrc=other->getConstPointer();
8273           for(int i=0;i<nbOfTuple;i++)
8274             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8275         }
8276       else
8277         throw INTERP_KERNEL::Exception(msg);
8278     }
8279   else if(nbOfTuple2==1)
8280     {
8281       if(nbOfComp2==nbOfComp)
8282         {
8283           int *ptr=getPointer();
8284           const int *ptrc=other->getConstPointer();
8285           for(int i=0;i<nbOfTuple;i++)
8286             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8287         }
8288       else
8289         throw INTERP_KERNEL::Exception(msg);
8290     }
8291   else
8292     throw INTERP_KERNEL::Exception(msg);
8293   declareAsNew();
8294 }
8295
8296 /*!
8297  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8298  * valid cases.
8299  * 1.  The arrays have same number of tuples and components. Then each value of
8300  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8301  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8302  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8303  *   component. Then
8304  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8305  * 3.  The arrays have same number of components and one array, say _a2_, has one
8306  *   tuple. Then
8307  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8308  *
8309  * Info on components is copied either from the first array (in the first case) or from
8310  * the array with maximal number of elements (getNbOfElems()).
8311  *  \param [in] a1 - an array to subtract from.
8312  *  \param [in] a2 - an array to subtract.
8313  *  \return DataArrayInt * - the new instance of DataArrayInt.
8314  *          The caller is to delete this result array using decrRef() as it is no more
8315  *          needed.
8316  *  \throw If either \a a1 or \a a2 is NULL.
8317  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8318  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8319  *         none of them has number of tuples or components equal to 1.
8320  */
8321 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8322 {
8323   if(!a1 || !a2)
8324     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8325   int nbOfTuple1=a1->getNumberOfTuples();
8326   int nbOfTuple2=a2->getNumberOfTuples();
8327   int nbOfComp1=a1->getNumberOfComponents();
8328   int nbOfComp2=a2->getNumberOfComponents();
8329   if(nbOfTuple2==nbOfTuple1)
8330     {
8331       if(nbOfComp1==nbOfComp2)
8332         {
8333           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8334           ret->alloc(nbOfTuple2,nbOfComp1);
8335           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8336           ret->copyStringInfoFrom(*a1);
8337           return ret.retn();
8338         }
8339       else if(nbOfComp2==1)
8340         {
8341           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8342           ret->alloc(nbOfTuple1,nbOfComp1);
8343           const int *a2Ptr=a2->getConstPointer();
8344           const int *a1Ptr=a1->getConstPointer();
8345           int *res=ret->getPointer();
8346           for(int i=0;i<nbOfTuple1;i++)
8347             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8348           ret->copyStringInfoFrom(*a1);
8349           return ret.retn();
8350         }
8351       else
8352         {
8353           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8354           return 0;
8355         }
8356     }
8357   else if(nbOfTuple2==1)
8358     {
8359       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8360       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8361       ret->alloc(nbOfTuple1,nbOfComp1);
8362       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8363       int *pt=ret->getPointer();
8364       for(int i=0;i<nbOfTuple1;i++)
8365         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8366       ret->copyStringInfoFrom(*a1);
8367       return ret.retn();
8368     }
8369   else
8370     {
8371       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8372       return 0;
8373     }
8374 }
8375
8376 /*!
8377  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8378  * valid cases.
8379  * 1.  The arrays have same number of tuples and components. Then each value of
8380  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8381  *   _a_ [ i, j ] -= _other_ [ i, j ].
8382  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8383  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8384  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8385  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8386  *
8387  *  \param [in] other - an array to subtract from \a this one.
8388  *  \throw If \a other is NULL.
8389  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8390  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8391  *         \a other has number of both tuples and components not equal to 1.
8392  */
8393 void DataArrayInt::substractEqual(const DataArrayInt *other)
8394 {
8395   if(!other)
8396     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8397   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8398   checkAllocated(); other->checkAllocated();
8399   int nbOfTuple=getNumberOfTuples();
8400   int nbOfTuple2=other->getNumberOfTuples();
8401   int nbOfComp=getNumberOfComponents();
8402   int nbOfComp2=other->getNumberOfComponents();
8403   if(nbOfTuple==nbOfTuple2)
8404     {
8405       if(nbOfComp==nbOfComp2)
8406         {
8407           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8408         }
8409       else if(nbOfComp2==1)
8410         {
8411           int *ptr=getPointer();
8412           const int *ptrc=other->getConstPointer();
8413           for(int i=0;i<nbOfTuple;i++)
8414             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8415         }
8416       else
8417         throw INTERP_KERNEL::Exception(msg);
8418     }
8419   else if(nbOfTuple2==1)
8420     {
8421       int *ptr=getPointer();
8422       const int *ptrc=other->getConstPointer();
8423       for(int i=0;i<nbOfTuple;i++)
8424         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8425     }
8426   else
8427     throw INTERP_KERNEL::Exception(msg);
8428   declareAsNew();
8429 }
8430
8431 /*!
8432  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8433  * valid cases.
8434  * 1.  The arrays have same number of tuples and components. Then each value of
8435  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8436  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8437  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8438  *   component. Then
8439  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8440  * 3.  The arrays have same number of components and one array, say _a2_, has one
8441  *   tuple. Then
8442  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8443  *
8444  * Info on components is copied either from the first array (in the first case) or from
8445  * the array with maximal number of elements (getNbOfElems()).
8446  *  \param [in] a1 - a factor array.
8447  *  \param [in] a2 - another factor array.
8448  *  \return DataArrayInt * - the new instance of DataArrayInt.
8449  *          The caller is to delete this result array using decrRef() as it is no more
8450  *          needed.
8451  *  \throw If either \a a1 or \a a2 is NULL.
8452  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8453  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8454  *         none of them has number of tuples or components equal to 1.
8455  */
8456 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8457 {
8458   if(!a1 || !a2)
8459     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8460   int nbOfTuple=a1->getNumberOfTuples();
8461   int nbOfTuple2=a2->getNumberOfTuples();
8462   int nbOfComp=a1->getNumberOfComponents();
8463   int nbOfComp2=a2->getNumberOfComponents();
8464   MCAuto<DataArrayInt> ret=0;
8465   if(nbOfTuple==nbOfTuple2)
8466     {
8467       if(nbOfComp==nbOfComp2)
8468         {
8469           ret=DataArrayInt::New();
8470           ret->alloc(nbOfTuple,nbOfComp);
8471           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8472           ret->copyStringInfoFrom(*a1);
8473         }
8474       else
8475         {
8476           int nbOfCompMin,nbOfCompMax;
8477           const DataArrayInt *aMin, *aMax;
8478           if(nbOfComp>nbOfComp2)
8479             {
8480               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8481               aMin=a2; aMax=a1;
8482             }
8483           else
8484             {
8485               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8486               aMin=a1; aMax=a2;
8487             }
8488           if(nbOfCompMin==1)
8489             {
8490               ret=DataArrayInt::New();
8491               ret->alloc(nbOfTuple,nbOfCompMax);
8492               const int *aMinPtr=aMin->getConstPointer();
8493               const int *aMaxPtr=aMax->getConstPointer();
8494               int *res=ret->getPointer();
8495               for(int i=0;i<nbOfTuple;i++)
8496                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8497               ret->copyStringInfoFrom(*aMax);
8498             }
8499           else
8500             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8501         }
8502     }
8503   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8504     {
8505       if(nbOfComp==nbOfComp2)
8506         {
8507           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8508           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8509           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8510           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8511           ret=DataArrayInt::New();
8512           ret->alloc(nbOfTupleMax,nbOfComp);
8513           int *res=ret->getPointer();
8514           for(int i=0;i<nbOfTupleMax;i++)
8515             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8516           ret->copyStringInfoFrom(*aMax);
8517         }
8518       else
8519         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8520     }
8521   else
8522     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8523   return ret.retn();
8524 }
8525
8526
8527 /*!
8528  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8529  * valid cases.
8530  * 1.  The arrays have same number of tuples and components. Then each value of
8531  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8532  *   _a_ [ i, j ] *= _other_ [ i, j ].
8533  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8534  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8535  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8536  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8537  *
8538  *  \param [in] other - an array to multiply to \a this one.
8539  *  \throw If \a other is NULL.
8540  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8541  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8542  *         \a other has number of both tuples and components not equal to 1.
8543  */
8544 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8545 {
8546   if(!other)
8547     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8548   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8549   checkAllocated(); other->checkAllocated();
8550   int nbOfTuple=getNumberOfTuples();
8551   int nbOfTuple2=other->getNumberOfTuples();
8552   int nbOfComp=getNumberOfComponents();
8553   int nbOfComp2=other->getNumberOfComponents();
8554   if(nbOfTuple==nbOfTuple2)
8555     {
8556       if(nbOfComp==nbOfComp2)
8557         {
8558           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8559         }
8560       else if(nbOfComp2==1)
8561         {
8562           int *ptr=getPointer();
8563           const int *ptrc=other->getConstPointer();
8564           for(int i=0;i<nbOfTuple;i++)
8565             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8566         }
8567       else
8568         throw INTERP_KERNEL::Exception(msg);
8569     }
8570   else if(nbOfTuple2==1)
8571     {
8572       if(nbOfComp2==nbOfComp)
8573         {
8574           int *ptr=getPointer();
8575           const int *ptrc=other->getConstPointer();
8576           for(int i=0;i<nbOfTuple;i++)
8577             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8578         }
8579       else
8580         throw INTERP_KERNEL::Exception(msg);
8581     }
8582   else
8583     throw INTERP_KERNEL::Exception(msg);
8584   declareAsNew();
8585 }
8586
8587
8588 /*!
8589  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8590  * valid cases.
8591  * 1.  The arrays have same number of tuples and components. Then each value of
8592  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8593  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8594  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8595  *   component. Then
8596  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8597  * 3.  The arrays have same number of components and one array, say _a2_, has one
8598  *   tuple. Then
8599  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8600  *
8601  * Info on components is copied either from the first array (in the first case) or from
8602  * the array with maximal number of elements (getNbOfElems()).
8603  *  \warning No check of division by zero is performed!
8604  *  \param [in] a1 - a numerator array.
8605  *  \param [in] a2 - a denominator array.
8606  *  \return DataArrayInt * - the new instance of DataArrayInt.
8607  *          The caller is to delete this result array using decrRef() as it is no more
8608  *          needed.
8609  *  \throw If either \a a1 or \a a2 is NULL.
8610  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8611  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8612  *         none of them has number of tuples or components equal to 1.
8613  */
8614 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8615 {
8616   if(!a1 || !a2)
8617     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8618   int nbOfTuple1=a1->getNumberOfTuples();
8619   int nbOfTuple2=a2->getNumberOfTuples();
8620   int nbOfComp1=a1->getNumberOfComponents();
8621   int nbOfComp2=a2->getNumberOfComponents();
8622   if(nbOfTuple2==nbOfTuple1)
8623     {
8624       if(nbOfComp1==nbOfComp2)
8625         {
8626           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8627           ret->alloc(nbOfTuple2,nbOfComp1);
8628           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8629           ret->copyStringInfoFrom(*a1);
8630           return ret.retn();
8631         }
8632       else if(nbOfComp2==1)
8633         {
8634           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8635           ret->alloc(nbOfTuple1,nbOfComp1);
8636           const int *a2Ptr=a2->getConstPointer();
8637           const int *a1Ptr=a1->getConstPointer();
8638           int *res=ret->getPointer();
8639           for(int i=0;i<nbOfTuple1;i++)
8640             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8641           ret->copyStringInfoFrom(*a1);
8642           return ret.retn();
8643         }
8644       else
8645         {
8646           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8647           return 0;
8648         }
8649     }
8650   else if(nbOfTuple2==1)
8651     {
8652       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8653       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8654       ret->alloc(nbOfTuple1,nbOfComp1);
8655       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8656       int *pt=ret->getPointer();
8657       for(int i=0;i<nbOfTuple1;i++)
8658         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8659       ret->copyStringInfoFrom(*a1);
8660       return ret.retn();
8661     }
8662   else
8663     {
8664       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8665       return 0;
8666     }
8667 }
8668
8669 /*!
8670  * Divide values of \a this array by values of another DataArrayInt. There are 3
8671  * valid cases.
8672  * 1.  The arrays have same number of tuples and components. Then each value of
8673  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8674  *   _a_ [ i, j ] /= _other_ [ i, j ].
8675  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8676  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8677  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8678  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8679  *
8680  *  \warning No check of division by zero is performed!
8681  *  \param [in] other - an array to divide \a this one by.
8682  *  \throw If \a other is NULL.
8683  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8684  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8685  *         \a other has number of both tuples and components not equal to 1.
8686  */
8687 void DataArrayInt::divideEqual(const DataArrayInt *other)
8688 {
8689   if(!other)
8690     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8691   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8692   checkAllocated(); other->checkAllocated();
8693   int nbOfTuple=getNumberOfTuples();
8694   int nbOfTuple2=other->getNumberOfTuples();
8695   int nbOfComp=getNumberOfComponents();
8696   int nbOfComp2=other->getNumberOfComponents();
8697   if(nbOfTuple==nbOfTuple2)
8698     {
8699       if(nbOfComp==nbOfComp2)
8700         {
8701           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8702         }
8703       else if(nbOfComp2==1)
8704         {
8705           int *ptr=getPointer();
8706           const int *ptrc=other->getConstPointer();
8707           for(int i=0;i<nbOfTuple;i++)
8708             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8709         }
8710       else
8711         throw INTERP_KERNEL::Exception(msg);
8712     }
8713   else if(nbOfTuple2==1)
8714     {
8715       if(nbOfComp2==nbOfComp)
8716         {
8717           int *ptr=getPointer();
8718           const int *ptrc=other->getConstPointer();
8719           for(int i=0;i<nbOfTuple;i++)
8720             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8721         }
8722       else
8723         throw INTERP_KERNEL::Exception(msg);
8724     }
8725   else
8726     throw INTERP_KERNEL::Exception(msg);
8727   declareAsNew();
8728 }
8729
8730
8731 /*!
8732  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8733  * valid cases.
8734  * 1.  The arrays have same number of tuples and components. Then each value of
8735  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8736  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8737  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8738  *   component. Then
8739  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8740  * 3.  The arrays have same number of components and one array, say _a2_, has one
8741  *   tuple. Then
8742  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8743  *
8744  * Info on components is copied either from the first array (in the first case) or from
8745  * the array with maximal number of elements (getNbOfElems()).
8746  *  \warning No check of division by zero is performed!
8747  *  \param [in] a1 - a dividend array.
8748  *  \param [in] a2 - a divisor array.
8749  *  \return DataArrayInt * - the new instance of DataArrayInt.
8750  *          The caller is to delete this result array using decrRef() as it is no more
8751  *          needed.
8752  *  \throw If either \a a1 or \a a2 is NULL.
8753  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8754  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8755  *         none of them has number of tuples or components equal to 1.
8756  */
8757 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8758 {
8759   if(!a1 || !a2)
8760     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8761   int nbOfTuple1=a1->getNumberOfTuples();
8762   int nbOfTuple2=a2->getNumberOfTuples();
8763   int nbOfComp1=a1->getNumberOfComponents();
8764   int nbOfComp2=a2->getNumberOfComponents();
8765   if(nbOfTuple2==nbOfTuple1)
8766     {
8767       if(nbOfComp1==nbOfComp2)
8768         {
8769           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8770           ret->alloc(nbOfTuple2,nbOfComp1);
8771           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8772           ret->copyStringInfoFrom(*a1);
8773           return ret.retn();
8774         }
8775       else if(nbOfComp2==1)
8776         {
8777           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8778           ret->alloc(nbOfTuple1,nbOfComp1);
8779           const int *a2Ptr=a2->getConstPointer();
8780           const int *a1Ptr=a1->getConstPointer();
8781           int *res=ret->getPointer();
8782           for(int i=0;i<nbOfTuple1;i++)
8783             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8784           ret->copyStringInfoFrom(*a1);
8785           return ret.retn();
8786         }
8787       else
8788         {
8789           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8790           return 0;
8791         }
8792     }
8793   else if(nbOfTuple2==1)
8794     {
8795       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8796       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8797       ret->alloc(nbOfTuple1,nbOfComp1);
8798       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8799       int *pt=ret->getPointer();
8800       for(int i=0;i<nbOfTuple1;i++)
8801         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8802       ret->copyStringInfoFrom(*a1);
8803       return ret.retn();
8804     }
8805   else
8806     {
8807       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8808       return 0;
8809     }
8810 }
8811
8812 /*!
8813  * Modify \a this array so that each value becomes a modulus of division of this value by
8814  * a value of another DataArrayInt. There are 3 valid cases.
8815  * 1.  The arrays have same number of tuples and components. Then each value of
8816  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8817  *   _a_ [ i, j ] %= _other_ [ i, j ].
8818  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8819  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8820  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8821  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8822  *
8823  *  \warning No check of division by zero is performed!
8824  *  \param [in] other - a divisor array.
8825  *  \throw If \a other is NULL.
8826  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8827  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8828  *         \a other has number of both tuples and components not equal to 1.
8829  */
8830 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8831 {
8832   if(!other)
8833     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8834   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8835   checkAllocated(); other->checkAllocated();
8836   int nbOfTuple=getNumberOfTuples();
8837   int nbOfTuple2=other->getNumberOfTuples();
8838   int nbOfComp=getNumberOfComponents();
8839   int nbOfComp2=other->getNumberOfComponents();
8840   if(nbOfTuple==nbOfTuple2)
8841     {
8842       if(nbOfComp==nbOfComp2)
8843         {
8844           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8845         }
8846       else if(nbOfComp2==1)
8847         {
8848           if(nbOfComp2==nbOfComp)
8849             {
8850               int *ptr=getPointer();
8851               const int *ptrc=other->getConstPointer();
8852               for(int i=0;i<nbOfTuple;i++)
8853                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8854             }
8855           else
8856             throw INTERP_KERNEL::Exception(msg);
8857         }
8858       else
8859         throw INTERP_KERNEL::Exception(msg);
8860     }
8861   else if(nbOfTuple2==1)
8862     {
8863       int *ptr=getPointer();
8864       const int *ptrc=other->getConstPointer();
8865       for(int i=0;i<nbOfTuple;i++)
8866         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8867     }
8868   else
8869     throw INTERP_KERNEL::Exception(msg);
8870   declareAsNew();
8871 }
8872
8873 /*!
8874  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8875  * valid cases.
8876  *
8877  *  \param [in] a1 - an array to pow up.
8878  *  \param [in] a2 - another array to sum up.
8879  *  \return DataArrayInt * - the new instance of DataArrayInt.
8880  *          The caller is to delete this result array using decrRef() as it is no more
8881  *          needed.
8882  *  \throw If either \a a1 or \a a2 is NULL.
8883  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8884  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8885  *  \throw If there is a negative value in \a a2.
8886  */
8887 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8888 {
8889   if(!a1 || !a2)
8890     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8891   int nbOfTuple=a1->getNumberOfTuples();
8892   int nbOfTuple2=a2->getNumberOfTuples();
8893   int nbOfComp=a1->getNumberOfComponents();
8894   int nbOfComp2=a2->getNumberOfComponents();
8895   if(nbOfTuple!=nbOfTuple2)
8896     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8897   if(nbOfComp!=1 || nbOfComp2!=1)
8898     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8899   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8900   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8901   int *ptr=ret->getPointer();
8902   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8903     {
8904       if(*ptr2>=0)
8905         {
8906           int tmp=1;
8907           for(int j=0;j<*ptr2;j++)
8908             tmp*=*ptr1;
8909           *ptr=tmp;
8910         }
8911       else
8912         {
8913           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8914           throw INTERP_KERNEL::Exception(oss.str().c_str());
8915         }
8916     }
8917   return ret.retn();
8918 }
8919
8920 /*!
8921  * Apply pow on values of another DataArrayInt to values of \a this one.
8922  *
8923  *  \param [in] other - an array to pow to \a this one.
8924  *  \throw If \a other is NULL.
8925  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8926  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8927  *  \throw If there is a negative value in \a other.
8928  */
8929 void DataArrayInt::powEqual(const DataArrayInt *other)
8930 {
8931   if(!other)
8932     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8933   int nbOfTuple=getNumberOfTuples();
8934   int nbOfTuple2=other->getNumberOfTuples();
8935   int nbOfComp=getNumberOfComponents();
8936   int nbOfComp2=other->getNumberOfComponents();
8937   if(nbOfTuple!=nbOfTuple2)
8938     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8939   if(nbOfComp!=1 || nbOfComp2!=1)
8940     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8941   int *ptr=getPointer();
8942   const int *ptrc=other->begin();
8943   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8944     {
8945       if(*ptrc>=0)
8946         {
8947           int tmp=1;
8948           for(int j=0;j<*ptrc;j++)
8949             tmp*=*ptr;
8950           *ptr=tmp;
8951         }
8952       else
8953         {
8954           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8955           throw INTERP_KERNEL::Exception(oss.str().c_str());
8956         }
8957     }
8958   declareAsNew();
8959 }
8960
8961 /*!
8962  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8963  * This map, if applied to \a start array, would make it sorted. For example, if
8964  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8965  * [5,6,0,3,2,7,1,4].
8966  *  \param [in] start - pointer to the first element of the array for which the
8967  *         permutation map is computed.
8968  *  \param [in] end - pointer specifying the end of the array \a start, so that
8969  *         the last value of \a start is \a end[ -1 ].
8970  *  \return int * - the result permutation array that the caller is to delete as it is no
8971  *         more needed.
8972  *  \throw If there are equal values in the input array.
8973  */
8974 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
8975 {
8976   std::size_t sz=std::distance(start,end);
8977   int *ret=(int *)malloc(sz*sizeof(int));
8978   int *work=new int[sz];
8979   std::copy(start,end,work);
8980   std::sort(work,work+sz);
8981   if(std::unique(work,work+sz)!=work+sz)
8982     {
8983       delete [] work;
8984       free(ret);
8985       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
8986     }
8987   std::map<int,int> m;
8988   for(int *workPt=work;workPt!=work+sz;workPt++)
8989     m[*workPt]=(int)std::distance(work,workPt);
8990   int *iter2=ret;
8991   for(const int *iter=start;iter!=end;iter++,iter2++)
8992     *iter2=m[*iter];
8993   delete [] work;
8994   return ret;
8995 }
8996
8997 /*!
8998  * Returns a new DataArrayInt containing an arithmetic progression
8999  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9000  * function.
9001  *  \param [in] begin - the start value of the result sequence.
9002  *  \param [in] end - limiting value, so that every value of the result array is less than
9003  *              \a end.
9004  *  \param [in] step - specifies the increment or decrement.
9005  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9006  *          array using decrRef() as it is no more needed.
9007  *  \throw If \a step == 0.
9008  *  \throw If \a end < \a begin && \a step > 0.
9009  *  \throw If \a end > \a begin && \a step < 0.
9010  */
9011 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9012 {
9013   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9014   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9015   ret->alloc(nbOfTuples,1);
9016   int *ptr=ret->getPointer();
9017   if(step>0)
9018     {
9019       for(int i=begin;i<end;i+=step,ptr++)
9020         *ptr=i;
9021     }
9022   else
9023     {
9024       for(int i=begin;i>end;i+=step,ptr++)
9025         *ptr=i;
9026     }
9027   return ret.retn();
9028 }
9029
9030 /*!
9031  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9032  * Server side.
9033  */
9034 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9035 {
9036   tinyInfo.resize(2);
9037   if(isAllocated())
9038     {
9039       tinyInfo[0]=getNumberOfTuples();
9040       tinyInfo[1]=getNumberOfComponents();
9041     }
9042   else
9043     {
9044       tinyInfo[0]=-1;
9045       tinyInfo[1]=-1;
9046     }
9047 }
9048
9049 /*!
9050  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9051  * Server side.
9052  */
9053 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9054 {
9055   if(isAllocated())
9056     {
9057       int nbOfCompo=getNumberOfComponents();
9058       tinyInfo.resize(nbOfCompo+1);
9059       tinyInfo[0]=getName();
9060       for(int i=0;i<nbOfCompo;i++)
9061         tinyInfo[i+1]=getInfoOnComponent(i);
9062     }
9063   else
9064     {
9065       tinyInfo.resize(1);
9066       tinyInfo[0]=getName();
9067     }
9068 }
9069
9070 /*!
9071  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9072  * This method returns if a feeding is needed.
9073  */
9074 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9075 {
9076   int nbOfTuple=tinyInfoI[0];
9077   int nbOfComp=tinyInfoI[1];
9078   if(nbOfTuple!=-1 || nbOfComp!=-1)
9079     {
9080       alloc(nbOfTuple,nbOfComp);
9081       return true;
9082     }
9083   return false;
9084 }
9085
9086 /*!
9087  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9088  * This method returns if a feeding is needed.
9089  */
9090 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9091 {
9092   setName(tinyInfoS[0]);
9093   if(isAllocated())
9094     {
9095       int nbOfCompo=tinyInfoI[1];
9096       for(int i=0;i<nbOfCompo;i++)
9097         setInfoOnComponent(i,tinyInfoS[i+1]);
9098     }
9099 }
9100
9101 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
9102 {
9103 }
9104
9105 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
9106 {
9107 }
9108
9109 std::string DataArrayIntTuple::repr() const
9110 {
9111   std::ostringstream oss; oss << "(";
9112   for(int i=0;i<_nb_of_compo-1;i++)
9113     oss << _pt[i] << ", ";
9114   oss << _pt[_nb_of_compo-1] << ")";
9115   return oss.str();
9116 }
9117
9118 int DataArrayIntTuple::intValue() const
9119 {
9120   return this->zeValue();
9121 }
9122
9123 /*!
9124  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9125  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9126  * 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
9127  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9128  */
9129 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9130 {
9131   return this->buildDA(nbOfTuples,nbOfCompo);
9132 }