Salome HOME
4218da2977993302cec1a53d8054528b8cfd0f6f
[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
44 template<int SPACEDIM>
45 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
46 {
47   const double *coordsPtr=getConstPointer();
48   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
49   std::vector<bool> isDone(nbNodes);
50   for(int i=0;i<nbNodes;i++)
51     {
52       if(!isDone[i])
53         {
54           std::vector<int> intersectingElems;
55           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
56           if(intersectingElems.size()>1)
57             {
58               std::vector<int> commonNodes;
59               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
60                 if(*it!=i)
61                   if(*it>=limitNodeId)
62                     {
63                       commonNodes.push_back(*it);
64                       isDone[*it]=true;
65                     }
66               if(!commonNodes.empty())
67                 {
68                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
69                   c->pushBackSilent(i);
70                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
71                 }
72             }
73         }
74     }
75 }
76
77 template<int SPACEDIM>
78 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
79                                                 DataArrayInt *c, DataArrayInt *cI)
80 {
81   for(int i=0;i<nbOfTuples;i++)
82     {
83       std::vector<int> intersectingElems;
84       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
85       std::vector<int> commonNodes;
86       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
87         commonNodes.push_back(*it);
88       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
89       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
90     }
91 }
92
93 template<int SPACEDIM>
94 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
95 {
96   double distOpt(dist);
97   const double *p(pos);
98   int *r(res);
99   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
100     {
101       while(true)
102         {
103           int elem=-1;
104           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
105           if(ret!=std::numeric_limits<double>::max())
106             {
107               distOpt=std::max(ret,1e-4);
108               *r=elem;
109               break;
110             }
111           else
112             { distOpt=2*distOpt; continue; }
113         }
114     }
115 }
116
117 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
118 {
119   if(nbOfTuples<=0)
120     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
121   if(nbOfShift>=0)
122     {
123       return nbOfShift%nbOfTuples;
124     }
125   else
126     {
127       int tmp(-nbOfShift);
128       tmp=tmp%nbOfTuples;
129       return nbOfTuples-tmp;
130     }
131 }
132
133 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
134 {
135   std::size_t sz1=_name.capacity();
136   std::size_t sz2=_info_on_compo.capacity();
137   std::size_t sz3=0;
138   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
139     sz3+=(*it).capacity();
140   return sz1+sz2+sz3;
141 }
142
143 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
144 {
145   return std::vector<const BigMemoryObject *>();
146 }
147
148 /*!
149  * Sets the attribute \a _name of \a this array.
150  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
151  *  \param [in] name - new array name
152  */
153 void DataArray::setName(const std::string& name)
154 {
155   _name=name;
156 }
157
158 /*!
159  * Copies textual data from an \a other DataArray. The copied data are
160  * - the name attribute,
161  * - the information of components.
162  *
163  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
164  *
165  *  \param [in] other - another instance of DataArray to copy the textual data from.
166  *  \throw If number of components of \a this array differs from that of the \a other.
167  */
168 void DataArray::copyStringInfoFrom(const DataArray& other)
169 {
170   if(_info_on_compo.size()!=other._info_on_compo.size())
171     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
172   _name=other._name;
173   _info_on_compo=other._info_on_compo;
174 }
175
176 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
177 {
178   int nbOfCompoOth=other.getNumberOfComponents();
179   std::size_t newNbOfCompo=compoIds.size();
180   for(std::size_t i=0;i<newNbOfCompo;i++)
181     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
182       {
183         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
184         throw INTERP_KERNEL::Exception(oss.str().c_str());
185       }
186   for(std::size_t i=0;i<newNbOfCompo;i++)
187     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
188 }
189
190 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
191 {
192   int nbOfCompo=getNumberOfComponents();
193   std::size_t partOfCompoToSet=compoIds.size();
194   if((int)partOfCompoToSet!=other.getNumberOfComponents())
195     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
196   for(std::size_t i=0;i<partOfCompoToSet;i++)
197     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
198       {
199         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
200         throw INTERP_KERNEL::Exception(oss.str().c_str());
201       }
202   for(std::size_t i=0;i<partOfCompoToSet;i++)
203     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
204 }
205
206 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
207 {
208   std::ostringstream oss;
209   if(_name!=other._name)
210     {
211       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
212       reason=oss.str();
213       return false;
214     }
215   if(_info_on_compo!=other._info_on_compo)
216     {
217       oss << "Components DataArray mismatch : \nThis components=";
218       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
219         oss << "\"" << *it << "\",";
220       oss << "\nOther components=";
221       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
222         oss << "\"" << *it << "\",";
223       reason=oss.str();
224       return false;
225     }
226   return true;
227 }
228
229 /*!
230  * Compares textual information of \a this DataArray with that of an \a other one.
231  * The compared data are
232  * - the name attribute,
233  * - the information of components.
234  *
235  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
236  *  \param [in] other - another instance of DataArray to compare the textual data of.
237  *  \return bool - \a true if the textual information is same, \a false else.
238  */
239 bool DataArray::areInfoEquals(const DataArray& other) const
240 {
241   std::string tmp;
242   return areInfoEqualsIfNotWhy(other,tmp);
243 }
244
245 void DataArray::reprWithoutNameStream(std::ostream& stream) const
246 {
247   stream << "Number of components : "<< getNumberOfComponents() << "\n";
248   stream << "Info of these components : ";
249   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
250     stream << "\"" << *iter << "\"   ";
251   stream << "\n";
252 }
253
254 std::string DataArray::cppRepr(const std::string& varName) const
255 {
256   std::ostringstream ret;
257   reprCppStream(varName,ret);
258   return ret.str();
259 }
260
261 /*!
262  * Sets information on all components. To know more on format of this information
263  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
264  *  \param [in] info - a vector of strings.
265  *  \throw If size of \a info differs from the number of components of \a this.
266  */
267 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
268 {
269   if(getNumberOfComponents()!=(int)info.size())
270     {
271       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
272       throw INTERP_KERNEL::Exception(oss.str().c_str());
273     }
274   _info_on_compo=info;
275 }
276
277 /*!
278  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
279  * type of \a this and \a aBase.
280  *
281  * \throw If \a aBase and \a this do not have the same type.
282  *
283  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
284  */
285 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
286 {
287   if(!aBase)
288     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
289   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
290   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
291   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
292   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
293   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
294   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
295   if(this1 && a1)
296     {
297       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
298       return ;
299     }
300   if(this2 && a2)
301     {
302       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
303       return ;
304     }
305   if(this3 && a3)
306     {
307       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
308       return ;
309     }
310   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
311 }
312
313 std::vector<std::string> DataArray::getVarsOnComponent() const
314 {
315   int nbOfCompo=(int)_info_on_compo.size();
316   std::vector<std::string> ret(nbOfCompo);
317   for(int i=0;i<nbOfCompo;i++)
318     ret[i]=getVarOnComponent(i);
319   return ret;
320 }
321
322 std::vector<std::string> DataArray::getUnitsOnComponent() const
323 {
324   int nbOfCompo=(int)_info_on_compo.size();
325   std::vector<std::string> ret(nbOfCompo);
326   for(int i=0;i<nbOfCompo;i++)
327     ret[i]=getUnitOnComponent(i);
328   return ret;
329 }
330
331 /*!
332  * Returns information on a component specified by an index.
333  * To know more on format of this information
334  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
335  *  \param [in] i - the index (zero based) of the component of interest.
336  *  \return std::string - a string containing the information on \a i-th component.
337  *  \throw If \a i is not a valid component index.
338  */
339 std::string DataArray::getInfoOnComponent(int i) const
340 {
341   if(i<(int)_info_on_compo.size() && i>=0)
342     return _info_on_compo[i];
343   else
344     {
345       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();
346       throw INTERP_KERNEL::Exception(oss.str().c_str());
347     }
348 }
349
350 /*!
351  * Returns the var part of the full information of the \a i-th component.
352  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
353  * \c getVarOnComponent(0) returns "SIGXY".
354  * If a unit part of information is not detected by presence of
355  * two square brackets, then the full information is returned.
356  * To read more about the component information format, see
357  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
358  *  \param [in] i - the index (zero based) of the component of interest.
359  *  \return std::string - a string containing the var information, or the full info.
360  *  \throw If \a i is not a valid component index.
361  */
362 std::string DataArray::getVarOnComponent(int i) const
363 {
364   if(i<(int)_info_on_compo.size() && i>=0)
365     {
366       return GetVarNameFromInfo(_info_on_compo[i]);
367     }
368   else
369     {
370       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();
371       throw INTERP_KERNEL::Exception(oss.str().c_str());
372     }
373 }
374
375 /*!
376  * Returns the unit part of the full information of the \a i-th component.
377  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
378  * \c getUnitOnComponent(0) returns " N/m^2".
379  * If a unit part of information is not detected by presence of
380  * two square brackets, then an empty string is returned.
381  * To read more about the component information format, see
382  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
383  *  \param [in] i - the index (zero based) of the component of interest.
384  *  \return std::string - a string containing the unit information, if any, or "".
385  *  \throw If \a i is not a valid component index.
386  */
387 std::string DataArray::getUnitOnComponent(int i) const
388 {
389   if(i<(int)_info_on_compo.size() && i>=0)
390     {
391       return GetUnitFromInfo(_info_on_compo[i]);
392     }
393   else
394     {
395       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();
396       throw INTERP_KERNEL::Exception(oss.str().c_str());
397     }
398 }
399
400 /*!
401  * Returns the var part of the full component information.
402  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
403  * If a unit part of information is not detected by presence of
404  * two square brackets, then the whole \a info is returned.
405  * To read more about the component information format, see
406  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
407  *  \param [in] info - the full component information.
408  *  \return std::string - a string containing only var information, or the \a info.
409  */
410 std::string DataArray::GetVarNameFromInfo(const std::string& info)
411 {
412   std::size_t p1=info.find_last_of('[');
413   std::size_t p2=info.find_last_of(']');
414   if(p1==std::string::npos || p2==std::string::npos)
415     return info;
416   if(p1>p2)
417     return info;
418   if(p1==0)
419     return std::string();
420   std::size_t p3=info.find_last_not_of(' ',p1-1);
421   return info.substr(0,p3+1);
422 }
423
424 /*!
425  * Returns the unit part of the full component information.
426  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
427  * If a unit part of information is not detected by presence of
428  * two square brackets, then an empty string is returned.
429  * To read more about the component information format, see
430  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
431  *  \param [in] info - the full component information.
432  *  \return std::string - a string containing only unit information, if any, or "".
433  */
434 std::string DataArray::GetUnitFromInfo(const std::string& info)
435 {
436   std::size_t p1=info.find_last_of('[');
437   std::size_t p2=info.find_last_of(']');
438   if(p1==std::string::npos || p2==std::string::npos)
439     return std::string();
440   if(p1>p2)
441     return std::string();
442   return info.substr(p1+1,p2-p1-1);
443 }
444
445 /*!
446  * This method put in info format the result of the merge of \a var and \a unit.
447  * The standard format for that is "var [unit]".
448  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
449  */
450 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
451 {
452   std::ostringstream oss;
453   oss << var << " [" << unit << "]";
454   return oss.str();
455 }
456
457 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
458 {
459   switch(at)
460     {
461     case AX_CART:
462       return std::string("AX_CART");
463     case AX_CYL:
464       return std::string("AX_CYL");
465     case AX_SPHER:
466       return std::string("AX_SPHER");
467     default:
468       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
469     }
470 }
471
472 /*!
473  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
474  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
475  * the number of component in the result array is same as that of each of given arrays.
476  * Info on components is copied from the first of the given arrays. Number of components
477  * in the given arrays must be  the same.
478  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
479  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
480  *          The caller is to delete this result array using decrRef() as it is no more
481  *          needed.
482  *  \throw If all arrays within \a arrs are NULL.
483  *  \throw If all not null arrays in \a arrs have not the same type.
484  *  \throw If getNumberOfComponents() of arrays within \a arrs.
485  */
486 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
487 {
488   std::vector<const DataArray *> arr2;
489   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
490     if(*it)
491       arr2.push_back(*it);
492   if(arr2.empty())
493     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
494   std::vector<const DataArrayDouble *> arrd;
495   std::vector<const DataArrayInt *> arri;
496   std::vector<const DataArrayChar *> arrc;
497   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
498     {
499       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
500       if(a)
501         { arrd.push_back(a); continue; }
502       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
503       if(b)
504         { arri.push_back(b); continue; }
505       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
506       if(c)
507         { arrc.push_back(c); continue; }
508       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
509     }
510   if(arr2.size()==arrd.size())
511     return DataArrayDouble::Aggregate(arrd);
512   if(arr2.size()==arri.size())
513     return DataArrayInt::Aggregate(arri);
514   if(arr2.size()==arrc.size())
515     return DataArrayChar::Aggregate(arrc);
516   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
517 }
518
519 /*!
520  * Sets information on a component specified by an index.
521  * To know more on format of this information
522  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
523  *  \warning Don't pass NULL as \a info!
524  *  \param [in] i - the index (zero based) of the component of interest.
525  *  \param [in] info - the string containing the information.
526  *  \throw If \a i is not a valid component index.
527  */
528 void DataArray::setInfoOnComponent(int i, const std::string& info)
529 {
530   if(i<(int)_info_on_compo.size() && i>=0)
531     _info_on_compo[i]=info;
532   else
533     {
534       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();
535       throw INTERP_KERNEL::Exception(oss.str().c_str());
536     }
537 }
538
539 /*!
540  * Sets information on all components. This method can change number of components
541  * at certain conditions; if the conditions are not respected, an exception is thrown.
542  * The number of components can be changed in \a this only if \a this is not allocated.
543  * The condition of number of components must not be changed.
544  *
545  * To know more on format of the component information see
546  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
547  *  \param [in] info - a vector of component infos.
548  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
549  */
550 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
551 {
552   if(getNumberOfComponents()!=(int)info.size())
553     {
554       if(!isAllocated())
555         _info_on_compo=info;
556       else
557         {
558           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 !";
559           throw INTERP_KERNEL::Exception(oss.str().c_str());
560         }
561     }
562   else
563     _info_on_compo=info;
564 }
565
566 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
567 {
568   if(getNumberOfTuples()!=nbOfTuples)
569     {
570       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
571       throw INTERP_KERNEL::Exception(oss.str().c_str());
572     }
573 }
574
575 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
576 {
577   if(getNumberOfComponents()!=nbOfCompo)
578     {
579       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582 }
583
584 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
585 {
586   if(getNbOfElems()!=nbOfElems)
587     {
588       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
589       throw INTERP_KERNEL::Exception(oss.str().c_str());
590     }
591 }
592
593 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
594 {
595   if(getNumberOfTuples()!=other.getNumberOfTuples())
596     {
597       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
598       throw INTERP_KERNEL::Exception(oss.str().c_str());
599     }
600   if(getNumberOfComponents()!=other.getNumberOfComponents())
601     {
602       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
603       throw INTERP_KERNEL::Exception(oss.str().c_str());
604     }
605 }
606
607 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
608 {
609   checkNbOfTuples(nbOfTuples,msg);
610   checkNbOfComps(nbOfCompo,msg);
611 }
612
613 /*!
614  * Simply this method checks that \b value is in [0,\b ref).
615  */
616 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
617 {
618   if(value<0 || value>=ref)
619     {
620       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
621       throw INTERP_KERNEL::Exception(oss.str().c_str());
622     }
623 }
624
625 /*!
626  * This method checks that [\b start, \b end) is compliant with ref length \b value.
627  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
628  */
629 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
630 {
631   if(start<0 || start>=value)
632     {
633       if(value!=start || end!=start)
634         {
635           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
636           throw INTERP_KERNEL::Exception(oss.str().c_str());
637         }
638     }
639   if(end<0 || end>value)
640     {
641       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
642       throw INTERP_KERNEL::Exception(oss.str().c_str());
643     }
644 }
645
646 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
647 {
648   if(value<0 || value>ref)
649     {
650       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
651       throw INTERP_KERNEL::Exception(oss.str().c_str());
652     }
653 }
654
655 /*!
656  * 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, 
657  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
658  *
659  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
660  *
661  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
662  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
663  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
664  * \param [in] sliceId - the slice id considered
665  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
666  * \param [out] startSlice - the start of the slice considered
667  * \param [out] stopSlice - the stop of the slice consided
668  * 
669  * \throw If \a step == 0
670  * \throw If \a nbOfSlices not > 0
671  * \throw If \a sliceId not in [0,nbOfSlices)
672  */
673 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
674 {
675   if(nbOfSlices<=0)
676     {
677       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
678       throw INTERP_KERNEL::Exception(oss.str().c_str());
679     }
680   if(sliceId<0 || sliceId>=nbOfSlices)
681     {
682       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
686   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
687   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
688   if(sliceId<nbOfSlices-1)
689     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
690   else
691     stopSlice=stop;
692 }
693
694 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
695 {
696   if(end<begin)
697     {
698       std::ostringstream oss; oss << msg << " : end before begin !";
699       throw INTERP_KERNEL::Exception(oss.str().c_str());
700     }
701   if(end==begin)
702     return 0;
703   if(step<=0)
704     {
705       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
706       throw INTERP_KERNEL::Exception(oss.str().c_str());
707     }
708   return (end-1-begin)/step+1;
709 }
710
711 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
712 {
713   if(step==0)
714     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
715   if(end<begin && step>0)
716     {
717       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
718       throw INTERP_KERNEL::Exception(oss.str().c_str());
719     }
720   if(begin<end && step<0)
721     {
722       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
723       throw INTERP_KERNEL::Exception(oss.str().c_str());
724     }
725   if(begin!=end)
726     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
727   else
728     return 0;
729 }
730
731 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
732 {
733   if(step!=0)
734     {
735       if(step>0)
736         {
737           if(begin<=value && value<end)
738             {
739               if((value-begin)%step==0)
740                 return (value-begin)/step;
741               else
742                 return -1;
743             }
744           else
745             return -1;
746         }
747       else
748         {
749           if(begin>=value && value>end)
750             {
751               if((begin-value)%(-step)==0)
752                 return (begin-value)/(-step);
753               else
754                 return -1;
755             }
756           else
757             return -1;
758         }
759     }
760   else
761     return -1;
762 }
763
764 /*!
765  * Returns a new instance of DataArrayDouble. The caller is to delete this array
766  * using decrRef() as it is no more needed. 
767  */
768 DataArrayDouble *DataArrayDouble::New()
769 {
770   return new DataArrayDouble;
771 }
772
773 /*!
774  * Returns the only one value in \a this, if and only if number of elements
775  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
776  *  \return double - the sole value stored in \a this array.
777  *  \throw If at least one of conditions stated above is not fulfilled.
778  */
779 double DataArrayDouble::doubleValue() const
780 {
781   if(isAllocated())
782     {
783       if(getNbOfElems()==1)
784         {
785           return *getConstPointer();
786         }
787       else
788         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
789     }
790   else
791     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
792 }
793
794 /*!
795  * Returns a full copy of \a this. For more info on copying data arrays see
796  * \ref MEDCouplingArrayBasicsCopyDeep.
797  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
798  *          delete this array using decrRef() as it is no more needed. 
799  */
800 DataArrayDouble *DataArrayDouble::deepCopy() const
801 {
802   return new DataArrayDouble(*this);
803 }
804
805 /*!
806  * Returns either a \a deep or \a shallow copy of this array. For more info see
807  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
808  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
809  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
810  *          == \a true) or \a this instance (if \a dCpy == \a false).
811  */
812 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
813 {
814   if(dCpy)
815     return deepCopy();
816   else
817     {
818       incrRef();
819       return const_cast<DataArrayDouble *>(this);
820     }
821 }
822
823 /*!
824  * Assign zero to all values in \a this array. To know more on filling arrays see
825  * \ref MEDCouplingArrayFill.
826  * \throw If \a this is not allocated.
827  */
828 void DataArrayDouble::fillWithZero()
829 {
830   fillWithValue(0.);
831 }
832
833 /*!
834  * Set all values in \a this array so that the i-th element equals to \a init + i
835  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
836  *  \param [in] init - value to assign to the first element of array.
837  *  \throw If \a this->getNumberOfComponents() != 1
838  *  \throw If \a this is not allocated.
839  */
840 void DataArrayDouble::iota(double init)
841 {
842   checkAllocated();
843   if(getNumberOfComponents()!=1)
844     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
845   double *ptr=getPointer();
846   int ntuples=getNumberOfTuples();
847   for(int i=0;i<ntuples;i++)
848     ptr[i]=init+double(i);
849   declareAsNew();
850 }
851
852 /*!
853  * Checks if all values in \a this array are equal to \a val at precision \a eps.
854  *  \param [in] val - value to check equality of array values to.
855  *  \param [in] eps - precision to check the equality.
856  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
857  *                 \a false else.
858  *  \throw If \a this->getNumberOfComponents() != 1
859  *  \throw If \a this is not allocated.
860  */
861 bool DataArrayDouble::isUniform(double val, double eps) const
862 {
863   checkAllocated();
864   if(getNumberOfComponents()!=1)
865     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
866   int nbOfTuples=getNumberOfTuples();
867   const double *w=getConstPointer();
868   const double *end2=w+nbOfTuples;
869   const double vmin=val-eps;
870   const double vmax=val+eps;
871   for(;w!=end2;w++)
872     if(*w<vmin || *w>vmax)
873       return false;
874   return true;
875 }
876
877 /*!
878  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
879  * with at least absolute difference value of |\a eps| at each step.
880  * If not an exception is thrown.
881  *  \param [in] increasing - if \a true, the array values should be increasing.
882  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
883  *                    the values are considered different.
884  *  \throw If sequence of values is not strictly monotonic in agreement with \a
885  *         increasing arg.
886  *  \throw If \a this->getNumberOfComponents() != 1.
887  *  \throw If \a this is not allocated.
888  */
889 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
890 {
891   if(!isMonotonic(increasing,eps))
892     {
893       if (increasing)
894         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
895       else
896         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
897     }
898 }
899
900 /*!
901  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
902  * with at least absolute difference value of |\a eps| at each step.
903  *  \param [in] increasing - if \a true, array values should be increasing.
904  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
905  *                    the values are considered different.
906  *  \return bool - \a true if values change in accordance with \a increasing arg.
907  *  \throw If \a this->getNumberOfComponents() != 1.
908  *  \throw If \a this is not allocated.
909  */
910 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
911 {
912   checkAllocated();
913   if(getNumberOfComponents()!=1)
914     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
915   int nbOfElements=getNumberOfTuples();
916   const double *ptr=getConstPointer();
917   if(nbOfElements==0)
918     return true;
919   double ref=ptr[0];
920   double absEps=fabs(eps);
921   if(increasing)
922     {
923       for(int i=1;i<nbOfElements;i++)
924         {
925           if(ptr[i]<(ref+absEps))
926             return false;
927           ref=ptr[i];
928         }
929       return true;
930     }
931   else
932     {
933       for(int i=1;i<nbOfElements;i++)
934         {
935           if(ptr[i]>(ref-absEps))
936             return false;
937           ref=ptr[i];
938         }
939       return true;
940     }
941 }
942
943 /*!
944  * Returns a textual and human readable representation of \a this instance of
945  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
946  * \return std::string - text describing \a this DataArrayDouble.
947  *
948  * \sa reprNotTooLong, reprZip
949  */
950 std::string DataArrayDouble::repr() const
951 {
952   std::ostringstream ret;
953   reprStream(ret);
954   return ret.str();
955 }
956
957 std::string DataArrayDouble::reprZip() const
958 {
959   std::ostringstream ret;
960   reprZipStream(ret);
961   return ret.str();
962 }
963
964 /*!
965  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
966  * printed out to avoid to consume too much space in interpretor.
967  * \sa repr
968  */
969 std::string DataArrayDouble::reprNotTooLong() const
970 {
971   std::ostringstream ret;
972   reprNotTooLongStream(ret);
973   return ret.str();
974 }
975
976 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
977 {
978   static const char SPACE[4]={' ',' ',' ',' '};
979   checkAllocated();
980   std::string idt(indent,' ');
981   ofs.precision(17);
982   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
983   //
984   bool areAllEmpty(true);
985   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
986     if(!(*it).empty())
987       areAllEmpty=false;
988   if(!areAllEmpty)
989     for(std::size_t i=0;i<_info_on_compo.size();i++)
990       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
991   //
992   if(byteArr)
993     {
994       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
995       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
996       float *pt(tmp);
997       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
998       for(const double *src=begin();src!=end();src++,pt++)
999         *pt=float(*src);
1000       const char *data(reinterpret_cast<const char *>((float *)tmp));
1001       std::size_t sz(getNbOfElems()*sizeof(float));
1002       byteArr->insertAtTheEnd(data,data+sz);
1003       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1004     }
1005   else
1006     {
1007       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1008       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1009     }
1010   ofs << std::endl << idt << "</DataArray>\n";
1011 }
1012
1013 void DataArrayDouble::reprStream(std::ostream& stream) const
1014 {
1015   stream << "Name of double array : \"" << _name << "\"\n";
1016   reprWithoutNameStream(stream);
1017 }
1018
1019 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1020 {
1021   stream << "Name of double array : \"" << _name << "\"\n";
1022   reprZipWithoutNameStream(stream);
1023 }
1024
1025 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1026 {
1027   stream << "Name of double array : \"" << _name << "\"\n";
1028   reprNotTooLongWithoutNameStream(stream);
1029 }
1030
1031 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1032 {
1033   DataArray::reprWithoutNameStream(stream);
1034   stream.precision(17);
1035   _mem.repr(getNumberOfComponents(),stream);
1036 }
1037
1038 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1039 {
1040   DataArray::reprWithoutNameStream(stream);
1041   stream.precision(17);
1042   _mem.reprZip(getNumberOfComponents(),stream);
1043 }
1044
1045 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1046 {
1047   DataArray::reprWithoutNameStream(stream);
1048   stream.precision(17);
1049   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1050 }
1051
1052 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1053 {
1054   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1055   const double *data=getConstPointer();
1056   stream.precision(17);
1057   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1058   if(nbTuples*nbComp>=1)
1059     {
1060       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1061       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1062       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1063       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1064     }
1065   else
1066     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1067   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1068 }
1069
1070 /*!
1071  * Method that gives a quick overvien of \a this for python.
1072  */
1073 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1074 {
1075   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1076   stream << "DataArrayDouble C++ instance at " << this << ". ";
1077   if(isAllocated())
1078     {
1079       int nbOfCompo=(int)_info_on_compo.size();
1080       if(nbOfCompo>=1)
1081         {
1082           int nbOfTuples=getNumberOfTuples();
1083           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1084           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1085         }
1086       else
1087         stream << "Number of components : 0.";
1088     }
1089   else
1090     stream << "*** No data allocated ****";
1091 }
1092
1093 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1094 {
1095   const double *data=begin();
1096   int nbOfTuples=getNumberOfTuples();
1097   int nbOfCompo=(int)_info_on_compo.size();
1098   std::ostringstream oss2; oss2 << "[";
1099   oss2.precision(17);
1100   std::string oss2Str(oss2.str());
1101   bool isFinished=true;
1102   for(int i=0;i<nbOfTuples && isFinished;i++)
1103     {
1104       if(nbOfCompo>1)
1105         {
1106           oss2 << "(";
1107           for(int j=0;j<nbOfCompo;j++,data++)
1108             {
1109               oss2 << *data;
1110               if(j!=nbOfCompo-1) oss2 << ", ";
1111             }
1112           oss2 << ")";
1113         }
1114       else
1115         oss2 << *data++;
1116       if(i!=nbOfTuples-1) oss2 << ", ";
1117       std::string oss3Str(oss2.str());
1118       if(oss3Str.length()<maxNbOfByteInRepr)
1119         oss2Str=oss3Str;
1120       else
1121         isFinished=false;
1122     }
1123   stream << oss2Str;
1124   if(!isFinished)
1125     stream << "... ";
1126   stream << "]";
1127 }
1128
1129 /*!
1130  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1131  * mismatch is given.
1132  * 
1133  * \param [in] other the instance to be compared with \a this
1134  * \param [in] prec the precision to compare numeric data of the arrays.
1135  * \param [out] reason In case of inequality returns the reason.
1136  * \sa DataArrayDouble::isEqual
1137  */
1138 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1139 {
1140   if(!areInfoEqualsIfNotWhy(other,reason))
1141     return false;
1142   return _mem.isEqual(other._mem,prec,reason);
1143 }
1144
1145 /*!
1146  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1147  * \ref MEDCouplingArrayBasicsCompare.
1148  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1149  *  \param [in] prec - precision value to compare numeric data of the arrays.
1150  *  \return bool - \a true if the two arrays are equal, \a false else.
1151  */
1152 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1153 {
1154   std::string tmp;
1155   return isEqualIfNotWhy(other,prec,tmp);
1156 }
1157
1158 /*!
1159  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1160  * \ref MEDCouplingArrayBasicsCompare.
1161  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1162  *  \param [in] prec - precision value to compare numeric data of the arrays.
1163  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1164  */
1165 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1166 {
1167   std::string tmp;
1168   return _mem.isEqual(other._mem,prec,tmp);
1169 }
1170
1171 /*!
1172  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1173  * array to the new one.
1174  *  \return DataArrayInt * - the new instance of DataArrayInt.
1175  */
1176 DataArrayInt *DataArrayDouble::convertToIntArr() const
1177 {
1178   DataArrayInt *ret=DataArrayInt::New();
1179   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1180   int *dest=ret->getPointer();
1181   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1182   for(const double *src=begin();src!=end();src++,dest++)
1183     *dest=(int)*src;
1184   ret->copyStringInfoFrom(*this);
1185   return ret;
1186 }
1187
1188 /*!
1189  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1190  * arranged in memory. If \a this array holds 2 components of 3 values:
1191  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1192  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1193  *  \warning Do not confuse this method with transpose()!
1194  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1195  *          is to delete using decrRef() as it is no more needed.
1196  *  \throw If \a this is not allocated.
1197  */
1198 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1199 {
1200   if(_mem.isNull())
1201     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1202   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1203   DataArrayDouble *ret=DataArrayDouble::New();
1204   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1205   return ret;
1206 }
1207
1208 /*!
1209  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1210  * arranged in memory. If \a this array holds 2 components of 3 values:
1211  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1212  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1213  *  \warning Do not confuse this method with transpose()!
1214  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1215  *          is to delete using decrRef() as it is no more needed.
1216  *  \throw If \a this is not allocated.
1217  */
1218 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1219 {
1220   if(_mem.isNull())
1221     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1222   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1223   DataArrayDouble *ret=DataArrayDouble::New();
1224   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1225   return ret;
1226 }
1227
1228 /*!
1229  * Appends components of another array to components of \a this one, tuple by tuple.
1230  * So that the number of tuples of \a this array remains the same and the number of 
1231  * components increases.
1232  *  \param [in] other - the DataArrayDouble to append to \a this one.
1233  *  \throw If \a this is not allocated.
1234  *  \throw If \a this and \a other arrays have different number of tuples.
1235  *
1236  *  \if ENABLE_EXAMPLES
1237  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1238  *
1239  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1240  *  \endif
1241  */
1242 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1243 {
1244   checkAllocated();
1245   other->checkAllocated();
1246   int nbOfTuples=getNumberOfTuples();
1247   if(nbOfTuples!=other->getNumberOfTuples())
1248     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1249   int nbOfComp1=getNumberOfComponents();
1250   int nbOfComp2=other->getNumberOfComponents();
1251   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1252   double *w=newArr;
1253   const double *inp1=getConstPointer();
1254   const double *inp2=other->getConstPointer();
1255   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1256     {
1257       w=std::copy(inp1,inp1+nbOfComp1,w);
1258       w=std::copy(inp2,inp2+nbOfComp2,w);
1259     }
1260   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1261   std::vector<int> compIds(nbOfComp2);
1262   for(int i=0;i<nbOfComp2;i++)
1263     compIds[i]=nbOfComp1+i;
1264   copyPartOfStringInfoFrom2(compIds,*other);
1265 }
1266
1267 /*!
1268  * This method checks that all tuples in \a other are in \a this.
1269  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1270  * 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.
1271  *
1272  * \param [in] other - the array having the same number of components than \a this.
1273  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1274  * \sa DataArrayDouble::findCommonTuples
1275  */
1276 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1277 {
1278   if(!other)
1279     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1280   checkAllocated(); other->checkAllocated();
1281   if(getNumberOfComponents()!=other->getNumberOfComponents())
1282     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1283   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1284   DataArrayInt *c=0,*ci=0;
1285   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1286   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1287   int newNbOfTuples=-1;
1288   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1289   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1290   tupleIds=ret1.retn();
1291   return newNbOfTuples==getNumberOfTuples();
1292 }
1293
1294 /*!
1295  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1296  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1297  * distance separating two points is computed with the infinite norm.
1298  *
1299  * Indices of coincident tuples are stored in output arrays.
1300  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1301  *
1302  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1303  * MEDCouplingUMesh::mergeNodes().
1304  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1305  *              considered not coincident.
1306  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1307  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1308  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1309  *               \a comm->getNumberOfComponents() == 1. 
1310  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1311  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1312  *               groups of (indices of) coincident tuples. Its every value is a tuple
1313  *               index where a next group of tuples begins. For example the second
1314  *               group of tuples in \a comm is described by following range of indices:
1315  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1316  *               gives the number of groups of coincident tuples.
1317  *  \throw If \a this is not allocated.
1318  *  \throw If the number of components is not in [1,2,3,4].
1319  *
1320  *  \if ENABLE_EXAMPLES
1321  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1322  *
1323  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1324  *  \endif
1325  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1326  */
1327 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1328 {
1329   checkAllocated();
1330   int nbOfCompo=getNumberOfComponents();
1331   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1332     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1333
1334   int nbOfTuples=getNumberOfTuples();
1335   //
1336   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1337   switch(nbOfCompo)
1338   {
1339     case 4:
1340       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1341       break;
1342     case 3:
1343       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1344       break;
1345     case 2:
1346       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1347       break;
1348     case 1:
1349       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1350       break;
1351     default:
1352       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1353   }
1354   comm=c.retn();
1355   commIndex=cI.retn();
1356 }
1357
1358 /*!
1359  * 
1360  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1361  *             \a nbTimes  should be at least equal to 1.
1362  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1363  * \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.
1364  */
1365 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1366 {
1367   checkAllocated();
1368   if(getNumberOfComponents()!=1)
1369     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1370   if(nbTimes<1)
1371     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1372   int nbTuples=getNumberOfTuples();
1373   const double *inPtr=getConstPointer();
1374   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1375   double *retPtr=ret->getPointer();
1376   for(int i=0;i<nbTuples;i++,inPtr++)
1377     {
1378       double val=*inPtr;
1379       for(int j=0;j<nbTimes;j++,retPtr++)
1380         *retPtr=val;
1381     }
1382   ret->copyStringInfoFrom(*this);
1383   return ret.retn();
1384 }
1385
1386 /*!
1387  * This methods returns the minimal distance between the two set of points \a this and \a other.
1388  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1389  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1390  *
1391  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1392  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1393  * \return the minimal distance between the two set of points \a this and \a other.
1394  * \sa DataArrayDouble::findClosestTupleId
1395  */
1396 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1397 {
1398   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1399   int nbOfCompo(getNumberOfComponents());
1400   int otherNbTuples(other->getNumberOfTuples());
1401   const double *thisPt(begin()),*otherPt(other->begin());
1402   const int *part1Pt(part1->begin());
1403   double ret=std::numeric_limits<double>::max();
1404   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1405     {
1406       double tmp(0.);
1407       for(int j=0;j<nbOfCompo;j++)
1408         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1409       if(tmp<ret)
1410         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1411     }
1412   return sqrt(ret);
1413 }
1414
1415 /*!
1416  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1417  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1418  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1419  *
1420  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1421  * \sa DataArrayDouble::minimalDistanceTo
1422  */
1423 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1424 {
1425   if(!other)
1426     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1427   checkAllocated(); other->checkAllocated();
1428   int nbOfCompo=getNumberOfComponents();
1429   if(nbOfCompo!=other->getNumberOfComponents())
1430     {
1431       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1432       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1433       throw INTERP_KERNEL::Exception(oss.str().c_str());
1434     }
1435   int nbOfTuples=other->getNumberOfTuples();
1436   int thisNbOfTuples=getNumberOfTuples();
1437   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1438   double bounds[6];
1439   getMinMaxPerComponent(bounds);
1440   switch(nbOfCompo)
1441   {
1442     case 3:
1443       {
1444         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1445         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1446         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1447         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1448         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1449         break;
1450       }
1451     case 2:
1452       {
1453         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1454         double delta=std::max(xDelta,yDelta);
1455         double characSize=sqrt(delta/(double)thisNbOfTuples);
1456         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1457         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1458         break;
1459       }
1460     case 1:
1461       {
1462         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1463         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1464         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1465         break;
1466       }
1467     default:
1468       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1469   }
1470   return ret.retn();
1471 }
1472
1473 /*!
1474  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1475  * 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
1476  * how many bounding boxes in \a otherBBoxFrmt.
1477  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1478  *
1479  * \param [in] otherBBoxFrmt - It is an array .
1480  * \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.
1481  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1482  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1483  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1484  */
1485 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1486 {
1487   if(!otherBBoxFrmt)
1488     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1489   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1490     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1491   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1492   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1493     {
1494       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1495       throw INTERP_KERNEL::Exception(oss.str().c_str());
1496     }
1497   if(nbOfComp%2!=0)
1498     {
1499       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1500       throw INTERP_KERNEL::Exception(oss.str().c_str());
1501     }
1502   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1503   const double *thisBBPtr(begin());
1504   int *retPtr(ret->getPointer());
1505   switch(nbOfComp/2)
1506   {
1507     case 3:
1508       {
1509         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1510         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1511           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1512         break;
1513       }
1514     case 2:
1515       {
1516         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1517         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1518           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1519         break;
1520       }
1521     case 1:
1522       {
1523         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1524         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1525           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1526         break;
1527       }
1528     default:
1529       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1530   }
1531
1532   return ret.retn();
1533 }
1534
1535 /*!
1536  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1537  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1538  * space. The distance between tuples is computed using norm2. If several tuples are
1539  * not far each from other than \a prec, only one of them remains in the result
1540  * array. The order of tuples in the result array is same as in \a this one except
1541  * that coincident tuples are excluded.
1542  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1543  *              considered not coincident.
1544  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1545  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1546  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1547  *          is to delete using decrRef() as it is no more needed.
1548  *  \throw If \a this is not allocated.
1549  *  \throw If the number of components is not in [1,2,3,4].
1550  *
1551  *  \if ENABLE_EXAMPLES
1552  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1553  *  \endif
1554  */
1555 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1556 {
1557   checkAllocated();
1558   DataArrayInt *c0=0,*cI0=0;
1559   findCommonTuples(prec,limitTupleId,c0,cI0);
1560   MCAuto<DataArrayInt> c(c0),cI(cI0);
1561   int newNbOfTuples=-1;
1562   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1563   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1564 }
1565
1566 /*!
1567  * Copy all components in a specified order from another DataArrayDouble.
1568  * Both numerical and textual data is copied. The number of tuples in \a this and
1569  * the other array can be different.
1570  *  \param [in] a - the array to copy data from.
1571  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1572  *              to be copied.
1573  *  \throw If \a a is NULL.
1574  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1575  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1576  *
1577  *  \if ENABLE_EXAMPLES
1578  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1579  *  \endif
1580  */
1581 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1582 {
1583   if(!a)
1584     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1585   checkAllocated();
1586   copyPartOfStringInfoFrom2(compoIds,*a);
1587   std::size_t partOfCompoSz=compoIds.size();
1588   int nbOfCompo=getNumberOfComponents();
1589   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1590   const double *ac=a->getConstPointer();
1591   double *nc=getPointer();
1592   for(int i=0;i<nbOfTuples;i++)
1593     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1594       nc[nbOfCompo*i+compoIds[j]]=*ac;
1595 }
1596
1597 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1598 {
1599   if(newArray!=arrayToSet)
1600     {
1601       if(arrayToSet)
1602         arrayToSet->decrRef();
1603       arrayToSet=newArray;
1604       if(arrayToSet)
1605         arrayToSet->incrRef();
1606     }
1607 }
1608
1609 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1610 {
1611   if(!other)
1612     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1613   if(getNumberOfComponents()!=other->getNumberOfComponents())
1614     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1615   _mem.insertAtTheEnd(other->begin(),other->end());
1616 }
1617
1618 /*!
1619  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1620  * is thrown.
1621  * \throw If zero is found in \a this array.
1622  */
1623 void DataArrayDouble::checkNoNullValues() const
1624 {
1625   const double *tmp=getConstPointer();
1626   std::size_t nbOfElems=getNbOfElems();
1627   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1628   if(where!=tmp+nbOfElems)
1629     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1630 }
1631
1632 /*!
1633  * Computes minimal and maximal value in each component. An output array is filled
1634  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1635  * enough memory before calling this method.
1636  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1637  *               It is filled as follows:<br>
1638  *               \a bounds[0] = \c min_of_component_0 <br>
1639  *               \a bounds[1] = \c max_of_component_0 <br>
1640  *               \a bounds[2] = \c min_of_component_1 <br>
1641  *               \a bounds[3] = \c max_of_component_1 <br>
1642  *               ...
1643  */
1644 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1645 {
1646   checkAllocated();
1647   int dim=getNumberOfComponents();
1648   for (int idim=0; idim<dim; idim++)
1649     {
1650       bounds[idim*2]=std::numeric_limits<double>::max();
1651       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1652     } 
1653   const double *ptr=getConstPointer();
1654   int nbOfTuples=getNumberOfTuples();
1655   for(int i=0;i<nbOfTuples;i++)
1656     {
1657       for(int idim=0;idim<dim;idim++)
1658         {
1659           if(bounds[idim*2]>ptr[i*dim+idim])
1660             {
1661               bounds[idim*2]=ptr[i*dim+idim];
1662             }
1663           if(bounds[idim*2+1]<ptr[i*dim+idim])
1664             {
1665               bounds[idim*2+1]=ptr[i*dim+idim];
1666             }
1667         }
1668     }
1669 }
1670
1671 /*!
1672  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1673  * to store both the min and max per component of each tuples. 
1674  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1675  *
1676  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1677  *
1678  * \throw If \a this is not allocated yet.
1679  */
1680 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1681 {
1682   checkAllocated();
1683   const double *dataPtr=getConstPointer();
1684   int nbOfCompo=getNumberOfComponents();
1685   int nbTuples=getNumberOfTuples();
1686   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1687   bbox->alloc(nbTuples,2*nbOfCompo);
1688   double *bboxPtr=bbox->getPointer();
1689   for(int i=0;i<nbTuples;i++)
1690     {
1691       for(int j=0;j<nbOfCompo;j++)
1692         {
1693           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1694           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1695         }
1696     }
1697   return bbox.retn();
1698 }
1699
1700 /*!
1701  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1702  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1703  * 
1704  * \param [in] other a DataArrayDouble having same number of components than \a this.
1705  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1706  * \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.
1707  *             \a cI allows to extract information in \a c.
1708  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1709  *
1710  * \throw In case of:
1711  *  - \a this is not allocated
1712  *  - \a other is not allocated or null
1713  *  - \a this and \a other do not have the same number of components
1714  *  - if number of components of \a this is not in [1,2,3]
1715  *
1716  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1717  */
1718 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1719 {
1720   if(!other)
1721     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1722   checkAllocated();
1723   other->checkAllocated();
1724   int nbOfCompo=getNumberOfComponents();
1725   int otherNbOfCompo=other->getNumberOfComponents();
1726   if(nbOfCompo!=otherNbOfCompo)
1727     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1728   int nbOfTuplesOther=other->getNumberOfTuples();
1729   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1730   switch(nbOfCompo)
1731   {
1732     case 3:
1733       {
1734         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1735         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1736         break;
1737       }
1738     case 2:
1739       {
1740         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1741         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1742         break;
1743       }
1744     case 1:
1745       {
1746         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1747         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1748         break;
1749       }
1750     default:
1751       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1752   }
1753   c=cArr.retn(); cI=cIArr.retn();
1754 }
1755
1756 /*!
1757  * 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
1758  * around origin of 'radius' 1.
1759  * 
1760  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1761  */
1762 void DataArrayDouble::recenterForMaxPrecision(double eps)
1763 {
1764   checkAllocated();
1765   int dim=getNumberOfComponents();
1766   std::vector<double> bounds(2*dim);
1767   getMinMaxPerComponent(&bounds[0]);
1768   for(int i=0;i<dim;i++)
1769     {
1770       double delta=bounds[2*i+1]-bounds[2*i];
1771       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1772       if(delta>eps)
1773         applyLin(1./delta,-offset/delta,i);
1774       else
1775         applyLin(1.,-offset,i);
1776     }
1777 }
1778
1779 /*!
1780  * Returns the maximal value and all its locations within \a this one-dimensional array.
1781  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1782  *               tuples holding the maximal value. The caller is to delete it using
1783  *               decrRef() as it is no more needed.
1784  *  \return double - the maximal value among all values of \a this array.
1785  *  \throw If \a this->getNumberOfComponents() != 1
1786  *  \throw If \a this->getNumberOfTuples() < 1
1787  */
1788 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1789 {
1790   int tmp;
1791   tupleIds=0;
1792   double ret=getMaxValue(tmp);
1793   tupleIds=findIdsInRange(ret,ret);
1794   return ret;
1795 }
1796
1797 /*!
1798  * Returns the minimal value and all its locations within \a this one-dimensional array.
1799  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1800  *               tuples holding the minimal value. The caller is to delete it using
1801  *               decrRef() as it is no more needed.
1802  *  \return double - the minimal value among all values of \a this array.
1803  *  \throw If \a this->getNumberOfComponents() != 1
1804  *  \throw If \a this->getNumberOfTuples() < 1
1805  */
1806 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1807 {
1808   int tmp;
1809   tupleIds=0;
1810   double ret=getMinValue(tmp);
1811   tupleIds=findIdsInRange(ret,ret);
1812   return ret;
1813 }
1814
1815 /*!
1816  * 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.
1817  * This method only works for single component array.
1818  *
1819  * \return a value in [ 0, \c this->getNumberOfTuples() )
1820  *
1821  * \throw If \a this is not allocated
1822  *
1823  */
1824 int DataArrayDouble::count(double value, double eps) const
1825 {
1826   int ret=0;
1827   checkAllocated();
1828   if(getNumberOfComponents()!=1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1830   const double *vals=begin();
1831   int nbOfTuples=getNumberOfTuples();
1832   for(int i=0;i<nbOfTuples;i++,vals++)
1833     if(fabs(*vals-value)<=eps)
1834       ret++;
1835   return ret;
1836 }
1837
1838 /*!
1839  * Returns the average value of \a this one-dimensional array.
1840  *  \return double - the average value over all values of \a this array.
1841  *  \throw If \a this->getNumberOfComponents() != 1
1842  *  \throw If \a this->getNumberOfTuples() < 1
1843  */
1844 double DataArrayDouble::getAverageValue() const
1845 {
1846   if(getNumberOfComponents()!=1)
1847     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1848   int nbOfTuples=getNumberOfTuples();
1849   if(nbOfTuples<=0)
1850     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1851   const double *vals=getConstPointer();
1852   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1853   return ret/nbOfTuples;
1854 }
1855
1856 /*!
1857  * Returns the Euclidean norm of the vector defined by \a this array.
1858  *  \return double - the value of the Euclidean norm, i.e.
1859  *          the square root of the inner product of vector.
1860  *  \throw If \a this is not allocated.
1861  */
1862 double DataArrayDouble::norm2() const
1863 {
1864   checkAllocated();
1865   double ret=0.;
1866   std::size_t nbOfElems=getNbOfElems();
1867   const double *pt=getConstPointer();
1868   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1869     ret+=(*pt)*(*pt);
1870   return sqrt(ret);
1871 }
1872
1873 /*!
1874  * Returns the maximum norm of the vector defined by \a this array.
1875  * This method works even if the number of components is diferent from one.
1876  * If the number of elements in \a this is 0, -1. is returned.
1877  *  \return double - the value of the maximum norm, i.e.
1878  *          the maximal absolute value among values of \a this array (whatever its number of components).
1879  *  \throw If \a this is not allocated.
1880  */
1881 double DataArrayDouble::normMax() const
1882 {
1883   checkAllocated();
1884   double ret(-1.);
1885   std::size_t nbOfElems(getNbOfElems());
1886   const double *pt(getConstPointer());
1887   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1888     {
1889       double val(std::abs(*pt));
1890       if(val>ret)
1891         ret=val;
1892     }
1893   return ret;
1894 }
1895
1896 /*!
1897  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1898  * This method works even if the number of components is diferent from one.
1899  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1900  *  \return double - the value of the minimum norm, i.e.
1901  *          the minimal absolute value among values of \a this array (whatever its number of components).
1902  *  \throw If \a this is not allocated.
1903  */
1904 double DataArrayDouble::normMin() const
1905 {
1906   checkAllocated();
1907   double ret(std::numeric_limits<double>::max());
1908   std::size_t nbOfElems(getNbOfElems());
1909   const double *pt(getConstPointer());
1910   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1911     {
1912       double val(std::abs(*pt));
1913       if(val<ret)
1914         ret=val;
1915     }
1916   return ret;
1917 }
1918
1919 /*!
1920  * Accumulates values of each component of \a this array.
1921  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1922  *         by the caller, that is filled by this method with sum value for each
1923  *         component.
1924  *  \throw If \a this is not allocated.
1925  */
1926 void DataArrayDouble::accumulate(double *res) const
1927 {
1928   checkAllocated();
1929   const double *ptr=getConstPointer();
1930   int nbTuple=getNumberOfTuples();
1931   int nbComps=getNumberOfComponents();
1932   std::fill(res,res+nbComps,0.);
1933   for(int i=0;i<nbTuple;i++)
1934     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1935 }
1936
1937 /*!
1938  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1939  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1940  *
1941  *
1942  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1943  * \a tupleEnd. If not an exception will be thrown.
1944  *
1945  * \param [in] tupleBg start pointer (included) of input external tuple
1946  * \param [in] tupleEnd end pointer (not included) of input external tuple
1947  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1948  * \return the min distance.
1949  * \sa MEDCouplingUMesh::distanceToPoint
1950  */
1951 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1952 {
1953   checkAllocated();
1954   int nbTuple=getNumberOfTuples();
1955   int nbComps=getNumberOfComponents();
1956   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1957     { 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()); }
1958   if(nbTuple==0)
1959     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1960   double ret0=std::numeric_limits<double>::max();
1961   tupleId=-1;
1962   const double *work=getConstPointer();
1963   for(int i=0;i<nbTuple;i++)
1964     {
1965       double val=0.;
1966       for(int j=0;j<nbComps;j++,work++) 
1967         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1968       if(val>=ret0)
1969         continue;
1970       else
1971         { ret0=val; tupleId=i; }
1972     }
1973   return sqrt(ret0);
1974 }
1975
1976 /*!
1977  * Accumulate values of the given component of \a this array.
1978  *  \param [in] compId - the index of the component of interest.
1979  *  \return double - a sum value of \a compId-th component.
1980  *  \throw If \a this is not allocated.
1981  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1982  *         not respected.
1983  */
1984 double DataArrayDouble::accumulate(int compId) const
1985 {
1986   checkAllocated();
1987   const double *ptr=getConstPointer();
1988   int nbTuple=getNumberOfTuples();
1989   int nbComps=getNumberOfComponents();
1990   if(compId<0 || compId>=nbComps)
1991     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1992   double ret=0.;
1993   for(int i=0;i<nbTuple;i++)
1994     ret+=ptr[i*nbComps+compId];
1995   return ret;
1996 }
1997
1998 /*!
1999  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
2000  * The returned array will have same number of components than \a this and number of tuples equal to
2001  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
2002  *
2003  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
2004  * 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.
2005  *
2006  * \param [in] bgOfIndex - begin (included) of the input index array.
2007  * \param [in] endOfIndex - end (excluded) of the input index array.
2008  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
2009  * 
2010  * \throw If bgOfIndex or end is NULL.
2011  * \throw If input index array is not ascendingly sorted.
2012  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
2013  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
2014  */
2015 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
2016 {
2017   if(!bgOfIndex || !endOfIndex)
2018     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
2019   checkAllocated();
2020   int nbCompo=getNumberOfComponents();
2021   int nbOfTuples=getNumberOfTuples();
2022   int sz=(int)std::distance(bgOfIndex,endOfIndex);
2023   if(sz<1)
2024     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
2025   sz--;
2026   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
2027   const int *w=bgOfIndex;
2028   if(*w<0 || *w>=nbOfTuples)
2029     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
2030   const double *srcPt=begin()+(*w)*nbCompo;
2031   double *tmp=ret->getPointer();
2032   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
2033     {
2034       std::fill(tmp,tmp+nbCompo,0.);
2035       if(w[1]>=w[0])
2036         {
2037           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
2038             {
2039               if(j>=0 && j<nbOfTuples)
2040                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
2041               else
2042                 {
2043                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2044                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2045                 }
2046             }
2047         }
2048       else
2049         {
2050           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2051           throw INTERP_KERNEL::Exception(oss.str().c_str());
2052         }
2053     }
2054   ret->copyStringInfoFrom(*this);
2055   return ret.retn();
2056 }
2057
2058 /*!
2059  * 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.
2060  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
2061  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
2062  *
2063  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2064  */
2065 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2066 {
2067   checkAllocated();
2068   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2069   int nbOfTuple(getNumberOfTuples());
2070   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2071   double *ptr(ret->getPointer());
2072   ptr[0]=0.;
2073   const double *thisPtr(begin());
2074   for(int i=0;i<nbOfTuple;i++)
2075     ptr[i+1]=ptr[i]+thisPtr[i];
2076   return ret;
2077 }
2078
2079 /*!
2080  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2081  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2082  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2083  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2084  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2085  *          is to delete this array using decrRef() as it is no more needed. The array
2086  *          does not contain any textual info on components.
2087  *  \throw If \a this->getNumberOfComponents() != 2.
2088  * \sa fromCartToPolar
2089  */
2090 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2091 {
2092   checkAllocated();
2093   int nbOfComp(getNumberOfComponents());
2094   if(nbOfComp!=2)
2095     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2096   int nbOfTuple(getNumberOfTuples());
2097   DataArrayDouble *ret(DataArrayDouble::New());
2098   ret->alloc(nbOfTuple,2);
2099   double *w(ret->getPointer());
2100   const double *wIn(getConstPointer());
2101   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2102     {
2103       w[0]=wIn[0]*cos(wIn[1]);
2104       w[1]=wIn[0]*sin(wIn[1]);
2105     }
2106   return ret;
2107 }
2108
2109 /*!
2110  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2111  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2112  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2113  * the Cylindrical CS.
2114  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2115  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2116  *          on the third component is copied from \a this array. The caller
2117  *          is to delete this array using decrRef() as it is no more needed. 
2118  *  \throw If \a this->getNumberOfComponents() != 3.
2119  * \sa fromCartToCyl
2120  */
2121 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2122 {
2123   checkAllocated();
2124   int nbOfComp(getNumberOfComponents());
2125   if(nbOfComp!=3)
2126     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2127   int nbOfTuple(getNumberOfTuples());
2128   DataArrayDouble *ret(DataArrayDouble::New());
2129   ret->alloc(getNumberOfTuples(),3);
2130   double *w(ret->getPointer());
2131   const double *wIn(getConstPointer());
2132   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2133     {
2134       w[0]=wIn[0]*cos(wIn[1]);
2135       w[1]=wIn[0]*sin(wIn[1]);
2136       w[2]=wIn[2];
2137     }
2138   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2139   return ret;
2140 }
2141
2142 /*!
2143  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2144  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2145  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2146  * point in the Cylindrical CS.
2147  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2148  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2149  *          on the third component is copied from \a this array. The caller
2150  *          is to delete this array using decrRef() as it is no more needed.
2151  *  \throw If \a this->getNumberOfComponents() != 3.
2152  * \sa fromCartToSpher
2153  */
2154 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2155 {
2156   checkAllocated();
2157   int nbOfComp(getNumberOfComponents());
2158   if(nbOfComp!=3)
2159     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2160   int nbOfTuple(getNumberOfTuples());
2161   DataArrayDouble *ret(DataArrayDouble::New());
2162   ret->alloc(getNumberOfTuples(),3);
2163   double *w(ret->getPointer());
2164   const double *wIn(getConstPointer());
2165   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2166     {
2167       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2168       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2169       w[2]=wIn[0]*cos(wIn[1]);
2170     }
2171   return ret;
2172 }
2173
2174 /*!
2175  * 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.
2176  * 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.
2177  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2178  *
2179  * \param [in] atOfThis - The axis type of \a this.
2180  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2181  */
2182 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2183 {
2184   checkAllocated();
2185   int nbOfComp(getNumberOfComponents());
2186   MCAuto<DataArrayDouble> ret;
2187   switch(atOfThis)
2188     {
2189     case AX_CART:
2190       ret=deepCopy();
2191     case AX_CYL:
2192       if(nbOfComp==3)
2193         {
2194           ret=fromCylToCart();
2195           break;
2196         }
2197       if(nbOfComp==2)
2198         {
2199           ret=fromPolarToCart();
2200           break;
2201         }
2202       else
2203         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2204     case AX_SPHER:
2205       if(nbOfComp==3)
2206         {
2207           ret=fromSpherToCart();
2208           break;
2209         }
2210       if(nbOfComp==2)
2211         {
2212           ret=fromPolarToCart();
2213           break;
2214         }
2215       else
2216         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2217     default:
2218       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2219     }
2220   ret->copyStringInfoFrom(*this);
2221   return ret.retn();
2222 }
2223
2224 /*!
2225  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2226  * This method expects that \a this has exactly 2 components.
2227  * \sa fromPolarToCart
2228  */
2229 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2230 {
2231   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2232   checkAllocated();
2233   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2234   if(nbOfComp!=2)
2235     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2236   ret->alloc(nbTuples,2);
2237   double *retPtr(ret->getPointer());
2238   const double *ptr(begin());
2239   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2240     {
2241       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2242       retPtr[1]=atan2(ptr[1],ptr[0]);
2243     }
2244   return ret.retn();
2245 }
2246
2247 /*!
2248  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2249  * This method expects that \a this has exactly 3 components.
2250  * \sa fromCylToCart
2251  */
2252 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2253 {
2254   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2255   checkAllocated();
2256   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2257   if(nbOfComp!=3)
2258     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2259   ret->alloc(nbTuples,3);
2260   double *retPtr(ret->getPointer());
2261   const double *ptr(begin());
2262   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2263     {
2264       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2265       retPtr[1]=atan2(ptr[1],ptr[0]);
2266       retPtr[2]=ptr[2];
2267     }
2268   return ret.retn();
2269 }
2270
2271 /*!
2272  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2273  * \sa fromSpherToCart
2274  */
2275 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2276 {
2277   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2278   checkAllocated();
2279   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2280   if(nbOfComp!=3)
2281     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2282   ret->alloc(nbTuples,3);
2283   double *retPtr(ret->getPointer());
2284   const double *ptr(begin());
2285   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2286     {
2287       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2288       retPtr[1]=acos(ptr[2]/retPtr[0]);
2289       retPtr[2]=atan2(ptr[1],ptr[0]);
2290     }
2291   return ret.retn();
2292 }
2293
2294 /*!
2295  * 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.
2296  * This method expects that \a this has exactly 3 components.
2297  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2298  */
2299 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2300 {
2301   if(!coords)
2302     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2303   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2304   checkAllocated(); coords->checkAllocated();
2305   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2306   if(nbOfComp!=3)
2307     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2308   if(coords->getNumberOfComponents()!=3)
2309     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2310   if(coords->getNumberOfTuples()!=nbTuples)
2311     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2312   ret->alloc(nbTuples,nbOfComp);
2313   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2314   if(magOfVect<1e-12)
2315     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2316   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2317   const double *coo(coords->begin()),*vectField(begin());
2318   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2319   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2320     {
2321       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2322       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];
2323       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2324       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2325       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];
2326       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2327       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2328       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2329     }
2330   ret->copyStringInfoFrom(*this);
2331   return ret.retn();
2332 }
2333
2334 /*!
2335  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2336  * array contating 6 components.
2337  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2338  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2339  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2340  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2341  *  \throw If \a this->getNumberOfComponents() != 6.
2342  */
2343 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2344 {
2345   checkAllocated();
2346   int nbOfComp(getNumberOfComponents());
2347   if(nbOfComp!=6)
2348     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2349   DataArrayDouble *ret=DataArrayDouble::New();
2350   int nbOfTuple=getNumberOfTuples();
2351   ret->alloc(nbOfTuple,1);
2352   const double *src=getConstPointer();
2353   double *dest=ret->getPointer();
2354   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2355     *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];
2356   return ret;
2357 }
2358
2359 /*!
2360  * Computes the determinant of every square matrix defined by the tuple of \a this
2361  * array, which contains either 4, 6 or 9 components. The case of 6 components
2362  * corresponds to that of the upper triangular matrix.
2363  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2364  *          is the determinant of matrix of the corresponding tuple of \a this array.
2365  *          The caller is to delete this result array using decrRef() as it is no more
2366  *          needed. 
2367  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2368  */
2369 DataArrayDouble *DataArrayDouble::determinant() const
2370 {
2371   checkAllocated();
2372   DataArrayDouble *ret=DataArrayDouble::New();
2373   int nbOfTuple=getNumberOfTuples();
2374   ret->alloc(nbOfTuple,1);
2375   const double *src=getConstPointer();
2376   double *dest=ret->getPointer();
2377   switch(getNumberOfComponents())
2378   {
2379     case 6:
2380       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2381         *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];
2382       return ret;
2383     case 4:
2384       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2385         *dest=src[0]*src[3]-src[1]*src[2];
2386       return ret;
2387     case 9:
2388       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2389         *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];
2390       return ret;
2391     default:
2392       ret->decrRef();
2393       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2394   }
2395 }
2396
2397 /*!
2398  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2399  * \a this array, which contains 6 components.
2400  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2401  *          components, whose each tuple contains the eigenvalues of the matrix of
2402  *          corresponding tuple of \a this array. 
2403  *          The caller is to delete this result array using decrRef() as it is no more
2404  *          needed. 
2405  *  \throw If \a this->getNumberOfComponents() != 6.
2406  */
2407 DataArrayDouble *DataArrayDouble::eigenValues() const
2408 {
2409   checkAllocated();
2410   int nbOfComp=getNumberOfComponents();
2411   if(nbOfComp!=6)
2412     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2413   DataArrayDouble *ret=DataArrayDouble::New();
2414   int nbOfTuple=getNumberOfTuples();
2415   ret->alloc(nbOfTuple,3);
2416   const double *src=getConstPointer();
2417   double *dest=ret->getPointer();
2418   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2419     INTERP_KERNEL::computeEigenValues6(src,dest);
2420   return ret;
2421 }
2422
2423 /*!
2424  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2425  * \a this array, which contains 6 components.
2426  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2427  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2428  *          corresponding tuple of \a this array.
2429  *          The caller is to delete this result array using decrRef() as it is no more
2430  *          needed.
2431  *  \throw If \a this->getNumberOfComponents() != 6.
2432  */
2433 DataArrayDouble *DataArrayDouble::eigenVectors() const
2434 {
2435   checkAllocated();
2436   int nbOfComp=getNumberOfComponents();
2437   if(nbOfComp!=6)
2438     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2439   DataArrayDouble *ret=DataArrayDouble::New();
2440   int nbOfTuple=getNumberOfTuples();
2441   ret->alloc(nbOfTuple,9);
2442   const double *src=getConstPointer();
2443   double *dest=ret->getPointer();
2444   for(int i=0;i<nbOfTuple;i++,src+=6)
2445     {
2446       double tmp[3];
2447       INTERP_KERNEL::computeEigenValues6(src,tmp);
2448       for(int j=0;j<3;j++,dest+=3)
2449         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2450     }
2451   return ret;
2452 }
2453
2454 /*!
2455  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2456  * array, which contains either 4, 6 or 9 components. The case of 6 components
2457  * corresponds to that of the upper triangular matrix.
2458  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2459  *          same number of components as \a this one, whose each tuple is the inverse
2460  *          matrix of the matrix of corresponding tuple of \a this array. 
2461  *          The caller is to delete this result array using decrRef() as it is no more
2462  *          needed. 
2463  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2464  */
2465 DataArrayDouble *DataArrayDouble::inverse() const
2466 {
2467   checkAllocated();
2468   int nbOfComp=getNumberOfComponents();
2469   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2470     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2471   DataArrayDouble *ret=DataArrayDouble::New();
2472   int nbOfTuple=getNumberOfTuples();
2473   ret->alloc(nbOfTuple,nbOfComp);
2474   const double *src=getConstPointer();
2475   double *dest=ret->getPointer();
2476   if(nbOfComp==6)
2477     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2478       {
2479         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];
2480         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2481         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2482         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2483         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2484         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2485         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2486       }
2487   else if(nbOfComp==4)
2488     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2489       {
2490         double det=src[0]*src[3]-src[1]*src[2];
2491         dest[0]=src[3]/det;
2492         dest[1]=-src[1]/det;
2493         dest[2]=-src[2]/det;
2494         dest[3]=src[0]/det;
2495       }
2496   else
2497     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2498       {
2499         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];
2500         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2501         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2502         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2503         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2504         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2505         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2506         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2507         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2508         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2509       }
2510   return ret;
2511 }
2512
2513 /*!
2514  * Computes the trace of every matrix defined by the tuple of \a this
2515  * array, which contains either 4, 6 or 9 components. The case of 6 components
2516  * corresponds to that of the upper triangular matrix.
2517  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2518  *          1 component, whose each tuple is the trace of
2519  *          the matrix of corresponding tuple of \a this array. 
2520  *          The caller is to delete this result array using decrRef() as it is no more
2521  *          needed. 
2522  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2523  */
2524 DataArrayDouble *DataArrayDouble::trace() const
2525 {
2526   checkAllocated();
2527   int nbOfComp=getNumberOfComponents();
2528   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2529     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2530   DataArrayDouble *ret=DataArrayDouble::New();
2531   int nbOfTuple=getNumberOfTuples();
2532   ret->alloc(nbOfTuple,1);
2533   const double *src=getConstPointer();
2534   double *dest=ret->getPointer();
2535   if(nbOfComp==6)
2536     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2537       *dest=src[0]+src[1]+src[2];
2538   else if(nbOfComp==4)
2539     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2540       *dest=src[0]+src[3];
2541   else
2542     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2543       *dest=src[0]+src[4]+src[8];
2544   return ret;
2545 }
2546
2547 /*!
2548  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2549  * \a this array, which contains 6 components.
2550  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2551  *          same number of components and tuples as \a this array.
2552  *          The caller is to delete this result array using decrRef() as it is no more
2553  *          needed.
2554  *  \throw If \a this->getNumberOfComponents() != 6.
2555  */
2556 DataArrayDouble *DataArrayDouble::deviator() const
2557 {
2558   checkAllocated();
2559   int nbOfComp=getNumberOfComponents();
2560   if(nbOfComp!=6)
2561     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2562   DataArrayDouble *ret=DataArrayDouble::New();
2563   int nbOfTuple=getNumberOfTuples();
2564   ret->alloc(nbOfTuple,6);
2565   const double *src=getConstPointer();
2566   double *dest=ret->getPointer();
2567   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2568     {
2569       double tr=(src[0]+src[1]+src[2])/3.;
2570       dest[0]=src[0]-tr;
2571       dest[1]=src[1]-tr;
2572       dest[2]=src[2]-tr;
2573       dest[3]=src[3];
2574       dest[4]=src[4];
2575       dest[5]=src[5];
2576     }
2577   return ret;
2578 }
2579
2580 /*!
2581  * Computes the magnitude of every vector defined by the tuple of
2582  * \a this array.
2583  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2584  *          same number of tuples as \a this array and one component.
2585  *          The caller is to delete this result array using decrRef() as it is no more
2586  *          needed.
2587  *  \throw If \a this is not allocated.
2588  */
2589 DataArrayDouble *DataArrayDouble::magnitude() const
2590 {
2591   checkAllocated();
2592   int nbOfComp=getNumberOfComponents();
2593   DataArrayDouble *ret=DataArrayDouble::New();
2594   int nbOfTuple=getNumberOfTuples();
2595   ret->alloc(nbOfTuple,1);
2596   const double *src=getConstPointer();
2597   double *dest=ret->getPointer();
2598   for(int i=0;i<nbOfTuple;i++,dest++)
2599     {
2600       double sum=0.;
2601       for(int j=0;j<nbOfComp;j++,src++)
2602         sum+=(*src)*(*src);
2603       *dest=sqrt(sum);
2604     }
2605   return ret;
2606 }
2607
2608 /*!
2609  * Computes for each tuple the sum of number of components values in the tuple and return it.
2610  * 
2611  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2612  *          same number of tuples as \a this array and one component.
2613  *          The caller is to delete this result array using decrRef() as it is no more
2614  *          needed.
2615  *  \throw If \a this is not allocated.
2616  */
2617 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2618 {
2619   checkAllocated();
2620   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2621   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2622   ret->alloc(nbOfTuple,1);
2623   const double *src(getConstPointer());
2624   double *dest(ret->getPointer());
2625   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2626     *dest=std::accumulate(src,src+nbOfComp,0.);
2627   return ret.retn();
2628 }
2629
2630 /*!
2631  * Computes the maximal value within every tuple of \a this array.
2632  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2633  *          same number of tuples as \a this array and one component.
2634  *          The caller is to delete this result array using decrRef() as it is no more
2635  *          needed.
2636  *  \throw If \a this is not allocated.
2637  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2638  */
2639 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2640 {
2641   checkAllocated();
2642   int nbOfComp=getNumberOfComponents();
2643   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2644   int nbOfTuple=getNumberOfTuples();
2645   ret->alloc(nbOfTuple,1);
2646   const double *src=getConstPointer();
2647   double *dest=ret->getPointer();
2648   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2649     *dest=*std::max_element(src,src+nbOfComp);
2650   return ret.retn();
2651 }
2652
2653 /*!
2654  * Computes the maximal value within every tuple of \a this array and it returns the first component
2655  * id for each tuple that corresponds to the maximal value within the tuple.
2656  * 
2657  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2658  *          same number of tuples and only one component.
2659  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2660  *          same number of tuples as \a this array and one component.
2661  *          The caller is to delete this result array using decrRef() as it is no more
2662  *          needed.
2663  *  \throw If \a this is not allocated.
2664  *  \sa DataArrayDouble::maxPerTuple
2665  */
2666 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2667 {
2668   checkAllocated();
2669   int nbOfComp=getNumberOfComponents();
2670   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2671   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2672   int nbOfTuple=getNumberOfTuples();
2673   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2674   const double *src=getConstPointer();
2675   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2676   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2677     {
2678       const double *loc=std::max_element(src,src+nbOfComp);
2679       *dest=*loc;
2680       *dest1=(int)std::distance(src,loc);
2681     }
2682   compoIdOfMaxPerTuple=ret1.retn();
2683   return ret0.retn();
2684 }
2685
2686 /*!
2687  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2688  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2689  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2690  * \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)
2691  *
2692  * \warning use this method with care because it can leads to big amount of consumed memory !
2693  * 
2694  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2695  *
2696  * \throw If \a this is not allocated.
2697  *
2698  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2699  */
2700 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2701 {
2702   checkAllocated();
2703   int nbOfComp=getNumberOfComponents();
2704   int nbOfTuples=getNumberOfTuples();
2705   const double *inData=getConstPointer();
2706   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2707   ret->alloc(nbOfTuples*nbOfTuples,1);
2708   double *outData=ret->getPointer();
2709   for(int i=0;i<nbOfTuples;i++)
2710     {
2711       outData[i*nbOfTuples+i]=0.;
2712       for(int j=i+1;j<nbOfTuples;j++)
2713         {
2714           double dist=0.;
2715           for(int k=0;k<nbOfComp;k++)
2716             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2717           dist=sqrt(dist);
2718           outData[i*nbOfTuples+j]=dist;
2719           outData[j*nbOfTuples+i]=dist;
2720         }
2721     }
2722   return ret.retn();
2723 }
2724
2725 /*!
2726  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2727  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2728  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2729  * \n Output rectangular matrix is sorted along rows.
2730  * \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)
2731  *
2732  * \warning use this method with care because it can leads to big amount of consumed memory !
2733  * 
2734  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2735  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2736  *
2737  * \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.
2738  *
2739  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2740  */
2741 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2742 {
2743   if(!other)
2744     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2745   checkAllocated();
2746   other->checkAllocated();
2747   int nbOfComp=getNumberOfComponents();
2748   int otherNbOfComp=other->getNumberOfComponents();
2749   if(nbOfComp!=otherNbOfComp)
2750     {
2751       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2752       throw INTERP_KERNEL::Exception(oss.str().c_str());
2753     }
2754   int nbOfTuples=getNumberOfTuples();
2755   int otherNbOfTuples=other->getNumberOfTuples();
2756   const double *inData=getConstPointer();
2757   const double *inDataOther=other->getConstPointer();
2758   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2759   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2760   double *outData=ret->getPointer();
2761   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2762     {
2763       for(int j=0;j<nbOfTuples;j++)
2764         {
2765           double dist=0.;
2766           for(int k=0;k<nbOfComp;k++)
2767             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2768           dist=sqrt(dist);
2769           outData[i*nbOfTuples+j]=dist;
2770         }
2771     }
2772   return ret.retn();
2773 }
2774
2775 /*!
2776  * Sorts value within every tuple of \a this array.
2777  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2778  *              in descending order.
2779  *  \throw If \a this is not allocated.
2780  */
2781 void DataArrayDouble::sortPerTuple(bool asc)
2782 {
2783   checkAllocated();
2784   double *pt=getPointer();
2785   int nbOfTuple=getNumberOfTuples();
2786   int nbOfComp=getNumberOfComponents();
2787   if(asc)
2788     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2789       std::sort(pt,pt+nbOfComp);
2790   else
2791     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2792       std::sort(pt,pt+nbOfComp,std::greater<double>());
2793   declareAsNew();
2794 }
2795
2796 /*!
2797  * Converts every value of \a this array to its absolute value.
2798  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2799  * should be called instead.
2800  *
2801  * \throw If \a this is not allocated.
2802  * \sa DataArrayDouble::computeAbs
2803  */
2804 void DataArrayDouble::abs()
2805 {
2806   checkAllocated();
2807   double *ptr(getPointer());
2808   std::size_t nbOfElems(getNbOfElems());
2809   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2810   declareAsNew();
2811 }
2812
2813 /*!
2814  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2815  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2816  *
2817  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2818  *         same number of tuples and component as \a this array.
2819  *         The caller is to delete this result array using decrRef() as it is no more
2820  *         needed.
2821  * \throw If \a this is not allocated.
2822  * \sa DataArrayDouble::abs
2823  */
2824 DataArrayDouble *DataArrayDouble::computeAbs() const
2825 {
2826   checkAllocated();
2827   DataArrayDouble *newArr(DataArrayDouble::New());
2828   int nbOfTuples(getNumberOfTuples());
2829   int nbOfComp(getNumberOfComponents());
2830   newArr->alloc(nbOfTuples,nbOfComp);
2831   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2832   newArr->copyStringInfoFrom(*this);
2833   return newArr;
2834 }
2835
2836 /*!
2837  * Apply a linear function to a given component of \a this array, so that
2838  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2839  *  \param [in] a - the first coefficient of the function.
2840  *  \param [in] b - the second coefficient of the function.
2841  *  \param [in] compoId - the index of component to modify.
2842  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2843  */
2844 void DataArrayDouble::applyLin(double a, double b, int compoId)
2845 {
2846   checkAllocated();
2847   double *ptr(getPointer()+compoId);
2848   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2849   if(compoId<0 || compoId>=nbOfComp)
2850     {
2851       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2852       throw INTERP_KERNEL::Exception(oss.str().c_str());
2853     }
2854   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2855     *ptr=a*(*ptr)+b;
2856   declareAsNew();
2857 }
2858
2859 /*!
2860  * Apply a linear function to all elements of \a this array, so that
2861  * an element _x_ becomes \f$ a * x + b \f$.
2862  *  \param [in] a - the first coefficient of the function.
2863  *  \param [in] b - the second coefficient of the function.
2864  *  \throw If \a this is not allocated.
2865  */
2866 void DataArrayDouble::applyLin(double a, double b)
2867 {
2868   checkAllocated();
2869   double *ptr=getPointer();
2870   std::size_t nbOfElems=getNbOfElems();
2871   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2872     *ptr=a*(*ptr)+b;
2873   declareAsNew();
2874 }
2875
2876 /*!
2877  * Modify all elements of \a this array, so that
2878  * an element _x_ becomes \f$ numerator / x \f$.
2879  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2880  *           array, all elements processed before detection of the zero element remain
2881  *           modified.
2882  *  \param [in] numerator - the numerator used to modify array elements.
2883  *  \throw If \a this is not allocated.
2884  *  \throw If there is an element equal to 0.0 in \a this array.
2885  */
2886 void DataArrayDouble::applyInv(double numerator)
2887 {
2888   checkAllocated();
2889   double *ptr=getPointer();
2890   std::size_t nbOfElems=getNbOfElems();
2891   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2892     {
2893       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2894         {
2895           *ptr=numerator/(*ptr);
2896         }
2897       else
2898         {
2899           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2900           oss << " !";
2901           throw INTERP_KERNEL::Exception(oss.str().c_str());
2902         }
2903     }
2904   declareAsNew();
2905 }
2906
2907 /*!
2908  * Returns a full copy of \a this array except that sign of all elements is reversed.
2909  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2910  *          same number of tuples and component as \a this array.
2911  *          The caller is to delete this result array using decrRef() as it is no more
2912  *          needed.
2913  *  \throw If \a this is not allocated.
2914  */
2915 DataArrayDouble *DataArrayDouble::negate() const
2916 {
2917   checkAllocated();
2918   DataArrayDouble *newArr=DataArrayDouble::New();
2919   int nbOfTuples=getNumberOfTuples();
2920   int nbOfComp=getNumberOfComponents();
2921   newArr->alloc(nbOfTuples,nbOfComp);
2922   const double *cptr=getConstPointer();
2923   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2924   newArr->copyStringInfoFrom(*this);
2925   return newArr;
2926 }
2927
2928 /*!
2929  * Modify all elements of \a this array, so that
2930  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2931  * all values in \a this have to be >= 0 if val is \b not integer.
2932  *  \param [in] val - the value used to apply pow on all array elements.
2933  *  \throw If \a this is not allocated.
2934  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2935  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2936  *           modified.
2937  */
2938 void DataArrayDouble::applyPow(double val)
2939 {
2940   checkAllocated();
2941   double *ptr=getPointer();
2942   std::size_t nbOfElems=getNbOfElems();
2943   int val2=(int)val;
2944   bool isInt=((double)val2)==val;
2945   if(!isInt)
2946     {
2947       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2948         {
2949           if(*ptr>=0)
2950             *ptr=pow(*ptr,val);
2951           else
2952             {
2953               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2954               throw INTERP_KERNEL::Exception(oss.str().c_str());
2955             }
2956         }
2957     }
2958   else
2959     {
2960       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2961         *ptr=pow(*ptr,val2);
2962     }
2963   declareAsNew();
2964 }
2965
2966 /*!
2967  * Modify all elements of \a this array, so that
2968  * an element _x_ becomes \f$ val ^ x \f$.
2969  *  \param [in] val - the value used to apply pow on all array elements.
2970  *  \throw If \a this is not allocated.
2971  *  \throw If \a val < 0.
2972  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2973  *           array, all elements processed before detection of the zero element remain
2974  *           modified.
2975  */
2976 void DataArrayDouble::applyRPow(double val)
2977 {
2978   checkAllocated();
2979   if(val<0.)
2980     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2981   double *ptr=getPointer();
2982   std::size_t nbOfElems=getNbOfElems();
2983   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2984     *ptr=pow(val,*ptr);
2985   declareAsNew();
2986 }
2987
2988 /*!
2989  * Returns a new DataArrayDouble created from \a this one by applying \a
2990  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2991  * For more info see \ref MEDCouplingArrayApplyFunc
2992  *  \param [in] nbOfComp - number of components in the result array.
2993  *  \param [in] func - the \a FunctionToEvaluate declared as 
2994  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2995  *              where \a pos points to the first component of a tuple of \a this array
2996  *              and \a res points to the first component of a tuple of the result array.
2997  *              Note that length (number of components) of \a pos can differ from
2998  *              that of \a res.
2999  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3000  *          same number of tuples as \a this array.
3001  *          The caller is to delete this result array using decrRef() as it is no more
3002  *          needed.
3003  *  \throw If \a this is not allocated.
3004  *  \throw If \a func returns \a false.
3005  */
3006 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
3007 {
3008   checkAllocated();
3009   DataArrayDouble *newArr=DataArrayDouble::New();
3010   int nbOfTuples=getNumberOfTuples();
3011   int oldNbOfComp=getNumberOfComponents();
3012   newArr->alloc(nbOfTuples,nbOfComp);
3013   const double *ptr=getConstPointer();
3014   double *ptrToFill=newArr->getPointer();
3015   for(int i=0;i<nbOfTuples;i++)
3016     {
3017       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3018         {
3019           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3020           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3021           oss << ") : Evaluation of function failed !";
3022           newArr->decrRef();
3023           throw INTERP_KERNEL::Exception(oss.str().c_str());
3024         }
3025     }
3026   return newArr;
3027 }
3028
3029 /*!
3030  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3031  * tuple of \a this array. Textual data is not copied.
3032  * For more info see \ref MEDCouplingArrayApplyFunc1.
3033  *  \param [in] nbOfComp - number of components in the result array.
3034  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3035  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3036  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3037  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3038  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3039  *          same number of tuples as \a this array and \a nbOfComp components.
3040  *          The caller is to delete this result array using decrRef() as it is no more
3041  *          needed.
3042  *  \throw If \a this is not allocated.
3043  *  \throw If computing \a func fails.
3044  */
3045 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
3046 {
3047   INTERP_KERNEL::ExprParser expr(func);
3048   expr.parse();
3049   std::set<std::string> vars;
3050   expr.getTrueSetOfVars(vars);
3051   std::vector<std::string> varsV(vars.begin(),vars.end());
3052   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
3053 }
3054
3055 /*!
3056  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3057  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
3058  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
3059  *
3060  * For more info see \ref MEDCouplingArrayApplyFunc0.
3061  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3062  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3063  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3064  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3065  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3066  *          same number of tuples and components as \a this array.
3067  *          The caller is to delete this result array using decrRef() as it is no more
3068  *          needed.
3069  *  \sa applyFuncOnThis
3070  *  \throw If \a this is not allocated.
3071  *  \throw If computing \a func fails.
3072  */
3073 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3074 {
3075   int nbOfComp(getNumberOfComponents());
3076   if(nbOfComp<=0)
3077     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3078   checkAllocated();
3079   int nbOfTuples(getNumberOfTuples());
3080   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3081   newArr->alloc(nbOfTuples,nbOfComp);
3082   INTERP_KERNEL::ExprParser expr(func);
3083   expr.parse();
3084   std::set<std::string> vars;
3085   expr.getTrueSetOfVars(vars);
3086   if((int)vars.size()>1)
3087     {
3088       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 : ";
3089       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3090       throw INTERP_KERNEL::Exception(oss.str().c_str());
3091     }
3092   if(vars.empty())
3093     {
3094       expr.prepareFastEvaluator();
3095       newArr->rearrange(1);
3096       newArr->fillWithValue(expr.evaluateDouble());
3097       newArr->rearrange(nbOfComp);
3098       return newArr.retn();
3099     }
3100   std::vector<std::string> vars2(vars.begin(),vars.end());
3101   double buff,*ptrToFill(newArr->getPointer());
3102   const double *ptr(begin());
3103   std::vector<double> stck;
3104   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3105   expr.prepareFastEvaluator();
3106   if(!isSafe)
3107     {
3108       for(int i=0;i<nbOfTuples;i++)
3109         {
3110           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3111             {
3112               buff=*ptr;
3113               expr.evaluateDoubleInternal(stck);
3114               *ptrToFill=stck.back();
3115               stck.pop_back();
3116             }
3117         }
3118     }
3119   else
3120     {
3121       for(int i=0;i<nbOfTuples;i++)
3122         {
3123           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3124             {
3125               buff=*ptr;
3126               try
3127               {
3128                   expr.evaluateDoubleInternalSafe(stck);
3129               }
3130               catch(INTERP_KERNEL::Exception& e)
3131               {
3132                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3133                   oss << buff;
3134                   oss << ") : Evaluation of function failed !" << e.what();
3135                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3136               }
3137               *ptrToFill=stck.back();
3138               stck.pop_back();
3139             }
3140         }
3141     }
3142   return newArr.retn();
3143 }
3144
3145 /*!
3146  * This method is a non const method that modify the array in \a this.
3147  * This method only works on one component array. It means that function \a func must
3148  * contain at most one variable.
3149  * This method is a specialization of applyFunc method with one parameter on one component array.
3150  *
3151  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3152  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3153  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3154  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3155  *
3156  * \sa applyFunc
3157  */
3158 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3159 {
3160   int nbOfComp(getNumberOfComponents());
3161   if(nbOfComp<=0)
3162     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3163   checkAllocated();
3164   int nbOfTuples(getNumberOfTuples());
3165   INTERP_KERNEL::ExprParser expr(func);
3166   expr.parse();
3167   std::set<std::string> vars;
3168   expr.getTrueSetOfVars(vars);
3169   if((int)vars.size()>1)
3170     {
3171       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 : ";
3172       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3173       throw INTERP_KERNEL::Exception(oss.str().c_str());
3174     }
3175   if(vars.empty())
3176     {
3177       expr.prepareFastEvaluator();
3178       std::vector<std::string> compInfo(getInfoOnComponents());
3179       rearrange(1);
3180       fillWithValue(expr.evaluateDouble());
3181       rearrange(nbOfComp);
3182       setInfoOnComponents(compInfo);
3183       return ;
3184     }
3185   std::vector<std::string> vars2(vars.begin(),vars.end());
3186   double buff,*ptrToFill(getPointer());
3187   const double *ptr(begin());
3188   std::vector<double> stck;
3189   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3190   expr.prepareFastEvaluator();
3191   if(!isSafe)
3192     {
3193       for(int i=0;i<nbOfTuples;i++)
3194         {
3195           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3196             {
3197               buff=*ptr;
3198               expr.evaluateDoubleInternal(stck);
3199               *ptrToFill=stck.back();
3200               stck.pop_back();
3201             }
3202         }
3203     }
3204   else
3205     {
3206       for(int i=0;i<nbOfTuples;i++)
3207         {
3208           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3209             {
3210               buff=*ptr;
3211               try
3212               {
3213                   expr.evaluateDoubleInternalSafe(stck);
3214               }
3215               catch(INTERP_KERNEL::Exception& e)
3216               {
3217                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3218                   oss << buff;
3219                   oss << ") : Evaluation of function failed !" << e.what();
3220                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3221               }
3222               *ptrToFill=stck.back();
3223               stck.pop_back();
3224             }
3225         }
3226     }
3227 }
3228
3229 /*!
3230  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3231  * tuple of \a this array. Textual data is not copied.
3232  * For more info see \ref MEDCouplingArrayApplyFunc2.
3233  *  \param [in] nbOfComp - number of components in the result array.
3234  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3235  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3236  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3237  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3238  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3239  *          same number of tuples as \a this array.
3240  *          The caller is to delete this result array using decrRef() as it is no more
3241  *          needed.
3242  *  \throw If \a this is not allocated.
3243  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3244  *  \throw If computing \a func fails.
3245  */
3246 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3247 {
3248   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3249 }
3250
3251 /*!
3252  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3253  * tuple of \a this array. Textual data is not copied.
3254  * For more info see \ref MEDCouplingArrayApplyFunc3.
3255  *  \param [in] nbOfComp - number of components in the result array.
3256  *  \param [in] varsOrder - sequence of vars defining their order.
3257  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3258  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3259  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3260  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3261  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3262  *          same number of tuples as \a this array.
3263  *          The caller is to delete this result array using decrRef() as it is no more
3264  *          needed.
3265  *  \throw If \a this is not allocated.
3266  *  \throw If \a func contains vars not in \a varsOrder.
3267  *  \throw If computing \a func fails.
3268  */
3269 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3270 {
3271   if(nbOfComp<=0)
3272     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3273   std::vector<std::string> varsOrder2(varsOrder);
3274   int oldNbOfComp(getNumberOfComponents());
3275   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3276     varsOrder2.push_back(std::string());
3277   checkAllocated();
3278   int nbOfTuples(getNumberOfTuples());
3279   INTERP_KERNEL::ExprParser expr(func);
3280   expr.parse();
3281   std::set<std::string> vars;
3282   expr.getTrueSetOfVars(vars);
3283   if((int)vars.size()>oldNbOfComp)
3284     {
3285       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3286       oss << vars.size() << " variables : ";
3287       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3288       throw INTERP_KERNEL::Exception(oss.str().c_str());
3289     }
3290   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3291   newArr->alloc(nbOfTuples,nbOfComp);
3292   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3293   double *buffPtr(buff),*ptrToFill;
3294   std::vector<double> stck;
3295   for(int iComp=0;iComp<nbOfComp;iComp++)
3296     {
3297       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3298       expr.prepareFastEvaluator();
3299       const double *ptr(getConstPointer());
3300       ptrToFill=newArr->getPointer()+iComp;
3301       if(!isSafe)
3302         {
3303           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3304             {
3305               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3306               expr.evaluateDoubleInternal(stck);
3307               *ptrToFill=stck.back();
3308               stck.pop_back();
3309             }
3310         }
3311       else
3312         {
3313           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3314             {
3315               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3316               try
3317               {
3318                   expr.evaluateDoubleInternalSafe(stck);
3319                   *ptrToFill=stck.back();
3320                   stck.pop_back();
3321               }
3322               catch(INTERP_KERNEL::Exception& e)
3323               {
3324                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3325                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3326                   oss << ") : Evaluation of function failed !" << e.what();
3327                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3328               }
3329             }
3330         }
3331     }
3332   return newArr.retn();
3333 }
3334
3335 void DataArrayDouble::applyFuncFast32(const std::string& func)
3336 {
3337   checkAllocated();
3338   INTERP_KERNEL::ExprParser expr(func);
3339   expr.parse();
3340   char *funcStr=expr.compileX86();
3341   MYFUNCPTR funcPtr;
3342   *((void **)&funcPtr)=funcStr;//he he...
3343   //
3344   double *ptr=getPointer();
3345   int nbOfComp=getNumberOfComponents();
3346   int nbOfTuples=getNumberOfTuples();
3347   int nbOfElems=nbOfTuples*nbOfComp;
3348   for(int i=0;i<nbOfElems;i++,ptr++)
3349     *ptr=funcPtr(*ptr);
3350   declareAsNew();
3351 }
3352
3353 void DataArrayDouble::applyFuncFast64(const std::string& func)
3354 {
3355   checkAllocated();
3356   INTERP_KERNEL::ExprParser expr(func);
3357   expr.parse();
3358   char *funcStr=expr.compileX86_64();
3359   MYFUNCPTR funcPtr;
3360   *((void **)&funcPtr)=funcStr;//he he...
3361   //
3362   double *ptr=getPointer();
3363   int nbOfComp=getNumberOfComponents();
3364   int nbOfTuples=getNumberOfTuples();
3365   int nbOfElems=nbOfTuples*nbOfComp;
3366   for(int i=0;i<nbOfElems;i++,ptr++)
3367     *ptr=funcPtr(*ptr);
3368   declareAsNew();
3369 }
3370
3371 /*!
3372  * \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.
3373  */
3374 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3375 {
3376   checkAllocated();
3377   if(getNumberOfComponents()!=3)
3378     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3379   int nbTuples(getNumberOfTuples());
3380   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3381   ret->alloc(nbTuples,3);
3382   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3383   return ret;
3384 }
3385
3386 DataArrayDoubleIterator *DataArrayDouble::iterator()
3387 {
3388   return new DataArrayDoubleIterator(this);
3389 }
3390
3391 /*!
3392  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3393  * array whose values are within a given range. Textual data is not copied.
3394  *  \param [in] vmin - a lowest acceptable value (included).
3395  *  \param [in] vmax - a greatest acceptable value (included).
3396  *  \return DataArrayInt * - the new instance of DataArrayInt.
3397  *          The caller is to delete this result array using decrRef() as it is no more
3398  *          needed.
3399  *  \throw If \a this->getNumberOfComponents() != 1.
3400  *
3401  *  \sa DataArrayDouble::findIdsNotInRange
3402  *
3403  *  \if ENABLE_EXAMPLES
3404  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3405  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3406  *  \endif
3407  */
3408 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3409 {
3410   checkAllocated();
3411   if(getNumberOfComponents()!=1)
3412     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3413   const double *cptr(begin());
3414   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3415   int nbOfTuples(getNumberOfTuples());
3416   for(int i=0;i<nbOfTuples;i++,cptr++)
3417     if(*cptr>=vmin && *cptr<=vmax)
3418       ret->pushBackSilent(i);
3419   return ret.retn();
3420 }
3421
3422 /*!
3423  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3424  * array whose values are not within a given range. Textual data is not copied.
3425  *  \param [in] vmin - a lowest not acceptable value (excluded).
3426  *  \param [in] vmax - a greatest not acceptable value (excluded).
3427  *  \return DataArrayInt * - the new instance of DataArrayInt.
3428  *          The caller is to delete this result array using decrRef() as it is no more
3429  *          needed.
3430  *  \throw If \a this->getNumberOfComponents() != 1.
3431  *
3432  *  \sa DataArrayDouble::findIdsInRange
3433  */
3434 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3435 {
3436   checkAllocated();
3437   if(getNumberOfComponents()!=1)
3438     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3439   const double *cptr(begin());
3440   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3441   int nbOfTuples(getNumberOfTuples());
3442   for(int i=0;i<nbOfTuples;i++,cptr++)
3443     if(*cptr<vmin || *cptr>vmax)
3444       ret->pushBackSilent(i);
3445   return ret.retn();
3446 }
3447
3448 /*!
3449  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3450  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3451  * the number of component in the result array is same as that of each of given arrays.
3452  * Info on components is copied from the first of the given arrays. Number of components
3453  * in the given arrays must be  the same.
3454  *  \param [in] a1 - an array to include in the result array.
3455  *  \param [in] a2 - another array to include in the result array.
3456  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3457  *          The caller is to delete this result array using decrRef() as it is no more
3458  *          needed.
3459  *  \throw If both \a a1 and \a a2 are NULL.
3460  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3461  */
3462 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3463 {
3464   std::vector<const DataArrayDouble *> tmp(2);
3465   tmp[0]=a1; tmp[1]=a2;
3466   return Aggregate(tmp);
3467 }
3468
3469 /*!
3470  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3471  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3472  * the number of component in the result array is same as that of each of given arrays.
3473  * Info on components is copied from the first of the given arrays. Number of components
3474  * in the given arrays must be  the same.
3475  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3476  * not the object itself.
3477  *  \param [in] arr - a sequence of arrays to include in the result array.
3478  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3479  *          The caller is to delete this result array using decrRef() as it is no more
3480  *          needed.
3481  *  \throw If all arrays within \a arr are NULL.
3482  *  \throw If getNumberOfComponents() of arrays within \a arr.
3483  */
3484 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3485 {
3486   std::vector<const DataArrayDouble *> a;
3487   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3488     if(*it4)
3489       a.push_back(*it4);
3490   if(a.empty())
3491     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3492   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3493   int nbOfComp=(*it)->getNumberOfComponents();
3494   int nbt=(*it++)->getNumberOfTuples();
3495   for(int i=1;it!=a.end();it++,i++)
3496     {
3497       if((*it)->getNumberOfComponents()!=nbOfComp)
3498         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3499       nbt+=(*it)->getNumberOfTuples();
3500     }
3501   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3502   ret->alloc(nbt,nbOfComp);
3503   double *pt=ret->getPointer();
3504   for(it=a.begin();it!=a.end();it++)
3505     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3506   ret->copyStringInfoFrom(*(a[0]));
3507   return ret.retn();
3508 }
3509
3510 /*!
3511  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3512  * of components in the result array is a sum of the number of components of given arrays
3513  * and (2) the number of tuples in the result array is same as that of each of given
3514  * arrays. In other words the i-th tuple of result array includes all components of
3515  * i-th tuples of all given arrays.
3516  * Number of tuples in the given arrays must be  the same.
3517  *  \param [in] a1 - an array to include in the result array.
3518  *  \param [in] a2 - another array to include in the result array.
3519  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3520  *          The caller is to delete this result array using decrRef() as it is no more
3521  *          needed.
3522  *  \throw If both \a a1 and \a a2 are NULL.
3523  *  \throw If any given array is not allocated.
3524  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3525  */
3526 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3527 {
3528   std::vector<const DataArrayDouble *> arr(2);
3529   arr[0]=a1; arr[1]=a2;
3530   return Meld(arr);
3531 }
3532
3533 /*!
3534  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3535  * of components in the result array is a sum of the number of components of given arrays
3536  * and (2) the number of tuples in the result array is same as that of each of given
3537  * arrays. In other words the i-th tuple of result array includes all components of
3538  * i-th tuples of all given arrays.
3539  * Number of tuples in the given arrays must be  the same.
3540  *  \param [in] arr - a sequence of arrays to include in the result array.
3541  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3542  *          The caller is to delete this result array using decrRef() as it is no more
3543  *          needed.
3544  *  \throw If all arrays within \a arr are NULL.
3545  *  \throw If any given array is not allocated.
3546  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3547  */
3548 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3549 {
3550   std::vector<const DataArrayDouble *> a;
3551   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3552     if(*it4)
3553       a.push_back(*it4);
3554   if(a.empty())
3555     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3556   std::vector<const DataArrayDouble *>::const_iterator it;
3557   for(it=a.begin();it!=a.end();it++)
3558     (*it)->checkAllocated();
3559   it=a.begin();
3560   int nbOfTuples=(*it)->getNumberOfTuples();
3561   std::vector<int> nbc(a.size());
3562   std::vector<const double *> pts(a.size());
3563   nbc[0]=(*it)->getNumberOfComponents();
3564   pts[0]=(*it++)->getConstPointer();
3565   for(int i=1;it!=a.end();it++,i++)
3566     {
3567       if(nbOfTuples!=(*it)->getNumberOfTuples())
3568         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3569       nbc[i]=(*it)->getNumberOfComponents();
3570       pts[i]=(*it)->getConstPointer();
3571     }
3572   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3573   DataArrayDouble *ret=DataArrayDouble::New();
3574   ret->alloc(nbOfTuples,totalNbOfComp);
3575   double *retPtr=ret->getPointer();
3576   for(int i=0;i<nbOfTuples;i++)
3577     for(int j=0;j<(int)a.size();j++)
3578       {
3579         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3580         pts[j]+=nbc[j];
3581       }
3582   int k=0;
3583   for(int i=0;i<(int)a.size();i++)
3584     for(int j=0;j<nbc[i];j++,k++)
3585       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3586   return ret;
3587 }
3588
3589 /*!
3590  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3591  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3592  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3593  * Info on components and name is copied from the first of the given arrays.
3594  * Number of tuples and components in the given arrays must be the same.
3595  *  \param [in] a1 - a given array.
3596  *  \param [in] a2 - another given array.
3597  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3598  *          The caller is to delete this result array using decrRef() as it is no more
3599  *          needed.
3600  *  \throw If either \a a1 or \a a2 is NULL.
3601  *  \throw If any given array is not allocated.
3602  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3603  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3604  */
3605 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3606 {
3607   if(!a1 || !a2)
3608     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3609   a1->checkAllocated();
3610   a2->checkAllocated();
3611   int nbOfComp=a1->getNumberOfComponents();
3612   if(nbOfComp!=a2->getNumberOfComponents())
3613     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3614   int nbOfTuple=a1->getNumberOfTuples();
3615   if(nbOfTuple!=a2->getNumberOfTuples())
3616     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3617   DataArrayDouble *ret=DataArrayDouble::New();
3618   ret->alloc(nbOfTuple,1);
3619   double *retPtr=ret->getPointer();
3620   const double *a1Ptr=a1->getConstPointer();
3621   const double *a2Ptr=a2->getConstPointer();
3622   for(int i=0;i<nbOfTuple;i++)
3623     {
3624       double sum=0.;
3625       for(int j=0;j<nbOfComp;j++)
3626         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3627       retPtr[i]=sum;
3628     }
3629   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3630   ret->setName(a1->getName());
3631   return ret;
3632 }
3633
3634 /*!
3635  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3636  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3637  * product of two vectors defined by the i-th tuples of given arrays.
3638  * Info on components is copied from the first of the given arrays.
3639  * Number of tuples in the given arrays must be the same.
3640  * Number of components in the given arrays must be 3.
3641  *  \param [in] a1 - a given array.
3642  *  \param [in] a2 - another given array.
3643  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3644  *          The caller is to delete this result array using decrRef() as it is no more
3645  *          needed.
3646  *  \throw If either \a a1 or \a a2 is NULL.
3647  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3648  *  \throw If \a a1->getNumberOfComponents() != 3
3649  *  \throw If \a a2->getNumberOfComponents() != 3
3650  */
3651 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3652 {
3653   if(!a1 || !a2)
3654     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3655   int nbOfComp=a1->getNumberOfComponents();
3656   if(nbOfComp!=a2->getNumberOfComponents())
3657     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3658   if(nbOfComp!=3)
3659     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3660   int nbOfTuple=a1->getNumberOfTuples();
3661   if(nbOfTuple!=a2->getNumberOfTuples())
3662     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3663   DataArrayDouble *ret=DataArrayDouble::New();
3664   ret->alloc(nbOfTuple,3);
3665   double *retPtr=ret->getPointer();
3666   const double *a1Ptr=a1->getConstPointer();
3667   const double *a2Ptr=a2->getConstPointer();
3668   for(int i=0;i<nbOfTuple;i++)
3669     {
3670       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3671       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3672       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3673     }
3674   ret->copyStringInfoFrom(*a1);
3675   return ret;
3676 }
3677
3678 /*!
3679  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3680  * Info on components is copied from the first of the given arrays.
3681  * Number of tuples and components in the given arrays must be the same.
3682  *  \param [in] a1 - an array to compare values with another one.
3683  *  \param [in] a2 - another array to compare values with the first one.
3684  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3685  *          The caller is to delete this result array using decrRef() as it is no more
3686  *          needed.
3687  *  \throw If either \a a1 or \a a2 is NULL.
3688  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3689  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3690  */
3691 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3692 {
3693   if(!a1 || !a2)
3694     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3695   int nbOfComp=a1->getNumberOfComponents();
3696   if(nbOfComp!=a2->getNumberOfComponents())
3697     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3698   int nbOfTuple=a1->getNumberOfTuples();
3699   if(nbOfTuple!=a2->getNumberOfTuples())
3700     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3701   DataArrayDouble *ret=DataArrayDouble::New();
3702   ret->alloc(nbOfTuple,nbOfComp);
3703   double *retPtr=ret->getPointer();
3704   const double *a1Ptr=a1->getConstPointer();
3705   const double *a2Ptr=a2->getConstPointer();
3706   int nbElem=nbOfTuple*nbOfComp;
3707   for(int i=0;i<nbElem;i++)
3708     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3709   ret->copyStringInfoFrom(*a1);
3710   return ret;
3711 }
3712
3713 /*!
3714  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3715  * Info on components is copied from the first of the given arrays.
3716  * Number of tuples and components in the given arrays must be the same.
3717  *  \param [in] a1 - an array to compare values with another one.
3718  *  \param [in] a2 - another array to compare values with the first one.
3719  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3720  *          The caller is to delete this result array using decrRef() as it is no more
3721  *          needed.
3722  *  \throw If either \a a1 or \a a2 is NULL.
3723  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3724  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3725  */
3726 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3727 {
3728   if(!a1 || !a2)
3729     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3730   int nbOfComp=a1->getNumberOfComponents();
3731   if(nbOfComp!=a2->getNumberOfComponents())
3732     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3733   int nbOfTuple=a1->getNumberOfTuples();
3734   if(nbOfTuple!=a2->getNumberOfTuples())
3735     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3736   DataArrayDouble *ret=DataArrayDouble::New();
3737   ret->alloc(nbOfTuple,nbOfComp);
3738   double *retPtr=ret->getPointer();
3739   const double *a1Ptr=a1->getConstPointer();
3740   const double *a2Ptr=a2->getConstPointer();
3741   int nbElem=nbOfTuple*nbOfComp;
3742   for(int i=0;i<nbElem;i++)
3743     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3744   ret->copyStringInfoFrom(*a1);
3745   return ret;
3746 }
3747
3748 /*!
3749  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3750  * valid cases.
3751  * 1.  The arrays have same number of tuples and components. Then each value of
3752  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3753  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3754  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3755  *   component. Then
3756  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3757  * 3.  The arrays have same number of components and one array, say _a2_, has one
3758  *   tuple. Then
3759  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3760  *
3761  * Info on components is copied either from the first array (in the first case) or from
3762  * the array with maximal number of elements (getNbOfElems()).
3763  *  \param [in] a1 - an array to sum up.
3764  *  \param [in] a2 - another array to sum up.
3765  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3766  *          The caller is to delete this result array using decrRef() as it is no more
3767  *          needed.
3768  *  \throw If either \a a1 or \a a2 is NULL.
3769  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3770  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3771  *         none of them has number of tuples or components equal to 1.
3772  */
3773 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3774 {
3775   if(!a1 || !a2)
3776     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3777   int nbOfTuple=a1->getNumberOfTuples();
3778   int nbOfTuple2=a2->getNumberOfTuples();
3779   int nbOfComp=a1->getNumberOfComponents();
3780   int nbOfComp2=a2->getNumberOfComponents();
3781   MCAuto<DataArrayDouble> ret=0;
3782   if(nbOfTuple==nbOfTuple2)
3783     {
3784       if(nbOfComp==nbOfComp2)
3785         {
3786           ret=DataArrayDouble::New();
3787           ret->alloc(nbOfTuple,nbOfComp);
3788           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3789           ret->copyStringInfoFrom(*a1);
3790         }
3791       else
3792         {
3793           int nbOfCompMin,nbOfCompMax;
3794           const DataArrayDouble *aMin, *aMax;
3795           if(nbOfComp>nbOfComp2)
3796             {
3797               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3798               aMin=a2; aMax=a1;
3799             }
3800           else
3801             {
3802               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3803               aMin=a1; aMax=a2;
3804             }
3805           if(nbOfCompMin==1)
3806             {
3807               ret=DataArrayDouble::New();
3808               ret->alloc(nbOfTuple,nbOfCompMax);
3809               const double *aMinPtr=aMin->getConstPointer();
3810               const double *aMaxPtr=aMax->getConstPointer();
3811               double *res=ret->getPointer();
3812               for(int i=0;i<nbOfTuple;i++)
3813                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3814               ret->copyStringInfoFrom(*aMax);
3815             }
3816           else
3817             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3818         }
3819     }
3820   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3821     {
3822       if(nbOfComp==nbOfComp2)
3823         {
3824           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3825           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3826           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3827           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3828           ret=DataArrayDouble::New();
3829           ret->alloc(nbOfTupleMax,nbOfComp);
3830           double *res=ret->getPointer();
3831           for(int i=0;i<nbOfTupleMax;i++)
3832             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3833           ret->copyStringInfoFrom(*aMax);
3834         }
3835       else
3836         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3837     }
3838   else
3839     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3840   return ret.retn();
3841 }
3842
3843 /*!
3844  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3845  * valid cases.
3846  * 1.  The arrays have same number of tuples and components. Then each value of
3847  *   \a other array is added to the corresponding value of \a this array, i.e.:
3848  *   _a_ [ i, j ] += _other_ [ i, j ].
3849  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3850  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3851  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3852  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3853  *
3854  *  \param [in] other - an array to add to \a this one.
3855  *  \throw If \a other is NULL.
3856  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3857  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3858  *         \a other has number of both tuples and components not equal to 1.
3859  */
3860 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3861 {
3862   if(!other)
3863     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3864   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3865   checkAllocated();
3866   other->checkAllocated();
3867   int nbOfTuple=getNumberOfTuples();
3868   int nbOfTuple2=other->getNumberOfTuples();
3869   int nbOfComp=getNumberOfComponents();
3870   int nbOfComp2=other->getNumberOfComponents();
3871   if(nbOfTuple==nbOfTuple2)
3872     {
3873       if(nbOfComp==nbOfComp2)
3874         {
3875           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3876         }
3877       else if(nbOfComp2==1)
3878         {
3879           double *ptr=getPointer();
3880           const double *ptrc=other->getConstPointer();
3881           for(int i=0;i<nbOfTuple;i++)
3882             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3883         }
3884       else
3885         throw INTERP_KERNEL::Exception(msg);
3886     }
3887   else if(nbOfTuple2==1)
3888     {
3889       if(nbOfComp2==nbOfComp)
3890         {
3891           double *ptr=getPointer();
3892           const double *ptrc=other->getConstPointer();
3893           for(int i=0;i<nbOfTuple;i++)
3894             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3895         }
3896       else
3897         throw INTERP_KERNEL::Exception(msg);
3898     }
3899   else
3900     throw INTERP_KERNEL::Exception(msg);
3901   declareAsNew();
3902 }
3903
3904 /*!
3905  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3906  * valid cases.
3907  * 1.  The arrays have same number of tuples and components. Then each value of
3908  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3909  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3910  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3911  *   component. Then
3912  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3913  * 3.  The arrays have same number of components and one array, say _a2_, has one
3914  *   tuple. Then
3915  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3916  *
3917  * Info on components is copied either from the first array (in the first case) or from
3918  * the array with maximal number of elements (getNbOfElems()).
3919  *  \param [in] a1 - an array to subtract from.
3920  *  \param [in] a2 - an array to subtract.
3921  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3922  *          The caller is to delete this result array using decrRef() as it is no more
3923  *          needed.
3924  *  \throw If either \a a1 or \a a2 is NULL.
3925  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3926  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3927  *         none of them has number of tuples or components equal to 1.
3928  */
3929 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3930 {
3931   if(!a1 || !a2)
3932     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3933   int nbOfTuple1=a1->getNumberOfTuples();
3934   int nbOfTuple2=a2->getNumberOfTuples();
3935   int nbOfComp1=a1->getNumberOfComponents();
3936   int nbOfComp2=a2->getNumberOfComponents();
3937   if(nbOfTuple2==nbOfTuple1)
3938     {
3939       if(nbOfComp1==nbOfComp2)
3940         {
3941           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3942           ret->alloc(nbOfTuple2,nbOfComp1);
3943           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3944           ret->copyStringInfoFrom(*a1);
3945           return ret.retn();
3946         }
3947       else if(nbOfComp2==1)
3948         {
3949           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3950           ret->alloc(nbOfTuple1,nbOfComp1);
3951           const double *a2Ptr=a2->getConstPointer();
3952           const double *a1Ptr=a1->getConstPointer();
3953           double *res=ret->getPointer();
3954           for(int i=0;i<nbOfTuple1;i++)
3955             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3956           ret->copyStringInfoFrom(*a1);
3957           return ret.retn();
3958         }
3959       else
3960         {
3961           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3962           return 0;
3963         }
3964     }
3965   else if(nbOfTuple2==1)
3966     {
3967       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3968       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3969       ret->alloc(nbOfTuple1,nbOfComp1);
3970       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3971       double *pt=ret->getPointer();
3972       for(int i=0;i<nbOfTuple1;i++)
3973         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3974       ret->copyStringInfoFrom(*a1);
3975       return ret.retn();
3976     }
3977   else
3978     {
3979       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3980       return 0;
3981     }
3982 }
3983
3984 /*!
3985  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3986  * valid cases.
3987  * 1.  The arrays have same number of tuples and components. Then each value of
3988  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3989  *   _a_ [ i, j ] -= _other_ [ i, j ].
3990  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3991  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3992  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3993  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3994  *
3995  *  \param [in] other - an array to subtract from \a this one.
3996  *  \throw If \a other is NULL.
3997  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3998  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3999  *         \a other has number of both tuples and components not equal to 1.
4000  */
4001 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
4002 {
4003   if(!other)
4004     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4005   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4006   checkAllocated();
4007   other->checkAllocated();
4008   int nbOfTuple=getNumberOfTuples();
4009   int nbOfTuple2=other->getNumberOfTuples();
4010   int nbOfComp=getNumberOfComponents();
4011   int nbOfComp2=other->getNumberOfComponents();
4012   if(nbOfTuple==nbOfTuple2)
4013     {
4014       if(nbOfComp==nbOfComp2)
4015         {
4016           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4017         }
4018       else if(nbOfComp2==1)
4019         {
4020           double *ptr=getPointer();
4021           const double *ptrc=other->getConstPointer();
4022           for(int i=0;i<nbOfTuple;i++)
4023             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4024         }
4025       else
4026         throw INTERP_KERNEL::Exception(msg);
4027     }
4028   else if(nbOfTuple2==1)
4029     {
4030       if(nbOfComp2==nbOfComp)
4031         {
4032           double *ptr=getPointer();
4033           const double *ptrc=other->getConstPointer();
4034           for(int i=0;i<nbOfTuple;i++)
4035             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4036         }
4037       else
4038         throw INTERP_KERNEL::Exception(msg);
4039     }
4040   else
4041     throw INTERP_KERNEL::Exception(msg);
4042   declareAsNew();
4043 }
4044
4045 /*!
4046  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4047  * valid cases.
4048  * 1.  The arrays have same number of tuples and components. Then each value of
4049  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4050  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4051  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4052  *   component. Then
4053  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4054  * 3.  The arrays have same number of components and one array, say _a2_, has one
4055  *   tuple. Then
4056  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4057  *
4058  * Info on components is copied either from the first array (in the first case) or from
4059  * the array with maximal number of elements (getNbOfElems()).
4060  *  \param [in] a1 - a factor array.
4061  *  \param [in] a2 - another factor array.
4062  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4063  *          The caller is to delete this result array using decrRef() as it is no more
4064  *          needed.
4065  *  \throw If either \a a1 or \a a2 is NULL.
4066  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4067  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4068  *         none of them has number of tuples or components equal to 1.
4069  */
4070 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4071 {
4072   if(!a1 || !a2)
4073     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4074   int nbOfTuple=a1->getNumberOfTuples();
4075   int nbOfTuple2=a2->getNumberOfTuples();
4076   int nbOfComp=a1->getNumberOfComponents();
4077   int nbOfComp2=a2->getNumberOfComponents();
4078   MCAuto<DataArrayDouble> ret=0;
4079   if(nbOfTuple==nbOfTuple2)
4080     {
4081       if(nbOfComp==nbOfComp2)
4082         {
4083           ret=DataArrayDouble::New();
4084           ret->alloc(nbOfTuple,nbOfComp);
4085           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4086           ret->copyStringInfoFrom(*a1);
4087         }
4088       else
4089         {
4090           int nbOfCompMin,nbOfCompMax;
4091           const DataArrayDouble *aMin, *aMax;
4092           if(nbOfComp>nbOfComp2)
4093             {
4094               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4095               aMin=a2; aMax=a1;
4096             }
4097           else
4098             {
4099               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4100               aMin=a1; aMax=a2;
4101             }
4102           if(nbOfCompMin==1)
4103             {
4104               ret=DataArrayDouble::New();
4105               ret->alloc(nbOfTuple,nbOfCompMax);
4106               const double *aMinPtr=aMin->getConstPointer();
4107               const double *aMaxPtr=aMax->getConstPointer();
4108               double *res=ret->getPointer();
4109               for(int i=0;i<nbOfTuple;i++)
4110                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4111               ret->copyStringInfoFrom(*aMax);
4112             }
4113           else
4114             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4115         }
4116     }
4117   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4118     {
4119       if(nbOfComp==nbOfComp2)
4120         {
4121           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4122           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4123           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4124           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4125           ret=DataArrayDouble::New();
4126           ret->alloc(nbOfTupleMax,nbOfComp);
4127           double *res=ret->getPointer();
4128           for(int i=0;i<nbOfTupleMax;i++)
4129             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4130           ret->copyStringInfoFrom(*aMax);
4131         }
4132       else
4133         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4134     }
4135   else
4136     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4137   return ret.retn();
4138 }
4139
4140 /*!
4141  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4142  * valid cases.
4143  * 1.  The arrays have same number of tuples and components. Then each value of
4144  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4145  *   _this_ [ i, j ] *= _other_ [ i, j ].
4146  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4147  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4148  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4149  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4150  *
4151  *  \param [in] other - an array to multiply to \a this one.
4152  *  \throw If \a other is NULL.
4153  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4154  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4155  *         \a other has number of both tuples and components not equal to 1.
4156  */
4157 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4158 {
4159   if(!other)
4160     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4161   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4162   checkAllocated();
4163   other->checkAllocated();
4164   int nbOfTuple=getNumberOfTuples();
4165   int nbOfTuple2=other->getNumberOfTuples();
4166   int nbOfComp=getNumberOfComponents();
4167   int nbOfComp2=other->getNumberOfComponents();
4168   if(nbOfTuple==nbOfTuple2)
4169     {
4170       if(nbOfComp==nbOfComp2)
4171         {
4172           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4173         }
4174       else if(nbOfComp2==1)
4175         {
4176           double *ptr=getPointer();
4177           const double *ptrc=other->getConstPointer();
4178           for(int i=0;i<nbOfTuple;i++)
4179             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4180         }
4181       else
4182         throw INTERP_KERNEL::Exception(msg);
4183     }
4184   else if(nbOfTuple2==1)
4185     {
4186       if(nbOfComp2==nbOfComp)
4187         {
4188           double *ptr=getPointer();
4189           const double *ptrc=other->getConstPointer();
4190           for(int i=0;i<nbOfTuple;i++)
4191             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4192         }
4193       else
4194         throw INTERP_KERNEL::Exception(msg);
4195     }
4196   else
4197     throw INTERP_KERNEL::Exception(msg);
4198   declareAsNew();
4199 }
4200
4201 /*!
4202  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4203  * valid cases.
4204  * 1.  The arrays have same number of tuples and components. Then each value of
4205  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4206  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4207  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4208  *   component. Then
4209  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4210  * 3.  The arrays have same number of components and one array, say _a2_, has one
4211  *   tuple. Then
4212  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4213  *
4214  * Info on components is copied either from the first array (in the first case) or from
4215  * the array with maximal number of elements (getNbOfElems()).
4216  *  \warning No check of division by zero is performed!
4217  *  \param [in] a1 - a numerator array.
4218  *  \param [in] a2 - a denominator array.
4219  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4220  *          The caller is to delete this result array using decrRef() as it is no more
4221  *          needed.
4222  *  \throw If either \a a1 or \a a2 is NULL.
4223  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4224  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4225  *         none of them has number of tuples or components equal to 1.
4226  */
4227 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4228 {
4229   if(!a1 || !a2)
4230     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4231   int nbOfTuple1=a1->getNumberOfTuples();
4232   int nbOfTuple2=a2->getNumberOfTuples();
4233   int nbOfComp1=a1->getNumberOfComponents();
4234   int nbOfComp2=a2->getNumberOfComponents();
4235   if(nbOfTuple2==nbOfTuple1)
4236     {
4237       if(nbOfComp1==nbOfComp2)
4238         {
4239           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4240           ret->alloc(nbOfTuple2,nbOfComp1);
4241           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4242           ret->copyStringInfoFrom(*a1);
4243           return ret.retn();
4244         }
4245       else if(nbOfComp2==1)
4246         {
4247           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4248           ret->alloc(nbOfTuple1,nbOfComp1);
4249           const double *a2Ptr=a2->getConstPointer();
4250           const double *a1Ptr=a1->getConstPointer();
4251           double *res=ret->getPointer();
4252           for(int i=0;i<nbOfTuple1;i++)
4253             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4254           ret->copyStringInfoFrom(*a1);
4255           return ret.retn();
4256         }
4257       else
4258         {
4259           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4260           return 0;
4261         }
4262     }
4263   else if(nbOfTuple2==1)
4264     {
4265       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4266       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4267       ret->alloc(nbOfTuple1,nbOfComp1);
4268       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4269       double *pt=ret->getPointer();
4270       for(int i=0;i<nbOfTuple1;i++)
4271         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4272       ret->copyStringInfoFrom(*a1);
4273       return ret.retn();
4274     }
4275   else
4276     {
4277       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4278       return 0;
4279     }
4280 }
4281
4282 /*!
4283  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4284  * valid cases.
4285  * 1.  The arrays have same number of tuples and components. Then each value of
4286  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4287  *   _a_ [ i, j ] /= _other_ [ i, j ].
4288  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4289  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4290  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4291  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4292  *
4293  *  \warning No check of division by zero is performed!
4294  *  \param [in] other - an array to divide \a this one by.
4295  *  \throw If \a other is NULL.
4296  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4297  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4298  *         \a other has number of both tuples and components not equal to 1.
4299  */
4300 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4301 {
4302   if(!other)
4303     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4304   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4305   checkAllocated();
4306   other->checkAllocated();
4307   int nbOfTuple=getNumberOfTuples();
4308   int nbOfTuple2=other->getNumberOfTuples();
4309   int nbOfComp=getNumberOfComponents();
4310   int nbOfComp2=other->getNumberOfComponents();
4311   if(nbOfTuple==nbOfTuple2)
4312     {
4313       if(nbOfComp==nbOfComp2)
4314         {
4315           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4316         }
4317       else if(nbOfComp2==1)
4318         {
4319           double *ptr=getPointer();
4320           const double *ptrc=other->getConstPointer();
4321           for(int i=0;i<nbOfTuple;i++)
4322             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4323         }
4324       else
4325         throw INTERP_KERNEL::Exception(msg);
4326     }
4327   else if(nbOfTuple2==1)
4328     {
4329       if(nbOfComp2==nbOfComp)
4330         {
4331           double *ptr=getPointer();
4332           const double *ptrc=other->getConstPointer();
4333           for(int i=0;i<nbOfTuple;i++)
4334             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4335         }
4336       else
4337         throw INTERP_KERNEL::Exception(msg);
4338     }
4339   else
4340     throw INTERP_KERNEL::Exception(msg);
4341   declareAsNew();
4342 }
4343
4344 /*!
4345  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4346  * valid cases.
4347  *
4348  *  \param [in] a1 - an array to pow up.
4349  *  \param [in] a2 - another array to sum up.
4350  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4351  *          The caller is to delete this result array using decrRef() as it is no more
4352  *          needed.
4353  *  \throw If either \a a1 or \a a2 is NULL.
4354  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4355  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4356  *  \throw If there is a negative value in \a a1.
4357  */
4358 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4359 {
4360   if(!a1 || !a2)
4361     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4362   int nbOfTuple=a1->getNumberOfTuples();
4363   int nbOfTuple2=a2->getNumberOfTuples();
4364   int nbOfComp=a1->getNumberOfComponents();
4365   int nbOfComp2=a2->getNumberOfComponents();
4366   if(nbOfTuple!=nbOfTuple2)
4367     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4368   if(nbOfComp!=1 || nbOfComp2!=1)
4369     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4370   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4371   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4372   double *ptr=ret->getPointer();
4373   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4374     {
4375       if(*ptr1>=0)
4376         {
4377           *ptr=pow(*ptr1,*ptr2);
4378         }
4379       else
4380         {
4381           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4382           throw INTERP_KERNEL::Exception(oss.str().c_str());
4383         }
4384     }
4385   return ret.retn();
4386 }
4387
4388 /*!
4389  * Apply pow on values of another DataArrayDouble to values of \a this one.
4390  *
4391  *  \param [in] other - an array to pow to \a this one.
4392  *  \throw If \a other is NULL.
4393  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4394  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4395  *  \throw If there is a negative value in \a this.
4396  */
4397 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4398 {
4399   if(!other)
4400     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4401   int nbOfTuple=getNumberOfTuples();
4402   int nbOfTuple2=other->getNumberOfTuples();
4403   int nbOfComp=getNumberOfComponents();
4404   int nbOfComp2=other->getNumberOfComponents();
4405   if(nbOfTuple!=nbOfTuple2)
4406     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4407   if(nbOfComp!=1 || nbOfComp2!=1)
4408     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4409   double *ptr=getPointer();
4410   const double *ptrc=other->begin();
4411   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4412     {
4413       if(*ptr>=0)
4414         *ptr=pow(*ptr,*ptrc);
4415       else
4416         {
4417           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4418           throw INTERP_KERNEL::Exception(oss.str().c_str());
4419         }
4420     }
4421   declareAsNew();
4422 }
4423
4424 /*!
4425  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4426  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4427  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4428  *
4429  * \throw if \a this is not allocated.
4430  * \throw if \a this has not exactly one component.
4431  */
4432 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4433 {
4434   checkAllocated();
4435   if(getNumberOfComponents()!=1)
4436     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4437   int nbt(getNumberOfTuples());
4438   std::vector<bool> ret(nbt);
4439   const double *pt(begin());
4440   for(int i=0;i<nbt;i++)
4441     {
4442       if(fabs(pt[i])<eps)
4443         ret[i]=false;
4444       else if(fabs(pt[i]-1.)<eps)
4445         ret[i]=true;
4446       else
4447         {
4448           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4449           throw INTERP_KERNEL::Exception(oss.str().c_str());
4450         }
4451     }
4452   return ret;
4453 }
4454
4455 /*!
4456  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4457  * Server side.
4458  */
4459 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4460 {
4461   tinyInfo.resize(2);
4462   if(isAllocated())
4463     {
4464       tinyInfo[0]=getNumberOfTuples();
4465       tinyInfo[1]=getNumberOfComponents();
4466     }
4467   else
4468     {
4469       tinyInfo[0]=-1;
4470       tinyInfo[1]=-1;
4471     }
4472 }
4473
4474 /*!
4475  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4476  * Server side.
4477  */
4478 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4479 {
4480   if(isAllocated())
4481     {
4482       int nbOfCompo=getNumberOfComponents();
4483       tinyInfo.resize(nbOfCompo+1);
4484       tinyInfo[0]=getName();
4485       for(int i=0;i<nbOfCompo;i++)
4486         tinyInfo[i+1]=getInfoOnComponent(i);
4487     }
4488   else
4489     {
4490       tinyInfo.resize(1);
4491       tinyInfo[0]=getName();
4492     }
4493 }
4494
4495 /*!
4496  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4497  * This method returns if a feeding is needed.
4498  */
4499 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4500 {
4501   int nbOfTuple=tinyInfoI[0];
4502   int nbOfComp=tinyInfoI[1];
4503   if(nbOfTuple!=-1 || nbOfComp!=-1)
4504     {
4505       alloc(nbOfTuple,nbOfComp);
4506       return true;
4507     }
4508   return false;
4509 }
4510
4511 /*!
4512  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4513  */
4514 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4515 {
4516   setName(tinyInfoS[0]);
4517   if(isAllocated())
4518     {
4519       int nbOfCompo=getNumberOfComponents();
4520       for(int i=0;i<nbOfCompo;i++)
4521         setInfoOnComponent(i,tinyInfoS[i+1]);
4522     }
4523 }
4524
4525 /*!
4526  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4527  * around an axe ( \a center, \a vect) and with angle \a angle.
4528  */
4529 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4530 {
4531   if(!center || !vect)
4532     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4533   double sina(sin(angle));
4534   double cosa(cos(angle));
4535   double vectorNorm[3];
4536   double matrix[9];
4537   double matrixTmp[9];
4538   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4539   if(norm<std::numeric_limits<double>::min())
4540     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4541   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4542   //rotation matrix computation
4543   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;
4544   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4545   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4546   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4547   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4548   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4549   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4550   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4551   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4552   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4553   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4554   //rotation matrix computed.
4555   double tmp[3];
4556   for(int i=0; i<nbNodes; i++)
4557     {
4558       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4559       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4560       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4561       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4562     }
4563 }
4564
4565 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4566 {
4567   double matrix[9],matrix2[9],matrix3[9];
4568   double vect[3],crossVect[3];
4569   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4570   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4571   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4572   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4573   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4574   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4575   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4576   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4577   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4578   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4579   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4580   for(int i=0;i<3;i++)
4581     for(int j=0;j<3;j++)
4582       {
4583         double val(0.);
4584         for(int k=0;k<3;k++)
4585           val+=matrix[3*i+k]*matrix2[3*k+j];
4586         matrix3[3*i+j]=val;
4587       }
4588   //rotation matrix computed.
4589   double tmp[3];
4590   for(int i=0; i<nbNodes; i++)
4591     {
4592       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4593       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4594       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4595       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4596     }
4597 }
4598
4599 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4600 {
4601   double vect[3],crossVect[3];
4602   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4603   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4604   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4605   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4606   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4607   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4608   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4609   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4610 }
4611
4612 /*!
4613  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4614  * around the center point \a center and with angle \a angle.
4615  */
4616 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4617 {
4618   double cosa=cos(angle);
4619   double sina=sin(angle);
4620   double matrix[4];
4621   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4622   double tmp[2];
4623   for(int i=0; i<nbNodes; i++)
4624     {
4625       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4626       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4627       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4628     }
4629 }
4630
4631 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4632 {
4633   if(_da)
4634     {
4635       _da->incrRef();
4636       if(_da->isAllocated())
4637         {
4638           _nb_comp=da->getNumberOfComponents();
4639           _nb_tuple=da->getNumberOfTuples();
4640           _pt=da->getPointer();
4641         }
4642     }
4643 }
4644
4645 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4646 {
4647   if(_da)
4648     _da->decrRef();
4649 }
4650
4651 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4652 {
4653   if(_tuple_id<_nb_tuple)
4654     {
4655       _tuple_id++;
4656       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4657       _pt+=_nb_comp;
4658       return ret;
4659     }
4660   else
4661     return 0;
4662 }
4663
4664 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4665 {
4666 }
4667
4668
4669 std::string DataArrayDoubleTuple::repr() const
4670 {
4671   std::ostringstream oss; oss.precision(17); oss << "(";
4672   for(int i=0;i<_nb_of_compo-1;i++)
4673     oss << _pt[i] << ", ";
4674   oss << _pt[_nb_of_compo-1] << ")";
4675   return oss.str();
4676 }
4677
4678 double DataArrayDoubleTuple::doubleValue() const
4679 {
4680   if(_nb_of_compo==1)
4681     return *_pt;
4682   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4683 }
4684
4685 /*!
4686  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4687  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4688  * 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
4689  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4690  */
4691 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4692 {
4693   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4694     {
4695       DataArrayDouble *ret=DataArrayDouble::New();
4696       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4697       return ret;
4698     }
4699   else
4700     {
4701       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4702       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4703       throw INTERP_KERNEL::Exception(oss.str().c_str());
4704     }
4705 }
4706
4707 /*!
4708  * Returns a new instance of DataArrayInt. The caller is to delete this array
4709  * using decrRef() as it is no more needed. 
4710  */
4711 DataArrayInt *DataArrayInt::New()
4712 {
4713   return new DataArrayInt;
4714 }
4715
4716 /*!
4717  * Returns the only one value in \a this, if and only if number of elements
4718  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4719  *  \return double - the sole value stored in \a this array.
4720  *  \throw If at least one of conditions stated above is not fulfilled.
4721  */
4722 int DataArrayInt::intValue() const
4723 {
4724   if(isAllocated())
4725     {
4726       if(getNbOfElems()==1)
4727         {
4728           return *getConstPointer();
4729         }
4730       else
4731         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4732     }
4733   else
4734     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4735 }
4736
4737 /*!
4738  * Returns an integer value characterizing \a this array, which is useful for a quick
4739  * comparison of many instances of DataArrayInt.
4740  *  \return int - the hash value.
4741  *  \throw If \a this is not allocated.
4742  */
4743 int DataArrayInt::getHashCode() const
4744 {
4745   checkAllocated();
4746   std::size_t nbOfElems=getNbOfElems();
4747   int ret=nbOfElems*65536;
4748   int delta=3;
4749   if(nbOfElems>48)
4750     delta=nbOfElems/8;
4751   int ret0=0;
4752   const int *pt=begin();
4753   for(std::size_t i=0;i<nbOfElems;i+=delta)
4754     ret0+=pt[i] & 0x1FFF;
4755   return ret+ret0;
4756 }
4757
4758 /*!
4759  * Returns a full copy of \a this. For more info on copying data arrays see
4760  * \ref MEDCouplingArrayBasicsCopyDeep.
4761  *  \return DataArrayInt * - a new instance of DataArrayInt.
4762  */
4763 DataArrayInt *DataArrayInt::deepCopy() const
4764 {
4765   return new DataArrayInt(*this);
4766 }
4767
4768 /*!
4769  * Returns either a \a deep or \a shallow copy of this array. For more info see
4770  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4771  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4772  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4773  *          == \a true) or \a this instance (if \a dCpy == \a false).
4774  */
4775 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4776 {
4777   if(dCpy)
4778     return deepCopy();
4779   else
4780     {
4781       incrRef();
4782       return const_cast<DataArrayInt *>(this);
4783     }
4784 }
4785
4786 /*!
4787  * Assign zero to all values in \a this array. To know more on filling arrays see
4788  * \ref MEDCouplingArrayFill.
4789  * \throw If \a this is not allocated.
4790  */
4791 void DataArrayInt::fillWithZero()
4792 {
4793   fillWithValue(0);
4794 }
4795
4796 /*!
4797  * Set all values in \a this array so that the i-th element equals to \a init + i
4798  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4799  *  \param [in] init - value to assign to the first element of array.
4800  *  \throw If \a this->getNumberOfComponents() != 1
4801  *  \throw If \a this is not allocated.
4802  */
4803 void DataArrayInt::iota(int init)
4804 {
4805   checkAllocated();
4806   if(getNumberOfComponents()!=1)
4807     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4808   int *ptr=getPointer();
4809   int ntuples=getNumberOfTuples();
4810   for(int i=0;i<ntuples;i++)
4811     ptr[i]=init+i;
4812   declareAsNew();
4813 }
4814
4815 /*!
4816  * Returns a textual and human readable representation of \a this instance of
4817  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4818  * \return std::string - text describing \a this DataArrayInt.
4819  * 
4820  * \sa reprNotTooLong, reprZip
4821  */
4822 std::string DataArrayInt::repr() const
4823 {
4824   std::ostringstream ret;
4825   reprStream(ret);
4826   return ret.str();
4827 }
4828
4829 std::string DataArrayInt::reprZip() const
4830 {
4831   std::ostringstream ret;
4832   reprZipStream(ret);
4833   return ret.str();
4834 }
4835
4836 /*!
4837  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4838  * printed out to avoid to consume too much space in interpretor.
4839  * \sa repr
4840  */
4841 std::string DataArrayInt::reprNotTooLong() const
4842 {
4843   std::ostringstream ret;
4844   reprNotTooLongStream(ret);
4845   return ret.str();
4846 }
4847
4848 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4849 {
4850   static const char SPACE[4]={' ',' ',' ',' '};
4851   checkAllocated();
4852   std::string idt(indent,' ');
4853   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4854   if(byteArr)
4855     {
4856       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4857       if(std::string(type)=="Int32")
4858         {
4859           const char *data(reinterpret_cast<const char *>(begin()));
4860           std::size_t sz(getNbOfElems()*sizeof(int));
4861           byteArr->insertAtTheEnd(data,data+sz);
4862           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4863         }
4864       else if(std::string(type)=="Int8")
4865         {
4866           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4867           std::copy(begin(),end(),(char *)tmp);
4868           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4869           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4870         }
4871       else if(std::string(type)=="UInt8")
4872         {
4873           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4874           std::copy(begin(),end(),(unsigned char *)tmp);
4875           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4876           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4877         }
4878       else
4879         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4880     }
4881   else
4882     {
4883       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4884       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4885     }
4886   ofs << std::endl << idt << "</DataArray>\n";
4887 }
4888
4889 void DataArrayInt::reprStream(std::ostream& stream) const
4890 {
4891   stream << "Name of int array : \"" << _name << "\"\n";
4892   reprWithoutNameStream(stream);
4893 }
4894
4895 void DataArrayInt::reprZipStream(std::ostream& stream) const
4896 {
4897   stream << "Name of int array : \"" << _name << "\"\n";
4898   reprZipWithoutNameStream(stream);
4899 }
4900
4901 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4902 {
4903   stream << "Name of int array : \"" << _name << "\"\n";
4904   reprNotTooLongWithoutNameStream(stream);
4905 }
4906
4907 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4908 {
4909   DataArray::reprWithoutNameStream(stream);
4910   _mem.repr(getNumberOfComponents(),stream);
4911 }
4912
4913 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4914 {
4915   DataArray::reprWithoutNameStream(stream);
4916   _mem.reprZip(getNumberOfComponents(),stream);
4917 }
4918
4919 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4920 {
4921   DataArray::reprWithoutNameStream(stream);
4922   stream.precision(17);
4923   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4924 }
4925
4926 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4927 {
4928   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4929   const int *data=getConstPointer();
4930   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4931   if(nbTuples*nbComp>=1)
4932     {
4933       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4934       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4935       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4936       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4937     }
4938   else
4939     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4940   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4941 }
4942
4943 /*!
4944  * Method that gives a quick overvien of \a this for python.
4945  */
4946 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4947 {
4948   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4949   stream << "DataArrayInt C++ instance at " << this << ". ";
4950   if(isAllocated())
4951     {
4952       int nbOfCompo=(int)_info_on_compo.size();
4953       if(nbOfCompo>=1)
4954         {
4955           int nbOfTuples=getNumberOfTuples();
4956           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4957           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4958         }
4959       else
4960         stream << "Number of components : 0.";
4961     }
4962   else
4963     stream << "*** No data allocated ****";
4964 }
4965
4966 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4967 {
4968   const int *data=begin();
4969   int nbOfTuples=getNumberOfTuples();
4970   int nbOfCompo=(int)_info_on_compo.size();
4971   std::ostringstream oss2; oss2 << "[";
4972   std::string oss2Str(oss2.str());
4973   bool isFinished=true;
4974   for(int i=0;i<nbOfTuples && isFinished;i++)
4975     {
4976       if(nbOfCompo>1)
4977         {
4978           oss2 << "(";
4979           for(int j=0;j<nbOfCompo;j++,data++)
4980             {
4981               oss2 << *data;
4982               if(j!=nbOfCompo-1) oss2 << ", ";
4983             }
4984           oss2 << ")";
4985         }
4986       else
4987         oss2 << *data++;
4988       if(i!=nbOfTuples-1) oss2 << ", ";
4989       std::string oss3Str(oss2.str());
4990       if(oss3Str.length()<maxNbOfByteInRepr)
4991         oss2Str=oss3Str;
4992       else
4993         isFinished=false;
4994     }
4995   stream << oss2Str;
4996   if(!isFinished)
4997     stream << "... ";
4998   stream << "]";
4999 }
5000
5001 /*!
5002  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5003  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5004  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5005  *         to \a this array.
5006  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5007  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5008  *  \throw If \a this->getNumberOfComponents() != 1
5009  *  \throw If any value of \a this can't be used as a valid index for 
5010  *         [\a indArrBg, \a indArrEnd).
5011  *
5012  *  \sa changeValue
5013  */
5014 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
5015 {
5016   checkAllocated();
5017   if(getNumberOfComponents()!=1)
5018     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5019   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
5020   for(int i=0;i<nbOfTuples;i++,pt++)
5021     {
5022       if(*pt>=0 && *pt<nbElemsIn)
5023         *pt=indArrBg[*pt];
5024       else
5025         {
5026           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5027           throw INTERP_KERNEL::Exception(oss.str().c_str());
5028         }
5029     }
5030   declareAsNew();
5031 }
5032
5033 /*!
5034  * Computes distribution of values of \a this one-dimensional array between given value
5035  * ranges (casts). This method is typically useful for entity number spliting by types,
5036  * for example. 
5037  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5038  *           check of this is be done. If not, the result is not warranted. 
5039  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5040  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5041  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5042  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5043  *         should be more than every value in \a this array.
5044  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5045  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5046  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5047  *         (same number of tuples and components), the caller is to delete 
5048  *         using decrRef() as it is no more needed.
5049  *         This array contains indices of ranges for every value of \a this array. I.e.
5050  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5051  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5052  *         this in which cast it holds.
5053  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5054  *         array, the caller is to delete using decrRef() as it is no more needed.
5055  *         This array contains ranks of values of \a this array within ranges
5056  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5057  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5058  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5059  *         for each tuple its rank inside its cast. The rank is computed as difference
5060  *         between the value and the lowest value of range.
5061  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5062  *         ranges (casts) to which at least one value of \a this array belongs.
5063  *         Or, in other words, this param contains the casts that \a this contains.
5064  *         The caller is to delete this array using decrRef() as it is no more needed.
5065  *
5066  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5067  *            the output of this method will be : 
5068  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5069  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5070  * - \a castsPresent  : [0,1]
5071  *
5072  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5073  * range #1 and its rank within this range is 2; etc.
5074  *
5075  *  \throw If \a this->getNumberOfComponents() != 1.
5076  *  \throw If \a arrEnd - arrBg < 2.
5077  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5078  */
5079 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5080                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5081 {
5082   checkAllocated();
5083   if(getNumberOfComponents()!=1)
5084     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5085   int nbOfTuples=getNumberOfTuples();
5086   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5087   if(nbOfCast<2)
5088     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5089   nbOfCast--;
5090   const int *work=getConstPointer();
5091   typedef std::reverse_iterator<const int *> rintstart;
5092   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5093   rintstart end2(arrBg);
5094   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5095   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5096   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5097   ret1->alloc(nbOfTuples,1);
5098   ret2->alloc(nbOfTuples,1);
5099   int *ret1Ptr=ret1->getPointer();
5100   int *ret2Ptr=ret2->getPointer();
5101   std::set<std::size_t> castsDetected;
5102   for(int i=0;i<nbOfTuples;i++)
5103     {
5104       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5105       std::size_t pos=std::distance(bg,res);
5106       std::size_t pos2=nbOfCast-pos;
5107       if(pos2<nbOfCast)
5108         {
5109           ret1Ptr[i]=(int)pos2;
5110           ret2Ptr[i]=work[i]-arrBg[pos2];
5111           castsDetected.insert(pos2);
5112         }
5113       else
5114         {
5115           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5116           throw INTERP_KERNEL::Exception(oss.str().c_str());
5117         }
5118     }
5119   ret3->alloc((int)castsDetected.size(),1);
5120   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5121   castArr=ret1.retn();
5122   rankInsideCast=ret2.retn();
5123   castsPresent=ret3.retn();
5124 }
5125
5126 /*!
5127  * 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 ).
5128  * 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 ).
5129  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5130  *
5131  * \param [out] strt - the start of the range (included) if true is returned.
5132  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5133  * \param [out] stteepp - the step of the range if true is returned.
5134  * \return the verdict of the check.
5135  *
5136  * \sa DataArray::GetNumberOfItemGivenBES
5137  */
5138 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5139 {
5140   checkAllocated();
5141   if(getNumberOfComponents()!=1)
5142     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5143   int nbTuples(getNumberOfTuples());
5144   if(nbTuples==0)
5145     { strt=0; sttoopp=0; stteepp=1; return true; }
5146   const int *pt(begin());
5147   strt=*pt; 
5148   if(nbTuples==1)
5149     { sttoopp=strt+1; stteepp=1; return true; }
5150   strt=*pt; sttoopp=pt[nbTuples-1];
5151   if(strt==sttoopp)
5152     return false;
5153   if(sttoopp>strt)
5154     {
5155       sttoopp++;
5156       int a(sttoopp-1-strt),tmp(strt);
5157       if(a%(nbTuples-1)!=0)
5158         return false;
5159       stteepp=a/(nbTuples-1);
5160       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5161         if(pt[i]!=tmp)
5162           return false;
5163       return true;
5164     }
5165   else
5166     {
5167       sttoopp--;
5168       int a(strt-sttoopp-1),tmp(strt);
5169       if(a%(nbTuples-1)!=0)
5170         return false;
5171       stteepp=-(a/(nbTuples-1));
5172       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5173         if(pt[i]!=tmp)
5174           return false;
5175       return true;
5176     }
5177 }
5178
5179 /*!
5180  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5181  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5182  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5183  * new value in place \a indArr[ \a v ] is i.
5184  *  \param [in] indArrBg - the array holding indices within the result array to assign
5185  *         indices of values of \a this array pointing to values of \a indArrBg.
5186  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5187  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5188  *  \return DataArrayInt * - the new instance of DataArrayInt.
5189  *          The caller is to delete this result array using decrRef() as it is no more
5190  *          needed.
5191  *  \throw If \a this->getNumberOfComponents() != 1.
5192  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5193  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5194  */
5195 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5196 {
5197   checkAllocated();
5198   if(getNumberOfComponents()!=1)
5199     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5200   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5201   int nbOfTuples=getNumberOfTuples();
5202   const int *pt=getConstPointer();
5203   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5204   ret->alloc(nbOfTuples,1);
5205   ret->fillWithValue(-1);
5206   int *tmp=ret->getPointer();
5207   for(int i=0;i<nbOfTuples;i++,pt++)
5208     {
5209       if(*pt>=0 && *pt<nbElemsIn)
5210         {
5211           int pos=indArrBg[*pt];
5212           if(pos>=0 && pos<nbOfTuples)
5213             tmp[pos]=i;
5214           else
5215             {
5216               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5217               throw INTERP_KERNEL::Exception(oss.str().c_str());
5218             }
5219         }
5220       else
5221         {
5222           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5223           throw INTERP_KERNEL::Exception(oss.str().c_str());
5224         }
5225     }
5226   return ret.retn();
5227 }
5228
5229 /*!
5230  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5231  * from values of \a this array, which is supposed to contain a renumbering map in 
5232  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5233  * To know how to use the renumbering maps see \ref numbering.
5234  *  \param [in] newNbOfElem - the number of tuples in the result array.
5235  *  \return DataArrayInt * - the new instance of DataArrayInt.
5236  *          The caller is to delete this result array using decrRef() as it is no more
5237  *          needed.
5238  * 
5239  *  \if ENABLE_EXAMPLES
5240  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5241  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5242  *  \endif
5243  */
5244 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5245 {
5246   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5247   ret->alloc(newNbOfElem,1);
5248   int nbOfOldNodes=getNumberOfTuples();
5249   const int *old2New=getConstPointer();
5250   int *pt=ret->getPointer();
5251   for(int i=0;i!=nbOfOldNodes;i++)
5252     {
5253       int newp(old2New[i]);
5254       if(newp!=-1)
5255         {
5256           if(newp>=0 && newp<newNbOfElem)
5257             pt[newp]=i;
5258           else
5259             {
5260               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5261               throw INTERP_KERNEL::Exception(oss.str().c_str());
5262             }
5263         }
5264     }
5265   return ret.retn();
5266 }
5267
5268 /*!
5269  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5270  * 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]
5271  */
5272 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5273 {
5274   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5275   ret->alloc(newNbOfElem,1);
5276   int nbOfOldNodes=getNumberOfTuples();
5277   const int *old2New=getConstPointer();
5278   int *pt=ret->getPointer();
5279   for(int i=nbOfOldNodes-1;i>=0;i--)
5280     {
5281       int newp(old2New[i]);
5282       if(newp!=-1)
5283         {
5284           if(newp>=0 && newp<newNbOfElem)
5285             pt[newp]=i;
5286           else
5287             {
5288               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5289               throw INTERP_KERNEL::Exception(oss.str().c_str());
5290             }
5291         }
5292     }
5293   return ret.retn();
5294 }
5295
5296 /*!
5297  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5298  * from values of \a this array, which is supposed to contain a renumbering map in 
5299  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5300  * To know how to use the renumbering maps see \ref numbering.
5301  *  \param [in] newNbOfElem - the number of tuples in the result array.
5302  *  \return DataArrayInt * - the new instance of DataArrayInt.
5303  *          The caller is to delete this result array using decrRef() as it is no more
5304  *          needed.
5305  * 
5306  *  \if ENABLE_EXAMPLES
5307  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5308  *
5309  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5310  *  \endif
5311  */
5312 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5313 {
5314   checkAllocated();
5315   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5316   ret->alloc(oldNbOfElem,1);
5317   const int *new2Old=getConstPointer();
5318   int *pt=ret->getPointer();
5319   std::fill(pt,pt+oldNbOfElem,-1);
5320   int nbOfNewElems=getNumberOfTuples();
5321   for(int i=0;i<nbOfNewElems;i++)
5322     {
5323       int v(new2Old[i]);
5324       if(v>=0 && v<oldNbOfElem)
5325         pt[v]=i;
5326       else
5327         {
5328           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5329           throw INTERP_KERNEL::Exception(oss.str().c_str());
5330         }
5331     }
5332   return ret.retn();
5333 }
5334
5335 /*!
5336  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5337  * mismatch is given.
5338  * 
5339  * \param [in] other the instance to be compared with \a this
5340  * \param [out] reason In case of inequality returns the reason.
5341  * \sa DataArrayInt::isEqual
5342  */
5343 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5344 {
5345   if(!areInfoEqualsIfNotWhy(other,reason))
5346     return false;
5347   return _mem.isEqual(other._mem,0,reason);
5348 }
5349
5350 /*!
5351  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5352  * \ref MEDCouplingArrayBasicsCompare.
5353  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5354  *  \return bool - \a true if the two arrays are equal, \a false else.
5355  */
5356 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5357 {
5358   std::string tmp;
5359   return isEqualIfNotWhy(other,tmp);
5360 }
5361
5362 /*!
5363  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5364  * \ref MEDCouplingArrayBasicsCompare.
5365  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5366  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5367  */
5368 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5369 {
5370   std::string tmp;
5371   return _mem.isEqual(other._mem,0,tmp);
5372 }
5373
5374 /*!
5375  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5376  * performed on sorted value sequences.
5377  * For more info see\ref MEDCouplingArrayBasicsCompare.
5378  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5379  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5380  */
5381 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5382 {
5383   MCAuto<DataArrayInt> a=deepCopy();
5384   MCAuto<DataArrayInt> b=other.deepCopy();
5385   a->sort();
5386   b->sort();
5387   return a->isEqualWithoutConsideringStr(*b);
5388 }
5389
5390 /*!
5391  * This method compares content of input vector \a v and \a this.
5392  * 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.
5393  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5394  *
5395  * \param [in] v - the vector of 'flags' to be compared with \a this.
5396  *
5397  * \throw If \a this is not sorted ascendingly.
5398  * \throw If \a this has not exactly one component.
5399  * \throw If \a this is not allocated.
5400  */
5401 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5402 {
5403   checkAllocated();
5404   if(getNumberOfComponents()!=1)
5405     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5406   const int *w(begin()),*end2(end());
5407   int refVal=-std::numeric_limits<int>::max();
5408   int i=0;
5409   std::vector<bool>::const_iterator it(v.begin());
5410   for(;it!=v.end();it++,i++)
5411     {
5412       if(*it)
5413         {
5414           if(w!=end2)
5415             {
5416               if(*w++==i)
5417                 {
5418                   if(i>refVal)
5419                     refVal=i;
5420                   else
5421                     {
5422                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5423                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5424                     }
5425                 }
5426               else
5427                 return false;
5428             }
5429           else
5430             return false;
5431         }
5432     }
5433   return w==end2;
5434 }
5435
5436 /*!
5437  * 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
5438  * put True to the corresponding entry in \a vec.
5439  * \a vec is expected to be with the same size than the number of tuples of \a this.
5440  *
5441  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5442  */
5443 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5444 {
5445   checkAllocated();
5446   if(getNumberOfComponents()!=1)
5447     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5448   int nbOfTuples(getNumberOfTuples());
5449   if(nbOfTuples!=(int)vec.size())
5450     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5451   const int *pt(begin());
5452   for(int i=0;i<nbOfTuples;i++)
5453     if(pt[i]==val)
5454       vec[i]=true;
5455 }
5456
5457 /*!
5458  * 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
5459  * put True to the corresponding entry in \a vec.
5460  * \a vec is expected to be with the same size than the number of tuples of \a this.
5461  * 
5462  *  \sa DataArrayInt::switchOnTupleEqualTo.
5463  */
5464 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5465 {
5466   checkAllocated();
5467   if(getNumberOfComponents()!=1)
5468     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5469   int nbOfTuples(getNumberOfTuples());
5470   if(nbOfTuples!=(int)vec.size())
5471     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5472   const int *pt(begin());
5473   for(int i=0;i<nbOfTuples;i++)
5474     if(pt[i]!=val)
5475       vec[i]=true;
5476 }
5477
5478 /*!
5479  * Computes for each tuple the sum of number of components values in the tuple and return it.
5480  * 
5481  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5482  *          same number of tuples as \a this array and one component.
5483  *          The caller is to delete this result array using decrRef() as it is no more
5484  *          needed.
5485  *  \throw If \a this is not allocated.
5486  */
5487 DataArrayInt *DataArrayInt::sumPerTuple() const
5488 {
5489   checkAllocated();
5490   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5491   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5492   ret->alloc(nbOfTuple,1);
5493   const int *src(getConstPointer());
5494   int *dest(ret->getPointer());
5495   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5496     *dest=std::accumulate(src,src+nbOfComp,0);
5497   return ret.retn();
5498 }
5499
5500 /*!
5501  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5502  * If not an exception is thrown.
5503  *  \param [in] increasing - if \a true, the array values should be increasing.
5504  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5505  *         increasing arg.
5506  *  \throw If \a this->getNumberOfComponents() != 1.
5507  *  \throw If \a this is not allocated.
5508  */
5509 void DataArrayInt::checkMonotonic(bool increasing) const
5510 {
5511   if(!isMonotonic(increasing))
5512     {
5513       if (increasing)
5514         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5515       else
5516         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5517     }
5518 }
5519
5520 /*!
5521  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5522  *  \param [in] increasing - if \a true, array values should be increasing.
5523  *  \return bool - \a true if values change in accordance with \a increasing arg.
5524  *  \throw If \a this->getNumberOfComponents() != 1.
5525  *  \throw If \a this is not allocated.
5526  */
5527 bool DataArrayInt::isMonotonic(bool increasing) const
5528 {
5529   checkAllocated();
5530   if(getNumberOfComponents()!=1)
5531     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5532   int nbOfElements=getNumberOfTuples();
5533   const int *ptr=getConstPointer();
5534   if(nbOfElements==0)
5535     return true;
5536   int ref=ptr[0];
5537   if(increasing)
5538     {
5539       for(int i=1;i<nbOfElements;i++)
5540         {
5541           if(ptr[i]>=ref)
5542             ref=ptr[i];
5543           else
5544             return false;
5545         }
5546     }
5547   else
5548     {
5549       for(int i=1;i<nbOfElements;i++)
5550         {
5551           if(ptr[i]<=ref)
5552             ref=ptr[i];
5553           else
5554             return false;
5555         }
5556     }
5557   return true;
5558 }
5559
5560 /*!
5561  * This method check that array consistently INCREASING or DECREASING in value.
5562  */
5563 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5564 {
5565   checkAllocated();
5566   if(getNumberOfComponents()!=1)
5567     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5568   int nbOfElements=getNumberOfTuples();
5569   const int *ptr=getConstPointer();
5570   if(nbOfElements==0)
5571     return true;
5572   int ref=ptr[0];
5573   if(increasing)
5574     {
5575       for(int i=1;i<nbOfElements;i++)
5576         {
5577           if(ptr[i]>ref)
5578             ref=ptr[i];
5579           else
5580             return false;
5581         }
5582     }
5583   else
5584     {
5585       for(int i=1;i<nbOfElements;i++)
5586         {
5587           if(ptr[i]<ref)
5588             ref=ptr[i];
5589           else
5590             return false;
5591         }
5592     }
5593   return true;
5594 }
5595
5596 /*!
5597  * This method check that array consistently INCREASING or DECREASING in value.
5598  */
5599 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5600 {
5601   if(!isStrictlyMonotonic(increasing))
5602     {
5603       if (increasing)
5604         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5605       else
5606         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5607     }
5608 }
5609
5610 /*!
5611  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5612  * one-dimensional arrays that must be of the same length. The result array describes
5613  * correspondence between \a this and \a other arrays, so that 
5614  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5615  * not possible because some element in \a other is not in \a this, an exception is thrown.
5616  *  \param [in] other - an array to compute permutation to.
5617  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5618  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5619  * no more needed.
5620  *  \throw If \a this->getNumberOfComponents() != 1.
5621  *  \throw If \a other->getNumberOfComponents() != 1.
5622  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5623  *  \throw If \a other includes a value which is not in \a this array.
5624  * 
5625  *  \if ENABLE_EXAMPLES
5626  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5627  *
5628  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5629  *  \endif
5630  */
5631 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5632 {
5633   checkAllocated();
5634   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5635     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5636   int nbTuple=getNumberOfTuples();
5637   other.checkAllocated();
5638   if(nbTuple!=other.getNumberOfTuples())
5639     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5640   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5641   ret->alloc(nbTuple,1);
5642   ret->fillWithValue(-1);
5643   const int *pt=getConstPointer();
5644   std::map<int,int> mm;
5645   for(int i=0;i<nbTuple;i++)
5646     mm[pt[i]]=i;
5647   pt=other.getConstPointer();
5648   int *retToFill=ret->getPointer();
5649   for(int i=0;i<nbTuple;i++)
5650     {
5651       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5652       if(it==mm.end())
5653         {
5654           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5655           throw INTERP_KERNEL::Exception(oss.str().c_str());
5656         }
5657       retToFill[i]=(*it).second;
5658     }
5659   return ret.retn();
5660 }
5661
5662 /*!
5663  * Elements of \a partOfThis are expected to be included in \a this.
5664  * The returned array \a ret is so that this[ret]==partOfThis
5665  *
5666  * 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]
5667  * the return array will contain [3,2,5,7].
5668  *
5669  * \a this is expected to be a 1 compo allocated array.
5670  * \param [in] partOfThis - A 1 compo allocated array
5671  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5672  * \throw if two same element is present twice in \a this
5673  * \throw if an element in \a partOfThis is \b NOT in \a this.
5674  */
5675 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5676 {
5677   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5678     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5679   checkAllocated(); partOfThis.checkAllocated();
5680   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5681   const int *thisPt(begin()),*pt(partOfThis.begin());
5682   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5683   ret->alloc(nbTuples,1);
5684   int *retPt(ret->getPointer());
5685   std::map<int,int> m;
5686   for(int i=0;i<thisNbTuples;i++,thisPt++)
5687     m[*thisPt]=i;
5688   if(m.size()!=thisNbTuples)
5689     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5690   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5691     {
5692       std::map<int,int>::const_iterator it(m.find(*pt));
5693       if(it!=m.end())
5694         *retPt=(*it).second;
5695       else
5696         {
5697           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5698           throw INTERP_KERNEL::Exception(oss.str());
5699         }
5700     }
5701   return ret.retn();
5702 }
5703
5704 void DataArrayInt::aggregate(const DataArrayInt *other)
5705 {
5706   if(!other)
5707     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5708   if(getNumberOfComponents()!=other->getNumberOfComponents())
5709     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5710   _mem.insertAtTheEnd(other->begin(),other->end());
5711 }
5712
5713 /*!
5714  * Returns a new DataArrayInt holding the same values as \a this array but differently
5715  * arranged in memory. If \a this array holds 2 components of 3 values:
5716  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5717  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5718  *  \warning Do not confuse this method with transpose()!
5719  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5720  *          is to delete using decrRef() as it is no more needed.
5721  *  \throw If \a this is not allocated.
5722  */
5723 DataArrayInt *DataArrayInt::fromNoInterlace() const
5724 {
5725   checkAllocated();
5726   if(_mem.isNull())
5727     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5728   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5729   DataArrayInt *ret=DataArrayInt::New();
5730   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5731   return ret;
5732 }
5733
5734 /*!
5735  * Returns a new DataArrayInt holding the same values as \a this array but differently
5736  * arranged in memory. If \a this array holds 2 components of 3 values:
5737  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5738  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5739  *  \warning Do not confuse this method with transpose()!
5740  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5741  *          is to delete using decrRef() as it is no more needed.
5742  *  \throw If \a this is not allocated.
5743  */
5744 DataArrayInt *DataArrayInt::toNoInterlace() const
5745 {
5746   checkAllocated();
5747   if(_mem.isNull())
5748     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5749   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5750   DataArrayInt *ret=DataArrayInt::New();
5751   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5752   return ret;
5753 }
5754
5755 /*!
5756  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5757  * This map, if applied to \a this array, would make it sorted. For example, if
5758  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5759  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5760  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5761  * This method is useful for renumbering (in MED file for example). For more info
5762  * on renumbering see \ref numbering.
5763  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5764  *          array using decrRef() as it is no more needed.
5765  *  \throw If \a this is not allocated.
5766  *  \throw If \a this->getNumberOfComponents() != 1.
5767  *  \throw If there are equal values in \a this array.
5768  */
5769 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5770 {
5771   checkAllocated();
5772   if(getNumberOfComponents()!=1)
5773     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5774   int nbTuples=getNumberOfTuples();
5775   const int *pt=getConstPointer();
5776   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5777   DataArrayInt *ret=DataArrayInt::New();
5778   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5779   return ret;
5780 }
5781
5782 /*!
5783  * 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
5784  * input array \a ids2.
5785  * \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.
5786  * 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
5787  * inversely.
5788  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5789  *
5790  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5791  *          array using decrRef() as it is no more needed.
5792  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5793  * 
5794  */
5795 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5796 {
5797   if(!ids1 || !ids2)
5798     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5799   if(!ids1->isAllocated() || !ids2->isAllocated())
5800     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5801   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5802     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5803   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5804     {
5805       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 !";
5806       throw INTERP_KERNEL::Exception(oss.str().c_str());
5807     }
5808   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5809   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5810   p1->sort(true); p2->sort(true);
5811   if(!p1->isEqualWithoutConsideringStr(*p2))
5812     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5813   p1=ids1->checkAndPreparePermutation();
5814   p2=ids2->checkAndPreparePermutation();
5815   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5816   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5817   return p2.retn();
5818 }
5819
5820 /*!
5821  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5822  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5823  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5824  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5825  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5826  * The first of out arrays returns indices of elements of \a this array, grouped by their
5827  * place in the set \a B. The second out array is the index of the first one; it shows how
5828  * many elements of \a A are mapped into each element of \a B. <br>
5829  * For more info on
5830  * mapping and its usage in renumbering see \ref numbering. <br>
5831  * \b Example:
5832  * - \a this: [0,3,2,3,2,2,1,2]
5833  * - \a targetNb: 4
5834  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5835  * - \a arrI: [0,1,2,6,8]
5836  *
5837  * This result means: <br>
5838  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5839  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5840  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5841  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5842  * \a arrI[ 2+1 ]]); <br> etc.
5843  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5844  *         than the maximal value of \a A.
5845  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5846  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5847  *         this array using decrRef() as it is no more needed.
5848  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5849  *         elements of \a this. The caller is to delete this array using decrRef() as it
5850  *         is no more needed.
5851  *  \throw If \a this is not allocated.
5852  *  \throw If \a this->getNumberOfComponents() != 1.
5853  *  \throw If any value in \a this is more or equal to \a targetNb.
5854  */
5855 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5856 {
5857   checkAllocated();
5858   if(getNumberOfComponents()!=1)
5859     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5860   int nbOfTuples=getNumberOfTuples();
5861   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5862   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5863   retI->alloc(targetNb+1,1);
5864   const int *input=getConstPointer();
5865   std::vector< std::vector<int> > tmp(targetNb);
5866   for(int i=0;i<nbOfTuples;i++)
5867     {
5868       int tmp2=input[i];
5869       if(tmp2>=0 && tmp2<targetNb)
5870         tmp[tmp2].push_back(i);
5871       else
5872         {
5873           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5874           throw INTERP_KERNEL::Exception(oss.str().c_str());
5875         }
5876     }
5877   int *retIPtr=retI->getPointer();
5878   *retIPtr=0;
5879   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5880     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5881   if(nbOfTuples!=retI->getIJ(targetNb,0))
5882     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5883   ret->alloc(nbOfTuples,1);
5884   int *retPtr=ret->getPointer();
5885   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5886     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5887   arr=ret.retn();
5888   arrI=retI.retn();
5889 }
5890
5891
5892 /*!
5893  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5894  * from a zip representation of a surjective format (returned e.g. by
5895  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5896  * for example). The result array minimizes the permutation. <br>
5897  * For more info on renumbering see \ref numbering. <br>
5898  * \b Example: <br>
5899  * - \a nbOfOldTuples: 10 
5900  * - \a arr          : [0,3, 5,7,9]
5901  * - \a arrIBg       : [0,2,5]
5902  * - \a newNbOfTuples: 7
5903  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5904  *
5905  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5906  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5907  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5908  *         (indices of) equal values. Its every element (except the last one) points to
5909  *         the first element of a group of equal values.
5910  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5911  *          arrIBg is \a arrIEnd[ -1 ].
5912  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5913  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5914  *          array using decrRef() as it is no more needed.
5915  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5916  */
5917 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5918 {
5919   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5920   ret->alloc(nbOfOldTuples,1);
5921   int *pt=ret->getPointer();
5922   std::fill(pt,pt+nbOfOldTuples,-1);
5923   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5924   const int *cIPtr=arrIBg;
5925   for(int i=0;i<nbOfGrps;i++)
5926     pt[arr[cIPtr[i]]]=-(i+2);
5927   int newNb=0;
5928   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5929     {
5930       if(pt[iNode]<0)
5931         {
5932           if(pt[iNode]==-1)
5933             pt[iNode]=newNb++;
5934           else
5935             {
5936               int grpId=-(pt[iNode]+2);
5937               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5938                 {
5939                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5940                     pt[arr[j]]=newNb;
5941                   else
5942                     {
5943                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5944                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5945                     }
5946                 }
5947               newNb++;
5948             }
5949         }
5950     }
5951   newNbOfTuples=newNb;
5952   return ret.retn();
5953 }
5954
5955 /*!
5956  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5957  * which if applied to \a this array would make it sorted ascendingly.
5958  * For more info on renumbering see \ref numbering. <br>
5959  * \b Example: <br>
5960  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5961  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5962  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5963  *
5964  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5965  *          array using decrRef() as it is no more needed.
5966  *  \throw If \a this is not allocated.
5967  *  \throw If \a this->getNumberOfComponents() != 1.
5968  */
5969 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5970 {
5971   checkAllocated();
5972   if(getNumberOfComponents()!=1)
5973     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5974   int nbOfTuples=getNumberOfTuples();
5975   const int *pt=getConstPointer();
5976   std::map<int,int> m;
5977   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5978   ret->alloc(nbOfTuples,1);
5979   int *opt=ret->getPointer();
5980   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5981     {
5982       int val=*pt;
5983       std::map<int,int>::iterator it=m.find(val);
5984       if(it!=m.end())
5985         {
5986           *opt=(*it).second;
5987           (*it).second++;
5988         }
5989       else
5990         {
5991           *opt=0;
5992           m.insert(std::pair<int,int>(val,1));
5993         }
5994     }
5995   int sum=0;
5996   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5997     {
5998       int vt=(*it).second;
5999       (*it).second=sum;
6000       sum+=vt;
6001     }
6002   pt=getConstPointer();
6003   opt=ret->getPointer();
6004   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6005     *opt+=m[*pt];
6006   //
6007   return ret.retn();
6008 }
6009
6010 /*!
6011  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
6012  * iota(). This method is particularly useful for DataArrayInt instances that represent
6013  * a renumbering array, to check if there is a real need in renumbering.
6014  * This method checks than \a this can be considered as an identity mapping
6015  * of a set having \a sizeExpected elements into itself.
6016  *
6017  *  \param [in] sizeExpected - The number of elements expected.
6018  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6019  *  \throw If \a this is not allocated.
6020  *  \throw If \a this->getNumberOfComponents() != 1.
6021  */
6022 bool DataArrayInt::isIota(int sizeExpected) const
6023 {
6024   checkAllocated();
6025   if(getNumberOfComponents()!=1)
6026     return false;
6027   int nbOfTuples(getNumberOfTuples());
6028   if(nbOfTuples!=sizeExpected)
6029     return false;
6030   const int *pt=getConstPointer();
6031   for(int i=0;i<nbOfTuples;i++,pt++)
6032     if(*pt!=i)
6033       return false;
6034   return true;
6035 }
6036
6037 /*!
6038  * Checks if all values in \a this array are equal to \a val.
6039  *  \param [in] val - value to check equality of array values to.
6040  *  \return bool - \a true if all values are \a val.
6041  *  \throw If \a this is not allocated.
6042  *  \throw If \a this->getNumberOfComponents() != 1
6043  */
6044 bool DataArrayInt::isUniform(int val) const
6045 {
6046   checkAllocated();
6047   if(getNumberOfComponents()!=1)
6048     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6049   int nbOfTuples=getNumberOfTuples();
6050   const int *w=getConstPointer();
6051   const int *end2=w+nbOfTuples;
6052   for(;w!=end2;w++)
6053     if(*w!=val)
6054       return false;
6055   return true;
6056 }
6057
6058 /*!
6059  * Checks if all values in \a this array are unique.
6060  *  \return bool - \a true if condition above is true
6061  *  \throw If \a this is not allocated.
6062  *  \throw If \a this->getNumberOfComponents() != 1
6063  */
6064 bool DataArrayInt::hasUniqueValues() const
6065 {
6066   checkAllocated();
6067   if(getNumberOfComponents()!=1)
6068     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6069   int nbOfTuples(getNumberOfTuples());
6070   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
6071   if (s.size() != nbOfTuples)
6072     return false;
6073   return true;
6074 }
6075
6076 /*!
6077  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6078  * array to the new one.
6079  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6080  */
6081 DataArrayDouble *DataArrayInt::convertToDblArr() const
6082 {
6083   checkAllocated();
6084   DataArrayDouble *ret=DataArrayDouble::New();
6085   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6086   std::size_t nbOfVals=getNbOfElems();
6087   const int *src=getConstPointer();
6088   double *dest=ret->getPointer();
6089   std::copy(src,src+nbOfVals,dest);
6090   ret->copyStringInfoFrom(*this);
6091   return ret;
6092 }
6093
6094 /*!
6095  * Appends components of another array to components of \a this one, tuple by tuple.
6096  * So that the number of tuples of \a this array remains the same and the number of 
6097  * components increases.
6098  *  \param [in] other - the DataArrayInt to append to \a this one.
6099  *  \throw If \a this is not allocated.
6100  *  \throw If \a this and \a other arrays have different number of tuples.
6101  *
6102  *  \if ENABLE_EXAMPLES
6103  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6104  *
6105  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6106  *  \endif
6107  */
6108 void DataArrayInt::meldWith(const DataArrayInt *other)
6109 {
6110   if(!other)
6111     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6112   checkAllocated();
6113   other->checkAllocated();
6114   int nbOfTuples=getNumberOfTuples();
6115   if(nbOfTuples!=other->getNumberOfTuples())
6116     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6117   int nbOfComp1=getNumberOfComponents();
6118   int nbOfComp2=other->getNumberOfComponents();
6119   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6120   int *w=newArr;
6121   const int *inp1=getConstPointer();
6122   const int *inp2=other->getConstPointer();
6123   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6124     {
6125       w=std::copy(inp1,inp1+nbOfComp1,w);
6126       w=std::copy(inp2,inp2+nbOfComp2,w);
6127     }
6128   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6129   std::vector<int> compIds(nbOfComp2);
6130   for(int i=0;i<nbOfComp2;i++)
6131     compIds[i]=nbOfComp1+i;
6132   copyPartOfStringInfoFrom2(compIds,*other);
6133 }
6134
6135 /*!
6136  * Copy all components in a specified order from another DataArrayInt.
6137  * The specified components become the first ones in \a this array.
6138  * Both numerical and textual data is copied. The number of tuples in \a this and
6139  * the other array can be different.
6140  *  \param [in] a - the array to copy data from.
6141  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6142  *              to be copied.
6143  *  \throw If \a a is NULL.
6144  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6145  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6146  *
6147  *  \if ENABLE_EXAMPLES
6148  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6149  *  \endif
6150  */
6151 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6152 {
6153   if(!a)
6154     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6155   checkAllocated();
6156   a->checkAllocated();
6157   copyPartOfStringInfoFrom2(compoIds,*a);
6158   std::size_t partOfCompoSz=compoIds.size();
6159   int nbOfCompo=getNumberOfComponents();
6160   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6161   const int *ac=a->getConstPointer();
6162   int *nc=getPointer();
6163   for(int i=0;i<nbOfTuples;i++)
6164     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6165       nc[nbOfCompo*i+compoIds[j]]=*ac;
6166 }
6167
6168 /*!
6169  * Assign pointer to one array to a pointer to another appay. Reference counter of
6170  * \a arrayToSet is incremented / decremented.
6171  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6172  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6173  */
6174 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6175 {
6176   if(newArray!=arrayToSet)
6177     {
6178       if(arrayToSet)
6179         arrayToSet->decrRef();
6180       arrayToSet=newArray;
6181       if(arrayToSet)
6182         arrayToSet->incrRef();
6183     }
6184 }
6185
6186 DataArrayIntIterator *DataArrayInt::iterator()
6187 {
6188   return new DataArrayIntIterator(this);
6189 }
6190
6191 /*!
6192  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6193  * given one. The ids are sorted in the ascending order.
6194  *  \param [in] val - the value to find within \a this.
6195  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6196  *          array using decrRef() as it is no more needed.
6197  *  \throw If \a this is not allocated.
6198  *  \throw If \a this->getNumberOfComponents() != 1.
6199  *  \sa DataArrayInt::findIdsEqualTuple
6200  */
6201 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6202 {
6203   checkAllocated();
6204   if(getNumberOfComponents()!=1)
6205     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6206   const int *cptr(getConstPointer());
6207   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6208   int nbOfTuples=getNumberOfTuples();
6209   for(int i=0;i<nbOfTuples;i++,cptr++)
6210     if(*cptr==val)
6211       ret->pushBackSilent(i);
6212   return ret.retn();
6213 }
6214
6215 /*!
6216  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6217  * equal to a given one. 
6218  *  \param [in] val - the value to ignore within \a this.
6219  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6220  *          array using decrRef() as it is no more needed.
6221  *  \throw If \a this is not allocated.
6222  *  \throw If \a this->getNumberOfComponents() != 1.
6223  */
6224 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6225 {
6226   checkAllocated();
6227   if(getNumberOfComponents()!=1)
6228     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6229   const int *cptr(getConstPointer());
6230   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6231   int nbOfTuples=getNumberOfTuples();
6232   for(int i=0;i<nbOfTuples;i++,cptr++)
6233     if(*cptr!=val)
6234       ret->pushBackSilent(i);
6235   return ret.retn();
6236 }
6237
6238 /*!
6239  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6240  * This method is an extension of  DataArrayInt::findIdsEqual method.
6241  *
6242  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6243  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6244  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6245  *          array using decrRef() as it is no more needed.
6246  *  \throw If \a this is not allocated.
6247  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6248  * \throw If \a this->getNumberOfComponents() is equal to 0.
6249  * \sa DataArrayInt::findIdsEqual
6250  */
6251 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6252 {
6253   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6254   checkAllocated();
6255   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6256     {
6257       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6258       throw INTERP_KERNEL::Exception(oss.str().c_str());
6259     }
6260   if(nbOfCompoExp==0)
6261     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6262   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6263   const int *bg(begin()),*end2(end()),*work(begin());
6264   while(work!=end2)
6265     {
6266       work=std::search(work,end2,tupleBg,tupleEnd);
6267       if(work!=end2)
6268         {
6269           std::size_t pos(std::distance(bg,work));
6270           if(pos%nbOfCompoExp==0)
6271             ret->pushBackSilent(pos/nbOfCompoExp);
6272           work++;
6273         }
6274     }
6275   return ret.retn();
6276 }
6277
6278 /*!
6279  * Assigns \a newValue to all elements holding \a oldValue within \a this
6280  * one-dimensional array.
6281  *  \param [in] oldValue - the value to replace.
6282  *  \param [in] newValue - the value to assign.
6283  *  \return int - number of replacements performed.
6284  *  \throw If \a this is not allocated.
6285  *  \throw If \a this->getNumberOfComponents() != 1.
6286  */
6287 int DataArrayInt::changeValue(int oldValue, int newValue)
6288 {
6289   checkAllocated();
6290   if(getNumberOfComponents()!=1)
6291     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6292   if(oldValue==newValue)
6293     return 0;
6294   int *start(getPointer()),*end2(start+getNbOfElems());
6295   int ret(0);
6296   for(int *val=start;val!=end2;val++)
6297     {
6298       if(*val==oldValue)
6299         {
6300           *val=newValue;
6301           ret++;
6302         }
6303     }
6304   if(ret>0)
6305     declareAsNew();
6306   return ret;
6307 }
6308
6309 /*!
6310  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6311  * one of given values.
6312  *  \param [in] valsBg - an array of values to find within \a this array.
6313  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6314  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6315  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6316  *          array using decrRef() as it is no more needed.
6317  *  \throw If \a this->getNumberOfComponents() != 1.
6318  */
6319 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6320 {
6321   if(getNumberOfComponents()!=1)
6322     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6323   std::set<int> vals2(valsBg,valsEnd);
6324   const int *cptr(getConstPointer());
6325   std::vector<int> res;
6326   int nbOfTuples(getNumberOfTuples());
6327   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6328   for(int i=0;i<nbOfTuples;i++,cptr++)
6329     if(vals2.find(*cptr)!=vals2.end())
6330       ret->pushBackSilent(i);
6331   return ret.retn();
6332 }
6333
6334 /*!
6335  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6336  * equal to any of given values.
6337  *  \param [in] valsBg - an array of values to ignore within \a this array.
6338  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6339  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6340  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6341  *          array using decrRef() as it is no more needed.
6342  *  \throw If \a this->getNumberOfComponents() != 1.
6343  */
6344 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6345 {
6346   if(getNumberOfComponents()!=1)
6347     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6348   std::set<int> vals2(valsBg,valsEnd);
6349   const int *cptr=getConstPointer();
6350   std::vector<int> res;
6351   int nbOfTuples=getNumberOfTuples();
6352   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6353   for(int i=0;i<nbOfTuples;i++,cptr++)
6354     if(vals2.find(*cptr)==vals2.end())
6355       ret->pushBackSilent(i);
6356   return ret.retn();
6357 }
6358
6359 /*!
6360  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6361  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6362  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6363  * If any the tuple id is returned. If not -1 is returned.
6364  * 
6365  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6366  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6367  *
6368  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6369  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6370  */
6371 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6372 {
6373   checkAllocated();
6374   int nbOfCompo=getNumberOfComponents();
6375   if(nbOfCompo==0)
6376     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6377   if(nbOfCompo!=(int)tupl.size())
6378     {
6379       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6380       throw INTERP_KERNEL::Exception(oss.str().c_str());
6381     }
6382   const int *cptr=getConstPointer();
6383   std::size_t nbOfVals=getNbOfElems();
6384   for(const int *work=cptr;work!=cptr+nbOfVals;)
6385     {
6386       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6387       if(work!=cptr+nbOfVals)
6388         {
6389           if(std::distance(cptr,work)%nbOfCompo!=0)
6390             work++;
6391           else
6392             return std::distance(cptr,work)/nbOfCompo;
6393         }
6394     }
6395   return -1;
6396 }
6397
6398 /*!
6399  * This method searches the sequence specified in input parameter \b vals in \b this.
6400  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6401  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6402  * \sa DataArrayInt::findIdFirstEqualTuple
6403  */
6404 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6405 {
6406   checkAllocated();
6407   int nbOfCompo=getNumberOfComponents();
6408   if(nbOfCompo!=1)
6409     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6410   const int *cptr=getConstPointer();
6411   std::size_t nbOfVals=getNbOfElems();
6412   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6413   if(loc!=cptr+nbOfVals)
6414     return std::distance(cptr,loc);
6415   return -1;
6416 }
6417
6418 /*!
6419  * This method expects to be called when number of components of this is equal to one.
6420  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6421  * If not any tuple contains \b value -1 is returned.
6422  * \sa DataArrayInt::presenceOfValue
6423  */
6424 int DataArrayInt::findIdFirstEqual(int value) const
6425 {
6426   checkAllocated();
6427   if(getNumberOfComponents()!=1)
6428     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6429   const int *cptr=getConstPointer();
6430   int nbOfTuples=getNumberOfTuples();
6431   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6432   if(ret!=cptr+nbOfTuples)
6433     return std::distance(cptr,ret);
6434   return -1;
6435 }
6436
6437 /*!
6438  * This method expects to be called when number of components of this is equal to one.
6439  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6440  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6441  * \sa DataArrayInt::presenceOfValue
6442  */
6443 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6444 {
6445   checkAllocated();
6446   if(getNumberOfComponents()!=1)
6447     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6448   std::set<int> vals2(vals.begin(),vals.end());
6449   const int *cptr=getConstPointer();
6450   int nbOfTuples=getNumberOfTuples();
6451   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6452     if(vals2.find(*w)!=vals2.end())
6453       return std::distance(cptr,w);
6454   return -1;
6455 }
6456
6457 /*!
6458  * This method returns the number of values in \a this that are equals to input parameter \a value.
6459  * This method only works for single component array.
6460  *
6461  * \return a value in [ 0, \c this->getNumberOfTuples() )
6462  *
6463  * \throw If \a this is not allocated
6464  *
6465  */
6466 int DataArrayInt::count(int value) const
6467 {
6468   int ret=0;
6469   checkAllocated();
6470   if(getNumberOfComponents()!=1)
6471     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6472   const int *vals=begin();
6473   int nbOfTuples=getNumberOfTuples();
6474   for(int i=0;i<nbOfTuples;i++,vals++)
6475     if(*vals==value)
6476       ret++;
6477   return ret;
6478 }
6479
6480 /*!
6481  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6482  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6483  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6484  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6485  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6486  * \sa DataArrayInt::findIdFirstEqualTuple
6487  */
6488 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6489 {
6490   return findIdFirstEqualTuple(tupl)!=-1;
6491 }
6492
6493
6494 /*!
6495  * Returns \a true if a given value is present within \a this one-dimensional array.
6496  *  \param [in] value - the value to find within \a this array.
6497  *  \return bool - \a true in case if \a value is present within \a this array.
6498  *  \throw If \a this is not allocated.
6499  *  \throw If \a this->getNumberOfComponents() != 1.
6500  *  \sa findIdFirstEqual()
6501  */
6502 bool DataArrayInt::presenceOfValue(int value) const
6503 {
6504   return findIdFirstEqual(value)!=-1;
6505 }
6506
6507 /*!
6508  * This method expects to be called when number of components of this is equal to one.
6509  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6510  * If not any tuple contains one of the values contained in 'vals' false is returned.
6511  * \sa DataArrayInt::findIdFirstEqual
6512  */
6513 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6514 {
6515   return findIdFirstEqual(vals)!=-1;
6516 }
6517
6518 /*!
6519  * Accumulates values of each component of \a this array.
6520  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6521  *         by the caller, that is filled by this method with sum value for each
6522  *         component.
6523  *  \throw If \a this is not allocated.
6524  */
6525 void DataArrayInt::accumulate(int *res) const
6526 {
6527   checkAllocated();
6528   const int *ptr=getConstPointer();
6529   int nbTuple=getNumberOfTuples();
6530   int nbComps=getNumberOfComponents();
6531   std::fill(res,res+nbComps,0);
6532   for(int i=0;i<nbTuple;i++)
6533     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6534 }
6535
6536 int DataArrayInt::accumulate(int compId) const
6537 {
6538   checkAllocated();
6539   const int *ptr=getConstPointer();
6540   int nbTuple=getNumberOfTuples();
6541   int nbComps=getNumberOfComponents();
6542   if(compId<0 || compId>=nbComps)
6543     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6544   int ret=0;
6545   for(int i=0;i<nbTuple;i++)
6546     ret+=ptr[i*nbComps+compId];
6547   return ret;
6548 }
6549
6550 /*!
6551  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6552  * The returned array will have same number of components than \a this and number of tuples equal to
6553  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6554  *
6555  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6556  *
6557  * \param [in] bgOfIndex - begin (included) of the input index array.
6558  * \param [in] endOfIndex - end (excluded) of the input index array.
6559  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6560  * 
6561  * \throw If bgOfIndex or end is NULL.
6562  * \throw If input index array is not ascendingly sorted.
6563  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6564  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6565  */
6566 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6567 {
6568   if(!bgOfIndex || !endOfIndex)
6569     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6570   checkAllocated();
6571   int nbCompo=getNumberOfComponents();
6572   int nbOfTuples=getNumberOfTuples();
6573   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6574   if(sz<1)
6575     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6576   sz--;
6577   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6578   const int *w=bgOfIndex;
6579   if(*w<0 || *w>=nbOfTuples)
6580     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6581   const int *srcPt=begin()+(*w)*nbCompo;
6582   int *tmp=ret->getPointer();
6583   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6584     {
6585       std::fill(tmp,tmp+nbCompo,0);
6586       if(w[1]>=w[0])
6587         {
6588           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6589             {
6590               if(j>=0 && j<nbOfTuples)
6591                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6592               else
6593                 {
6594                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6595                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6596                 }
6597             }
6598         }
6599       else
6600         {
6601           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6602           throw INTERP_KERNEL::Exception(oss.str().c_str());
6603         }
6604     }
6605   ret->copyStringInfoFrom(*this);
6606   return ret.retn();
6607 }
6608
6609 /*!
6610  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6611  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6612  * offsetA2</em> and (2)
6613  * the number of component in the result array is same as that of each of given arrays.
6614  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6615  * Info on components is copied from the first of the given arrays. Number of components
6616  * in the given arrays must be the same.
6617  *  \param [in] a1 - an array to include in the result array.
6618  *  \param [in] a2 - another array to include in the result array.
6619  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6620  *  \return DataArrayInt * - the new instance of DataArrayInt.
6621  *          The caller is to delete this result array using decrRef() as it is no more
6622  *          needed.
6623  *  \throw If either \a a1 or \a a2 is NULL.
6624  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6625  */
6626 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6627 {
6628   if(!a1 || !a2)
6629     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6630   int nbOfComp=a1->getNumberOfComponents();
6631   if(nbOfComp!=a2->getNumberOfComponents())
6632     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6633   int nbOfTuple1=a1->getNumberOfTuples();
6634   int nbOfTuple2=a2->getNumberOfTuples();
6635   DataArrayInt *ret=DataArrayInt::New();
6636   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6637   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6638   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6639   ret->copyStringInfoFrom(*a1);
6640   return ret;
6641 }
6642
6643 /*!
6644  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6645  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6646  * the number of component in the result array is same as that of each of given arrays.
6647  * Info on components is copied from the first of the given arrays. Number of components
6648  * in the given arrays must be  the same.
6649  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6650  * not the object itself.
6651  *  \param [in] arr - a sequence of arrays to include in the result array.
6652  *  \return DataArrayInt * - the new instance of DataArrayInt.
6653  *          The caller is to delete this result array using decrRef() as it is no more
6654  *          needed.
6655  *  \throw If all arrays within \a arr are NULL.
6656  *  \throw If getNumberOfComponents() of arrays within \a arr.
6657  */
6658 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6659 {
6660   std::vector<const DataArrayInt *> a;
6661   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6662     if(*it4)
6663       a.push_back(*it4);
6664   if(a.empty())
6665     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6666   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6667   int nbOfComp=(*it)->getNumberOfComponents();
6668   int nbt=(*it++)->getNumberOfTuples();
6669   for(int i=1;it!=a.end();it++,i++)
6670     {
6671       if((*it)->getNumberOfComponents()!=nbOfComp)
6672         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6673       nbt+=(*it)->getNumberOfTuples();
6674     }
6675   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6676   ret->alloc(nbt,nbOfComp);
6677   int *pt=ret->getPointer();
6678   for(it=a.begin();it!=a.end();it++)
6679     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6680   ret->copyStringInfoFrom(*(a[0]));
6681   return ret.retn();
6682 }
6683
6684 /*!
6685  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6686  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6687  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6688  * 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.
6689  * 
6690  * \return DataArrayInt * - a new object to be managed by the caller.
6691  */
6692 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6693 {
6694   int retSz=1;
6695   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6696     {
6697       if(*it4)
6698         {
6699           (*it4)->checkAllocated();
6700           if((*it4)->getNumberOfComponents()!=1)
6701             {
6702               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6703               throw INTERP_KERNEL::Exception(oss.str().c_str());
6704             }
6705           int nbTupl=(*it4)->getNumberOfTuples();
6706           if(nbTupl<1)
6707             {
6708               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6709               throw INTERP_KERNEL::Exception(oss.str().c_str());
6710             }
6711           if((*it4)->front()!=0)
6712             {
6713               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6714               throw INTERP_KERNEL::Exception(oss.str().c_str());
6715             }
6716           retSz+=nbTupl-1;
6717         }
6718       else
6719         {
6720           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6721           throw INTERP_KERNEL::Exception(oss.str().c_str());
6722         }
6723     }
6724   if(arrs.empty())
6725     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6726   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6727   ret->alloc(retSz,1);
6728   int *pt=ret->getPointer(); *pt++=0;
6729   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6730     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6731   ret->copyStringInfoFrom(*(arrs[0]));
6732   return ret.retn();
6733 }
6734
6735 /*!
6736  * Returns in a single walk in \a this the min value and the max value in \a this.
6737  * \a this is expected to be single component array.
6738  *
6739  * \param [out] minValue - the min value in \a this.
6740  * \param [out] maxValue - the max value in \a this.
6741  *
6742  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6743  */
6744 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6745 {
6746   checkAllocated();
6747   if(getNumberOfComponents()!=1)
6748     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6749   int nbTuples(getNumberOfTuples());
6750   const int *pt(begin());
6751   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6752   for(int i=0;i<nbTuples;i++,pt++)
6753     {
6754       if(*pt<minValue)
6755         minValue=*pt;
6756       if(*pt>maxValue)
6757         maxValue=*pt;
6758     }
6759 }
6760
6761 /*!
6762  * Converts every value of \a this array to its absolute value.
6763  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6764  * should be called instead.
6765  *
6766  * \throw If \a this is not allocated.
6767  * \sa DataArrayInt::computeAbs
6768  */
6769 void DataArrayInt::abs()
6770 {
6771   checkAllocated();
6772   int *ptr(getPointer());
6773   std::size_t nbOfElems(getNbOfElems());
6774   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6775   declareAsNew();
6776 }
6777
6778 /*!
6779  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6780  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6781  *
6782  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6783  *         same number of tuples and component as \a this array.
6784  *         The caller is to delete this result array using decrRef() as it is no more
6785  *         needed.
6786  * \throw If \a this is not allocated.
6787  * \sa DataArrayInt::abs
6788  */
6789 DataArrayInt *DataArrayInt::computeAbs() const
6790 {
6791   checkAllocated();
6792   DataArrayInt *newArr(DataArrayInt::New());
6793   int nbOfTuples(getNumberOfTuples());
6794   int nbOfComp(getNumberOfComponents());
6795   newArr->alloc(nbOfTuples,nbOfComp);
6796   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6797   newArr->copyStringInfoFrom(*this);
6798   return newArr;
6799 }
6800
6801 /*!
6802  * Apply a liner function to a given component of \a this array, so that
6803  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6804  *  \param [in] a - the first coefficient of the function.
6805  *  \param [in] b - the second coefficient of the function.
6806  *  \param [in] compoId - the index of component to modify.
6807  *  \throw If \a this is not allocated.
6808  */
6809 void DataArrayInt::applyLin(int a, int b, int compoId)
6810 {
6811   checkAllocated();
6812   int *ptr=getPointer()+compoId;
6813   int nbOfComp=getNumberOfComponents();
6814   int nbOfTuple=getNumberOfTuples();
6815   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6816     *ptr=a*(*ptr)+b;
6817   declareAsNew();
6818 }
6819
6820 /*!
6821  * Apply a liner function to all elements of \a this array, so that
6822  * an element _x_ becomes \f$ a * x + b \f$.
6823  *  \param [in] a - the first coefficient of the function.
6824  *  \param [in] b - the second coefficient of the function.
6825  *  \throw If \a this is not allocated.
6826  */
6827 void DataArrayInt::applyLin(int a, int b)
6828 {
6829   checkAllocated();
6830   int *ptr=getPointer();
6831   std::size_t nbOfElems=getNbOfElems();
6832   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6833     *ptr=a*(*ptr)+b;
6834   declareAsNew();
6835 }
6836
6837 /*!
6838  * Returns a full copy of \a this array except that sign of all elements is reversed.
6839  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6840  *          same number of tuples and component as \a this array.
6841  *          The caller is to delete this result array using decrRef() as it is no more
6842  *          needed.
6843  *  \throw If \a this is not allocated.
6844  */
6845 DataArrayInt *DataArrayInt::negate() const
6846 {
6847   checkAllocated();
6848   DataArrayInt *newArr=DataArrayInt::New();
6849   int nbOfTuples=getNumberOfTuples();
6850   int nbOfComp=getNumberOfComponents();
6851   newArr->alloc(nbOfTuples,nbOfComp);
6852   const int *cptr=getConstPointer();
6853   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6854   newArr->copyStringInfoFrom(*this);
6855   return newArr;
6856 }
6857
6858 /*!
6859  * Modify all elements of \a this array, so that
6860  * an element _x_ becomes \f$ numerator / x \f$.
6861  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6862  *           array, all elements processed before detection of the zero element remain
6863  *           modified.
6864  *  \param [in] numerator - the numerator used to modify array elements.
6865  *  \throw If \a this is not allocated.
6866  *  \throw If there is an element equal to 0 in \a this array.
6867  */
6868 void DataArrayInt::applyInv(int numerator)
6869 {
6870   checkAllocated();
6871   int *ptr=getPointer();
6872   std::size_t nbOfElems=getNbOfElems();
6873   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6874     {
6875       if(*ptr!=0)
6876         {
6877           *ptr=numerator/(*ptr);
6878         }
6879       else
6880         {
6881           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6882           oss << " !";
6883           throw INTERP_KERNEL::Exception(oss.str().c_str());
6884         }
6885     }
6886   declareAsNew();
6887 }
6888
6889 /*!
6890  * Modify all elements of \a this array, so that
6891  * an element _x_ becomes \f$ x / val \f$.
6892  *  \param [in] val - the denominator used to modify array elements.
6893  *  \throw If \a this is not allocated.
6894  *  \throw If \a val == 0.
6895  */
6896 void DataArrayInt::applyDivideBy(int val)
6897 {
6898   if(val==0)
6899     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6900   checkAllocated();
6901   int *ptr=getPointer();
6902   std::size_t nbOfElems=getNbOfElems();
6903   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6904   declareAsNew();
6905 }
6906
6907 /*!
6908  * Modify all elements of \a this array, so that
6909  * an element _x_ becomes  <em> x % val </em>.
6910  *  \param [in] val - the divisor used to modify array elements.
6911  *  \throw If \a this is not allocated.
6912  *  \throw If \a val <= 0.
6913  */
6914 void DataArrayInt::applyModulus(int val)
6915 {
6916   if(val<=0)
6917     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6918   checkAllocated();
6919   int *ptr=getPointer();
6920   std::size_t nbOfElems=getNbOfElems();
6921   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6922   declareAsNew();
6923 }
6924
6925 /*!
6926  * This method works only on data array with one component.
6927  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6928  * this[*id] in [\b vmin,\b vmax)
6929  * 
6930  * \param [in] vmin begin of range. This value is included in range (included).
6931  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6932  * \return a newly allocated data array that the caller should deal with.
6933  *
6934  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6935  */
6936 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6937 {
6938   checkAllocated();
6939   if(getNumberOfComponents()!=1)
6940     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
6941   const int *cptr(begin());
6942   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6943   int nbOfTuples(getNumberOfTuples());
6944   for(int i=0;i<nbOfTuples;i++,cptr++)
6945     if(*cptr>=vmin && *cptr<vmax)
6946       ret->pushBackSilent(i);
6947   return ret.retn();
6948 }
6949
6950 /*!
6951  * This method works only on data array with one component.
6952  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6953  * this[*id] \b not in [\b vmin,\b vmax)
6954  * 
6955  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6956  * \param [in] vmax end of range. This value is included in range (included).
6957  * \return a newly allocated data array that the caller should deal with.
6958  * 
6959  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6960  */
6961 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6962 {
6963   checkAllocated();
6964   if(getNumberOfComponents()!=1)
6965     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
6966   const int *cptr(getConstPointer());
6967   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6968   int nbOfTuples(getNumberOfTuples());
6969   for(int i=0;i<nbOfTuples;i++,cptr++)
6970     if(*cptr<vmin || *cptr>=vmax)
6971       ret->pushBackSilent(i);
6972   return ret.retn();
6973 }
6974
6975 /*!
6976  * 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.
6977  *
6978  * \return a newly allocated data array that the caller should deal with.
6979  * \sa DataArrayInt::findIdsInRange
6980  */
6981 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6982 {
6983   checkAllocated();
6984   if(getNumberOfComponents()!=1)
6985     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
6986   const int *cptr(getConstPointer());
6987   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6988   int nbOfTuples(getNumberOfTuples());
6989   for(int i=0;i<nbOfTuples;i++,cptr++)
6990     if(*cptr<0)
6991       ret->pushBackSilent(i);
6992   return ret.retn();
6993 }
6994
6995 /*!
6996  * This method works only on data array with one component.
6997  * 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.
6998  * 
6999  * \param [in] vmin begin of range. This value is included in range (included).
7000  * \param [in] vmax end of range. This value is \b not included in range (excluded).
7001  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
7002 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
7003 {
7004   checkAllocated();
7005   if(getNumberOfComponents()!=1)
7006     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
7007   int nbOfTuples=getNumberOfTuples();
7008   bool ret=true;
7009   const int *cptr=getConstPointer();
7010   for(int i=0;i<nbOfTuples;i++,cptr++)
7011     {
7012       if(*cptr>=vmin && *cptr<vmax)
7013         { ret=ret && *cptr==i; }
7014       else
7015         {
7016           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
7017           throw INTERP_KERNEL::Exception(oss.str().c_str());
7018         }
7019     }
7020   return ret;
7021 }
7022
7023 /*!
7024  * Modify all elements of \a this array, so that
7025  * an element _x_ becomes <em> val % x </em>.
7026  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
7027  *           array, all elements processed before detection of the zero element remain
7028  *           modified.
7029  *  \param [in] val - the divident used to modify array elements.
7030  *  \throw If \a this is not allocated.
7031  *  \throw If there is an element equal to or less than 0 in \a this array.
7032  */
7033 void DataArrayInt::applyRModulus(int val)
7034 {
7035   checkAllocated();
7036   int *ptr=getPointer();
7037   std::size_t nbOfElems=getNbOfElems();
7038   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7039     {
7040       if(*ptr>0)
7041         {
7042           *ptr=val%(*ptr);
7043         }
7044       else
7045         {
7046           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7047           oss << " !";
7048           throw INTERP_KERNEL::Exception(oss.str().c_str());
7049         }
7050     }
7051   declareAsNew();
7052 }
7053
7054 /*!
7055  * Modify all elements of \a this array, so that
7056  * an element _x_ becomes <em> val ^ x </em>.
7057  *  \param [in] val - the value used to apply pow on all array elements.
7058  *  \throw If \a this is not allocated.
7059  *  \throw If \a val < 0.
7060  */
7061 void DataArrayInt::applyPow(int val)
7062 {
7063   checkAllocated();
7064   if(val<0)
7065     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7066   int *ptr=getPointer();
7067   std::size_t nbOfElems=getNbOfElems();
7068   if(val==0)
7069     {
7070       std::fill(ptr,ptr+nbOfElems,1);
7071       return ;
7072     }
7073   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7074     {
7075       int tmp=1;
7076       for(int j=0;j<val;j++)
7077         tmp*=*ptr;
7078       *ptr=tmp;
7079     }
7080   declareAsNew();
7081 }
7082
7083 /*!
7084  * Modify all elements of \a this array, so that
7085  * an element _x_ becomes \f$ val ^ x \f$.
7086  *  \param [in] val - the value used to apply pow on all array elements.
7087  *  \throw If \a this is not allocated.
7088  *  \throw If there is an element < 0 in \a this array.
7089  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7090  *           array, all elements processed before detection of the zero element remain
7091  *           modified.
7092  */
7093 void DataArrayInt::applyRPow(int val)
7094 {
7095   checkAllocated();
7096   int *ptr=getPointer();
7097   std::size_t nbOfElems=getNbOfElems();
7098   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7099     {
7100       if(*ptr>=0)
7101         {
7102           int tmp=1;
7103           for(int j=0;j<*ptr;j++)
7104             tmp*=val;
7105           *ptr=tmp;
7106         }
7107       else
7108         {
7109           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7110           oss << " !";
7111           throw INTERP_KERNEL::Exception(oss.str().c_str());
7112         }
7113     }
7114   declareAsNew();
7115 }
7116
7117 /*!
7118  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7119  * of components in the result array is a sum of the number of components of given arrays
7120  * and (2) the number of tuples in the result array is same as that of each of given
7121  * arrays. In other words the i-th tuple of result array includes all components of
7122  * i-th tuples of all given arrays.
7123  * Number of tuples in the given arrays must be the same.
7124  *  \param [in] a1 - an array to include in the result array.
7125  *  \param [in] a2 - another array to include in the result array.
7126  *  \return DataArrayInt * - the new instance of DataArrayInt.
7127  *          The caller is to delete this result array using decrRef() as it is no more
7128  *          needed.
7129  *  \throw If both \a a1 and \a a2 are NULL.
7130  *  \throw If any given array is not allocated.
7131  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7132  */
7133 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7134 {
7135   std::vector<const DataArrayInt *> arr(2);
7136   arr[0]=a1; arr[1]=a2;
7137   return Meld(arr);
7138 }
7139
7140 /*!
7141  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7142  * of components in the result array is a sum of the number of components of given arrays
7143  * and (2) the number of tuples in the result array is same as that of each of given
7144  * arrays. In other words the i-th tuple of result array includes all components of
7145  * i-th tuples of all given arrays.
7146  * Number of tuples in the given arrays must be  the same.
7147  *  \param [in] arr - a sequence of arrays to include in the result array.
7148  *  \return DataArrayInt * - the new instance of DataArrayInt.
7149  *          The caller is to delete this result array using decrRef() as it is no more
7150  *          needed.
7151  *  \throw If all arrays within \a arr are NULL.
7152  *  \throw If any given array is not allocated.
7153  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7154  */
7155 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7156 {
7157   std::vector<const DataArrayInt *> a;
7158   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7159     if(*it4)
7160       a.push_back(*it4);
7161   if(a.empty())
7162     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7163   std::vector<const DataArrayInt *>::const_iterator it;
7164   for(it=a.begin();it!=a.end();it++)
7165     (*it)->checkAllocated();
7166   it=a.begin();
7167   int nbOfTuples=(*it)->getNumberOfTuples();
7168   std::vector<int> nbc(a.size());
7169   std::vector<const int *> pts(a.size());
7170   nbc[0]=(*it)->getNumberOfComponents();
7171   pts[0]=(*it++)->getConstPointer();
7172   for(int i=1;it!=a.end();it++,i++)
7173     {
7174       if(nbOfTuples!=(*it)->getNumberOfTuples())
7175         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7176       nbc[i]=(*it)->getNumberOfComponents();
7177       pts[i]=(*it)->getConstPointer();
7178     }
7179   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7180   DataArrayInt *ret=DataArrayInt::New();
7181   ret->alloc(nbOfTuples,totalNbOfComp);
7182   int *retPtr=ret->getPointer();
7183   for(int i=0;i<nbOfTuples;i++)
7184     for(int j=0;j<(int)a.size();j++)
7185       {
7186         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7187         pts[j]+=nbc[j];
7188       }
7189   int k=0;
7190   for(int i=0;i<(int)a.size();i++)
7191     for(int j=0;j<nbc[i];j++,k++)
7192       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7193   return ret;
7194 }
7195
7196 /*!
7197  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7198  * The i-th item of the result array is an ID of a set of elements belonging to a
7199  * unique set of groups, which the i-th element is a part of. This set of elements
7200  * belonging to a unique set of groups is called \a family, so the result array contains
7201  * IDs of families each element belongs to.
7202  *
7203  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7204  * then there are 3 families:
7205  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7206  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7207  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7208  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7209  * stands for the element #3 which is in none of groups.
7210  *
7211  *  \param [in] groups - sequence of groups of element IDs.
7212  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7213  *         in \a groups.
7214  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7215  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7216  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7217  *         delete this array using decrRef() as it is no more needed.
7218  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7219  */
7220 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7221 {
7222   std::vector<const DataArrayInt *> groups2;
7223   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7224     if(*it4)
7225       groups2.push_back(*it4);
7226   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7227   ret->alloc(newNb,1);
7228   int *retPtr=ret->getPointer();
7229   std::fill(retPtr,retPtr+newNb,0);
7230   int fid=1;
7231   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7232     {
7233       const int *ptr=(*iter)->getConstPointer();
7234       std::size_t nbOfElem=(*iter)->getNbOfElems();
7235       int sfid=fid;
7236       for(int j=0;j<sfid;j++)
7237         {
7238           bool found=false;
7239           for(std::size_t i=0;i<nbOfElem;i++)
7240             {
7241               if(ptr[i]>=0 && ptr[i]<newNb)
7242                 {
7243                   if(retPtr[ptr[i]]==j)
7244                     {
7245                       retPtr[ptr[i]]=fid;
7246                       found=true;
7247                     }
7248                 }
7249               else
7250                 {
7251                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7252                   oss << ") !";
7253                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7254                 }
7255             }
7256           if(found)
7257             fid++;
7258         }
7259     }
7260   fidsOfGroups.clear();
7261   fidsOfGroups.resize(groups2.size());
7262   int grId=0;
7263   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7264     {
7265       std::set<int> tmp;
7266       const int *ptr=(*iter)->getConstPointer();
7267       std::size_t nbOfElem=(*iter)->getNbOfElems();
7268       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7269         tmp.insert(retPtr[*p]);
7270       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7271     }
7272   return ret.retn();
7273 }
7274
7275 /*!
7276  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7277  * arrays. The result array does not contain any duplicates and its values
7278  * are sorted in ascending order.
7279  *  \param [in] arr - sequence of DataArrayInt's to unite.
7280  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7281  *         array using decrRef() as it is no more needed.
7282  *  \throw If any \a arr[i] is not allocated.
7283  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7284  */
7285 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7286 {
7287   std::vector<const DataArrayInt *> a;
7288   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7289     if(*it4)
7290       a.push_back(*it4);
7291   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7292     {
7293       (*it)->checkAllocated();
7294       if((*it)->getNumberOfComponents()!=1)
7295         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7296     }
7297   //
7298   std::set<int> r;
7299   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7300     {
7301       const int *pt=(*it)->getConstPointer();
7302       int nbOfTuples=(*it)->getNumberOfTuples();
7303       r.insert(pt,pt+nbOfTuples);
7304     }
7305   DataArrayInt *ret=DataArrayInt::New();
7306   ret->alloc((int)r.size(),1);
7307   std::copy(r.begin(),r.end(),ret->getPointer());
7308   return ret;
7309 }
7310
7311 /*!
7312  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7313  * arrays. The result array does not contain any duplicates and its values
7314  * are sorted in ascending order.
7315  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7316  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7317  *         array using decrRef() as it is no more needed.
7318  *  \throw If any \a arr[i] is not allocated.
7319  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7320  */
7321 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7322 {
7323   std::vector<const DataArrayInt *> a;
7324   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7325     if(*it4)
7326       a.push_back(*it4);
7327   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7328     {
7329       (*it)->checkAllocated();
7330       if((*it)->getNumberOfComponents()!=1)
7331         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7332     }
7333   //
7334   std::set<int> r;
7335   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7336     {
7337       const int *pt=(*it)->getConstPointer();
7338       int nbOfTuples=(*it)->getNumberOfTuples();
7339       std::set<int> s1(pt,pt+nbOfTuples);
7340       if(it!=a.begin())
7341         {
7342           std::set<int> r2;
7343           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7344           r=r2;
7345         }
7346       else
7347         r=s1;
7348     }
7349   DataArrayInt *ret(DataArrayInt::New());
7350   ret->alloc((int)r.size(),1);
7351   std::copy(r.begin(),r.end(),ret->getPointer());
7352   return ret;
7353 }
7354
7355 /// @cond INTERNAL
7356 namespace MEDCouplingImpl
7357 {
7358   class OpSwitchedOn
7359   {
7360   public:
7361     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7362     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7363   private:
7364     int *_pt;
7365     int _cnt;
7366   };
7367
7368   class OpSwitchedOff
7369   {
7370   public:
7371     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7372     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7373   private:
7374     int *_pt;
7375     int _cnt;
7376   };
7377 }
7378 /// @endcond
7379
7380 /*!
7381  * This method returns the list of ids in ascending mode so that v[id]==true.
7382  */
7383 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7384 {
7385   int sz((int)std::count(v.begin(),v.end(),true));
7386   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7387   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7388   return ret.retn();
7389 }
7390
7391 /*!
7392  * This method returns the list of ids in ascending mode so that v[id]==false.
7393  */
7394 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7395 {
7396   int sz((int)std::count(v.begin(),v.end(),false));
7397   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7398   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7399   return ret.retn();
7400 }
7401
7402 /*!
7403  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7404  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7405  *
7406  * \param [in] v the input data structure to be translate into skyline format.
7407  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7408  * \param [out] dataIndex the second element of the skyline format.
7409  */
7410 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7411 {
7412   int sz((int)v.size());
7413   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7414   ret1->alloc(sz+1,1);
7415   int *pt(ret1->getPointer()); *pt=0;
7416   for(int i=0;i<sz;i++,pt++)
7417     pt[1]=pt[0]+(int)v[i].size();
7418   ret0->alloc(ret1->back(),1);
7419   pt=ret0->getPointer();
7420   for(int i=0;i<sz;i++)
7421     pt=std::copy(v[i].begin(),v[i].end(),pt);
7422   data=ret0.retn(); dataIndex=ret1.retn();
7423 }
7424
7425 /*!
7426  * Returns a new DataArrayInt which contains a complement of elements of \a this
7427  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7428  * \a nbOfElement) not present in \a this array.
7429  *  \param [in] nbOfElement - maximal size of the result array.
7430  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7431  *         array using decrRef() as it is no more needed.
7432  *  \throw If \a this is not allocated.
7433  *  \throw If \a this->getNumberOfComponents() != 1.
7434  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7435  *         nbOfElement ).
7436  */
7437 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7438 {
7439   checkAllocated();
7440   if(getNumberOfComponents()!=1)
7441     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7442   std::vector<bool> tmp(nbOfElement);
7443   const int *pt=getConstPointer();
7444   int nbOfTuples=getNumberOfTuples();
7445   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7446     if(*w>=0 && *w<nbOfElement)
7447       tmp[*w]=true;
7448     else
7449       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7450   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7451   DataArrayInt *ret=DataArrayInt::New();
7452   ret->alloc(nbOfRetVal,1);
7453   int j=0;
7454   int *retPtr=ret->getPointer();
7455   for(int i=0;i<nbOfElement;i++)
7456     if(!tmp[i])
7457       retPtr[j++]=i;
7458   return ret;
7459 }
7460
7461 /*!
7462  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7463  * from an \a other one-dimensional array.
7464  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7465  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7466  *         caller is to delete this array using decrRef() as it is no more needed.
7467  *  \throw If \a other is NULL.
7468  *  \throw If \a other is not allocated.
7469  *  \throw If \a other->getNumberOfComponents() != 1.
7470  *  \throw If \a this is not allocated.
7471  *  \throw If \a this->getNumberOfComponents() != 1.
7472  *  \sa DataArrayInt::buildSubstractionOptimized()
7473  */
7474 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7475 {
7476   if(!other)
7477     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7478   checkAllocated();
7479   other->checkAllocated();
7480   if(getNumberOfComponents()!=1)
7481     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7482   if(other->getNumberOfComponents()!=1)
7483     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7484   const int *pt=getConstPointer();
7485   int nbOfTuples=getNumberOfTuples();
7486   std::set<int> s1(pt,pt+nbOfTuples);
7487   pt=other->getConstPointer();
7488   nbOfTuples=other->getNumberOfTuples();
7489   std::set<int> s2(pt,pt+nbOfTuples);
7490   std::vector<int> r;
7491   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7492   DataArrayInt *ret=DataArrayInt::New();
7493   ret->alloc((int)r.size(),1);
7494   std::copy(r.begin(),r.end(),ret->getPointer());
7495   return ret;
7496 }
7497
7498 /*!
7499  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7500  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7501  * 
7502  * \param [in] other an array with one component and expected to be sorted ascendingly.
7503  * \ret list of ids in \a this but not in \a other.
7504  * \sa DataArrayInt::buildSubstraction
7505  */
7506 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7507 {
7508   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7509   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7510   checkAllocated(); other->checkAllocated();
7511   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7512   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7513   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7514   const int *work1(pt1Bg),*work2(pt2Bg);
7515   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7516   for(;work1!=pt1End;work1++)
7517     {
7518       if(work2!=pt2End && *work1==*work2)
7519         work2++;
7520       else
7521         ret->pushBackSilent(*work1);
7522     }
7523   return ret.retn();
7524 }
7525
7526
7527 /*!
7528  * Returns a new DataArrayInt which contains all elements of \a this and a given
7529  * one-dimensional arrays. The result array does not contain any duplicates
7530  * and its values are sorted in ascending order.
7531  *  \param [in] other - an array to unite with \a this one.
7532  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7533  *         array using decrRef() as it is no more needed.
7534  *  \throw If \a this or \a other is not allocated.
7535  *  \throw If \a this->getNumberOfComponents() != 1.
7536  *  \throw If \a other->getNumberOfComponents() != 1.
7537  */
7538 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7539 {
7540   std::vector<const DataArrayInt *>arrs(2);
7541   arrs[0]=this; arrs[1]=other;
7542   return BuildUnion(arrs);
7543 }
7544
7545
7546 /*!
7547  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7548  * one-dimensional arrays. The result array does not contain any duplicates
7549  * and its values are sorted in ascending order.
7550  *  \param [in] other - an array to intersect with \a this one.
7551  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7552  *         array using decrRef() as it is no more needed.
7553  *  \throw If \a this or \a other is not allocated.
7554  *  \throw If \a this->getNumberOfComponents() != 1.
7555  *  \throw If \a other->getNumberOfComponents() != 1.
7556  */
7557 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7558 {
7559   std::vector<const DataArrayInt *>arrs(2);
7560   arrs[0]=this; arrs[1]=other;
7561   return BuildIntersection(arrs);
7562 }
7563
7564 /*!
7565  * This method can be applied on allocated with one component DataArrayInt instance.
7566  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7567  * 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]
7568  * 
7569  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7570  * \throw if \a this is not allocated or if \a this has not exactly one component.
7571  * \sa DataArrayInt::buildUniqueNotSorted
7572  */
7573 DataArrayInt *DataArrayInt::buildUnique() const
7574 {
7575   checkAllocated();
7576   if(getNumberOfComponents()!=1)
7577     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7578   int nbOfTuples=getNumberOfTuples();
7579   MCAuto<DataArrayInt> tmp=deepCopy();
7580   int *data=tmp->getPointer();
7581   int *last=std::unique(data,data+nbOfTuples);
7582   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7583   ret->alloc(std::distance(data,last),1);
7584   std::copy(data,last,ret->getPointer());
7585   return ret.retn();
7586 }
7587
7588 /*!
7589  * This method can be applied on allocated with one component DataArrayInt instance.
7590  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7591  *
7592  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7593  *
7594  * \throw if \a this is not allocated or if \a this has not exactly one component.
7595  *
7596  * \sa DataArrayInt::buildUnique
7597  */
7598 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7599 {
7600   checkAllocated();
7601     if(getNumberOfComponents()!=1)
7602       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7603   int minVal,maxVal;
7604   getMinMaxValues(minVal,maxVal);
7605   std::vector<bool> b(maxVal-minVal+1,false);
7606   const int *ptBg(begin()),*endBg(end());
7607   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7608   for(const int *pt=ptBg;pt!=endBg;pt++)
7609     {
7610       if(!b[*pt-minVal])
7611         {
7612           ret->pushBackSilent(*pt);
7613           b[*pt-minVal]=true;
7614         }
7615     }
7616   ret->copyStringInfoFrom(*this);
7617   return ret.retn();
7618 }
7619
7620 /*!
7621  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7622  * "index" array. Such "index" array is returned for example by 
7623  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7624  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7625  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7626  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7627  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7628  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7629  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7630  *          The caller is to delete this array using decrRef() as it is no more needed. 
7631  *  \throw If \a this is not allocated.
7632  *  \throw If \a this->getNumberOfComponents() != 1.
7633  *  \throw If \a this->getNumberOfTuples() < 2.
7634  *
7635  *  \b Example: <br> 
7636  *         - this contains [1,3,6,7,7,9,15]
7637  *         - result array contains [2,3,1,0,2,6],
7638  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7639  *
7640  * \sa DataArrayInt::computeOffsetsFull
7641  */
7642 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7643 {
7644   checkAllocated();
7645   if(getNumberOfComponents()!=1)
7646     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7647   int nbOfTuples=getNumberOfTuples();
7648   if(nbOfTuples<2)
7649     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7650   const int *ptr=getConstPointer();
7651   DataArrayInt *ret=DataArrayInt::New();
7652   ret->alloc(nbOfTuples-1,1);
7653   int *out=ret->getPointer();
7654   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7655   return ret;
7656 }
7657
7658 /*!
7659  * Modifies \a this one-dimensional array so that value of each element \a x
7660  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7661  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7662  * and components remains the same.<br>
7663  * This method is useful for allToAllV in MPI with contiguous policy. This method
7664  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7665  * this one.
7666  *  \throw If \a this is not allocated.
7667  *  \throw If \a this->getNumberOfComponents() != 1.
7668  *
7669  *  \b Example: <br>
7670  *          - Before \a this contains [3,5,1,2,0,8]
7671  *          - After \a this contains  [0,3,8,9,11,11]<br>
7672  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7673  *          array is retained and thus there is no space to store the last element.
7674  */
7675 void DataArrayInt::computeOffsets()
7676 {
7677   checkAllocated();
7678   if(getNumberOfComponents()!=1)
7679     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7680   int nbOfTuples=getNumberOfTuples();
7681   if(nbOfTuples==0)
7682     return ;
7683   int *work=getPointer();
7684   int tmp=work[0];
7685   work[0]=0;
7686   for(int i=1;i<nbOfTuples;i++)
7687     {
7688       int tmp2=work[i];
7689       work[i]=work[i-1]+tmp;
7690       tmp=tmp2;
7691     }
7692   declareAsNew();
7693 }
7694
7695
7696 /*!
7697  * Modifies \a this one-dimensional array so that value of each element \a x
7698  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7699  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7700  * components remains the same and number of tuples is inceamented by one.<br>
7701  * This method is useful for allToAllV in MPI with contiguous policy. This method
7702  * differs from computeOffsets() in that the number of tuples is changed by this one.
7703  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7704  *  \throw If \a this is not allocated.
7705  *  \throw If \a this->getNumberOfComponents() != 1.
7706  *
7707  *  \b Example: <br>
7708  *          - Before \a this contains [3,5,1,2,0,8]
7709  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7710  * \sa DataArrayInt::deltaShiftIndex
7711  */
7712 void DataArrayInt::computeOffsetsFull()
7713 {
7714   checkAllocated();
7715   if(getNumberOfComponents()!=1)
7716     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7717   int nbOfTuples=getNumberOfTuples();
7718   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7719   const int *work=getConstPointer();
7720   ret[0]=0;
7721   for(int i=0;i<nbOfTuples;i++)
7722     ret[i+1]=work[i]+ret[i];
7723   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7724   declareAsNew();
7725 }
7726
7727 /*!
7728  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7729  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7730  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7731  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7732  * filling completely one of the ranges in \a this.
7733  *
7734  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7735  * \param [out] rangeIdsFetched the range ids fetched
7736  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7737  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7738  *
7739  * \sa DataArrayInt::computeOffsetsFull
7740  *
7741  *  \b Example: <br>
7742  *          - \a this : [0,3,7,9,15,18]
7743  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7744  *          - \a rangeIdsFetched result array: [0,2,4]
7745  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7746  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7747  * <br>
7748  */
7749 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7750 {
7751   if(!listOfIds)
7752     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7753   listOfIds->checkAllocated(); checkAllocated();
7754   if(listOfIds->getNumberOfComponents()!=1)
7755     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7756   if(getNumberOfComponents()!=1)
7757     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7758   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7759   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7760   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7761   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7762   while(tupPtr!=tupEnd && offPtr!=offEnd)
7763     {
7764       if(*tupPtr==*offPtr)
7765         {
7766           int i=offPtr[0];
7767           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7768           if(i==offPtr[1])
7769             {
7770               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7771               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7772               offPtr++;
7773             }
7774         }
7775       else
7776         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7777     }
7778   rangeIdsFetched=ret0.retn();
7779   idsInInputListThatFetch=ret1.retn();
7780 }
7781
7782 /*!
7783  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7784  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7785  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7786  * beginning within the "iota" array. And \a this is a one-dimensional array
7787  * considered as a selector of groups described by \a offsets to include into the result array.
7788  *  \throw If \a offsets is NULL.
7789  *  \throw If \a offsets is not allocated.
7790  *  \throw If \a offsets->getNumberOfComponents() != 1.
7791  *  \throw If \a offsets is not monotonically increasing.
7792  *  \throw If \a this is not allocated.
7793  *  \throw If \a this->getNumberOfComponents() != 1.
7794  *  \throw If any element of \a this is not a valid index for \a offsets array.
7795  *
7796  *  \b Example: <br>
7797  *          - \a this: [0,2,3]
7798  *          - \a offsets: [0,3,6,10,14,20]
7799  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7800  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7801  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7802  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7803  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7804  */
7805 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7806 {
7807   if(!offsets)
7808     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7809   checkAllocated();
7810   if(getNumberOfComponents()!=1)
7811     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7812   offsets->checkAllocated();
7813   if(offsets->getNumberOfComponents()!=1)
7814     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7815   int othNbTuples=offsets->getNumberOfTuples()-1;
7816   int nbOfTuples=getNumberOfTuples();
7817   int retNbOftuples=0;
7818   const int *work=getConstPointer();
7819   const int *offPtr=offsets->getConstPointer();
7820   for(int i=0;i<nbOfTuples;i++)
7821     {
7822       int val=work[i];
7823       if(val>=0 && val<othNbTuples)
7824         {
7825           int delta=offPtr[val+1]-offPtr[val];
7826           if(delta>=0)
7827             retNbOftuples+=delta;
7828           else
7829             {
7830               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7831               throw INTERP_KERNEL::Exception(oss.str().c_str());
7832             }
7833         }
7834       else
7835         {
7836           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7837           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7838           throw INTERP_KERNEL::Exception(oss.str().c_str());
7839         }
7840     }
7841   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7842   ret->alloc(retNbOftuples,1);
7843   int *retPtr=ret->getPointer();
7844   for(int i=0;i<nbOfTuples;i++)
7845     {
7846       int val=work[i];
7847       int start=offPtr[val];
7848       int off=offPtr[val+1]-start;
7849       for(int j=0;j<off;j++,retPtr++)
7850         *retPtr=start+j;
7851     }
7852   return ret.retn();
7853 }
7854
7855 /*!
7856  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7857  * scaled array (monotonically increasing).
7858 from that of \a this and \a
7859  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7860  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7861  * beginning within the "iota" array. And \a this is a one-dimensional array
7862  * considered as a selector of groups described by \a offsets to include into the result array.
7863  *  \throw If \a  is NULL.
7864  *  \throw If \a this is not allocated.
7865  *  \throw If \a this->getNumberOfComponents() != 1.
7866  *  \throw If \a this->getNumberOfTuples() == 0.
7867  *  \throw If \a this is not monotonically increasing.
7868  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7869  *
7870  *  \b Example: <br>
7871  *          - \a bg , \a stop and \a step : (0,5,2)
7872  *          - \a this: [0,3,6,10,14,20]
7873  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7874  */
7875 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7876 {
7877   if(!isAllocated())
7878     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7879   if(getNumberOfComponents()!=1)
7880     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7881   int nbOfTuples(getNumberOfTuples());
7882   if(nbOfTuples==0)
7883     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7884   const int *ids(begin());
7885   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7886   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7887     {
7888       if(pos>=0 && pos<nbOfTuples-1)
7889         {
7890           int delta(ids[pos+1]-ids[pos]);
7891           sz+=delta;
7892           if(delta<0)
7893             {
7894               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7895               throw INTERP_KERNEL::Exception(oss.str().c_str());
7896             }          
7897         }
7898       else
7899         {
7900           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7901           throw INTERP_KERNEL::Exception(oss.str().c_str());
7902         }
7903     }
7904   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7905   int *retPtr(ret->getPointer());
7906   pos=bg;
7907   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7908     {
7909       int delta(ids[pos+1]-ids[pos]);
7910       for(int j=0;j<delta;j++,retPtr++)
7911         *retPtr=pos;
7912     }
7913   return ret.retn();
7914 }
7915
7916 /*!
7917  * 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.
7918  * 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
7919  * in tuple **i** of returned DataArrayInt.
7920  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7921  *
7922  * 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)]
7923  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7924  * 
7925  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7926  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7927  * \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
7928  *        is thrown if no ranges in \a ranges contains value in \a this.
7929  * 
7930  * \sa DataArrayInt::findIdInRangeForEachTuple
7931  */
7932 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7933 {
7934   if(!ranges)
7935     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7936   if(ranges->getNumberOfComponents()!=2)
7937     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7938   checkAllocated();
7939   if(getNumberOfComponents()!=1)
7940     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7941   int nbTuples=getNumberOfTuples();
7942   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7943   int nbOfRanges=ranges->getNumberOfTuples();
7944   const int *rangesPtr=ranges->getConstPointer();
7945   int *retPtr=ret->getPointer();
7946   const int *inPtr=getConstPointer();
7947   for(int i=0;i<nbTuples;i++,retPtr++)
7948     {
7949       int val=inPtr[i];
7950       bool found=false;
7951       for(int j=0;j<nbOfRanges && !found;j++)
7952         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7953           { *retPtr=j; found=true; }
7954       if(found)
7955         continue;
7956       else
7957         {
7958           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7959           throw INTERP_KERNEL::Exception(oss.str().c_str());
7960         }
7961     }
7962   return ret.retn();
7963 }
7964
7965 /*!
7966  * 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.
7967  * 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
7968  * in tuple **i** of returned DataArrayInt.
7969  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7970  *
7971  * 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)]
7972  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7973  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7974  * 
7975  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7976  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7977  * \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
7978  *        is thrown if no ranges in \a ranges contains value in \a this.
7979  * \sa DataArrayInt::findRangeIdForEachTuple
7980  */
7981 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7982 {
7983   if(!ranges)
7984     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7985   if(ranges->getNumberOfComponents()!=2)
7986     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7987   checkAllocated();
7988   if(getNumberOfComponents()!=1)
7989     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7990   int nbTuples=getNumberOfTuples();
7991   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7992   int nbOfRanges=ranges->getNumberOfTuples();
7993   const int *rangesPtr=ranges->getConstPointer();
7994   int *retPtr=ret->getPointer();
7995   const int *inPtr=getConstPointer();
7996   for(int i=0;i<nbTuples;i++,retPtr++)
7997     {
7998       int val=inPtr[i];
7999       bool found=false;
8000       for(int j=0;j<nbOfRanges && !found;j++)
8001         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8002           { *retPtr=val-rangesPtr[2*j]; found=true; }
8003       if(found)
8004         continue;
8005       else
8006         {
8007           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
8008           throw INTERP_KERNEL::Exception(oss.str().c_str());
8009         }
8010     }
8011   return ret.retn();
8012 }
8013
8014 /*!
8015  * \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).
8016  * 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).
8017  * 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 !
8018  * If this method has correctly worked, \a this will be able to be considered as a linked list.
8019  * This method does nothing if number of tuples is lower of equal to 1.
8020  *
8021  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
8022  *
8023  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
8024  */
8025 void DataArrayInt::sortEachPairToMakeALinkedList()
8026 {
8027   checkAllocated();
8028   if(getNumberOfComponents()!=2)
8029     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
8030   int nbOfTuples(getNumberOfTuples());
8031   if(nbOfTuples<=1)
8032     return ;
8033   int *conn(getPointer());
8034   for(int i=1;i<nbOfTuples;i++,conn+=2)
8035     {
8036       if(i>1)
8037         {
8038           if(conn[2]==conn[3])
8039             {
8040               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
8041               throw INTERP_KERNEL::Exception(oss.str().c_str());
8042             }
8043           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8044             std::swap(conn[2],conn[3]);
8045           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8046           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8047             {
8048               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8049               throw INTERP_KERNEL::Exception(oss.str().c_str());
8050             }
8051         }
8052       else
8053         {
8054           if(conn[0]==conn[1] || conn[2]==conn[3])
8055             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8056           int tmp[4];
8057           std::set<int> s;
8058           s.insert(conn,conn+4);
8059           if(s.size()!=3)
8060             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8061           if(std::count(conn,conn+4,conn[0])==2)
8062             {
8063               tmp[0]=conn[1];
8064               tmp[1]=conn[0];
8065               tmp[2]=conn[0];
8066               if(conn[2]==conn[0])
8067                 { tmp[3]=conn[3]; }
8068               else
8069                 { tmp[3]=conn[2];}
8070               std::copy(tmp,tmp+4,conn);
8071             }
8072           else
8073             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8074               if(conn[1]==conn[3])
8075                 std::swap(conn[2],conn[3]);
8076             }
8077         }
8078     }
8079 }
8080
8081 /*!
8082  * \a this is expected to be a correctly linked list of pairs.
8083  * 
8084  * \sa DataArrayInt::sortEachPairToMakeALinkedList
8085  */
8086 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8087 {
8088   checkAllocated();
8089   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8090   int nbTuples(getNumberOfTuples());
8091   if(nbTuples<1)
8092     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8093   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8094   const int *thisPtr(begin());
8095   int *retPtr(ret->getPointer());
8096   retPtr[0]=thisPtr[0];
8097   for(int i=0;i<nbTuples;i++)
8098     {
8099       retPtr[i+1]=thisPtr[2*i+1];
8100       if(i<nbTuples-1)
8101         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8102           {
8103             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 ?";
8104             throw INTERP_KERNEL::Exception(oss.str());
8105           }
8106     }
8107   return ret;
8108 }
8109
8110 /*!
8111  * 
8112  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8113  *             \a nbTimes  should be at least equal to 1.
8114  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8115  * \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.
8116  */
8117 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8118 {
8119   checkAllocated();
8120   if(getNumberOfComponents()!=1)
8121     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8122   if(nbTimes<1)
8123     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8124   int nbTuples=getNumberOfTuples();
8125   const int *inPtr=getConstPointer();
8126   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8127   int *retPtr=ret->getPointer();
8128   for(int i=0;i<nbTuples;i++,inPtr++)
8129     {
8130       int val=*inPtr;
8131       for(int j=0;j<nbTimes;j++,retPtr++)
8132         *retPtr=val;
8133     }
8134   ret->copyStringInfoFrom(*this);
8135   return ret.retn();
8136 }
8137
8138 /*!
8139  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8140  * But the number of components can be different from one.
8141  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8142  */
8143 DataArrayInt *DataArrayInt::getDifferentValues() const
8144 {
8145   checkAllocated();
8146   std::set<int> ret;
8147   ret.insert(begin(),end());
8148   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8149   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8150   return ret2.retn();
8151 }
8152
8153 /*!
8154  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8155  * them it tells which tuple id have this id.
8156  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8157  * This method returns two arrays having same size.
8158  * 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.
8159  * 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]]
8160  */
8161 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8162 {
8163   checkAllocated();
8164   if(getNumberOfComponents()!=1)
8165     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8166   int id=0;
8167   std::map<int,int> m,m2,m3;
8168   for(const int *w=begin();w!=end();w++)
8169     m[*w]++;
8170   differentIds.resize(m.size());
8171   std::vector<DataArrayInt *> ret(m.size());
8172   std::vector<int *> retPtr(m.size());
8173   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8174     {
8175       m2[(*it).first]=id;
8176       ret[id]=DataArrayInt::New();
8177       ret[id]->alloc((*it).second,1);
8178       retPtr[id]=ret[id]->getPointer();
8179       differentIds[id]=(*it).first;
8180     }
8181   id=0;
8182   for(const int *w=begin();w!=end();w++,id++)
8183     {
8184       retPtr[m2[*w]][m3[*w]++]=id;
8185     }
8186   return ret;
8187 }
8188
8189 /*!
8190  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8191  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8192  *
8193  * \param [in] nbOfSlices - number of slices expected.
8194  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8195  * 
8196  * \sa DataArray::GetSlice
8197  * \throw If \a this is not allocated or not with exactly one component.
8198  * \throw If an element in \a this if < 0.
8199  */
8200 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8201 {
8202   if(!isAllocated() || getNumberOfComponents()!=1)
8203     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8204   if(nbOfSlices<=0)
8205     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8206   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8207   int sumPerSlc(sum/nbOfSlices),pos(0);
8208   const int *w(begin());
8209   std::vector< std::pair<int,int> > ret(nbOfSlices);
8210   for(int i=0;i<nbOfSlices;i++)
8211     {
8212       std::pair<int,int> p(pos,-1);
8213       int locSum(0);
8214       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8215       if(i!=nbOfSlices-1)
8216         p.second=pos;
8217       else
8218         p.second=nbOfTuples;
8219       ret[i]=p;
8220     }
8221   return ret;
8222 }
8223
8224 /*!
8225  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8226  * valid cases.
8227  * 1.  The arrays have same number of tuples and components. Then each value of
8228  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8229  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8230  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8231  *   component. Then
8232  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8233  * 3.  The arrays have same number of components and one array, say _a2_, has one
8234  *   tuple. Then
8235  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8236  *
8237  * Info on components is copied either from the first array (in the first case) or from
8238  * the array with maximal number of elements (getNbOfElems()).
8239  *  \param [in] a1 - an array to sum up.
8240  *  \param [in] a2 - another array to sum up.
8241  *  \return DataArrayInt * - the new instance of DataArrayInt.
8242  *          The caller is to delete this result array using decrRef() as it is no more
8243  *          needed.
8244  *  \throw If either \a a1 or \a a2 is NULL.
8245  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8246  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8247  *         none of them has number of tuples or components equal to 1.
8248  */
8249 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8250 {
8251   if(!a1 || !a2)
8252     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8253   int nbOfTuple=a1->getNumberOfTuples();
8254   int nbOfTuple2=a2->getNumberOfTuples();
8255   int nbOfComp=a1->getNumberOfComponents();
8256   int nbOfComp2=a2->getNumberOfComponents();
8257   MCAuto<DataArrayInt> ret=0;
8258   if(nbOfTuple==nbOfTuple2)
8259     {
8260       if(nbOfComp==nbOfComp2)
8261         {
8262           ret=DataArrayInt::New();
8263           ret->alloc(nbOfTuple,nbOfComp);
8264           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8265           ret->copyStringInfoFrom(*a1);
8266         }
8267       else
8268         {
8269           int nbOfCompMin,nbOfCompMax;
8270           const DataArrayInt *aMin, *aMax;
8271           if(nbOfComp>nbOfComp2)
8272             {
8273               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8274               aMin=a2; aMax=a1;
8275             }
8276           else
8277             {
8278               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8279               aMin=a1; aMax=a2;
8280             }
8281           if(nbOfCompMin==1)
8282             {
8283               ret=DataArrayInt::New();
8284               ret->alloc(nbOfTuple,nbOfCompMax);
8285               const int *aMinPtr=aMin->getConstPointer();
8286               const int *aMaxPtr=aMax->getConstPointer();
8287               int *res=ret->getPointer();
8288               for(int i=0;i<nbOfTuple;i++)
8289                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8290               ret->copyStringInfoFrom(*aMax);
8291             }
8292           else
8293             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8294         }
8295     }
8296   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8297     {
8298       if(nbOfComp==nbOfComp2)
8299         {
8300           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8301           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8302           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8303           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8304           ret=DataArrayInt::New();
8305           ret->alloc(nbOfTupleMax,nbOfComp);
8306           int *res=ret->getPointer();
8307           for(int i=0;i<nbOfTupleMax;i++)
8308             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8309           ret->copyStringInfoFrom(*aMax);
8310         }
8311       else
8312         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8313     }
8314   else
8315     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8316   return ret.retn();
8317 }
8318
8319 /*!
8320  * Adds values of another DataArrayInt to values of \a this one. There are 3
8321  * valid cases.
8322  * 1.  The arrays have same number of tuples and components. Then each value of
8323  *   \a other array is added to the corresponding value of \a this array, i.e.:
8324  *   _a_ [ i, j ] += _other_ [ i, j ].
8325  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8326  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8327  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8328  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8329  *
8330  *  \param [in] other - an array to add to \a this one.
8331  *  \throw If \a other is NULL.
8332  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8333  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8334  *         \a other has number of both tuples and components not equal to 1.
8335  */
8336 void DataArrayInt::addEqual(const DataArrayInt *other)
8337 {
8338   if(!other)
8339     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8340   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8341   checkAllocated(); other->checkAllocated();
8342   int nbOfTuple=getNumberOfTuples();
8343   int nbOfTuple2=other->getNumberOfTuples();
8344   int nbOfComp=getNumberOfComponents();
8345   int nbOfComp2=other->getNumberOfComponents();
8346   if(nbOfTuple==nbOfTuple2)
8347     {
8348       if(nbOfComp==nbOfComp2)
8349         {
8350           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8351         }
8352       else if(nbOfComp2==1)
8353         {
8354           int *ptr=getPointer();
8355           const int *ptrc=other->getConstPointer();
8356           for(int i=0;i<nbOfTuple;i++)
8357             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8358         }
8359       else
8360         throw INTERP_KERNEL::Exception(msg);
8361     }
8362   else if(nbOfTuple2==1)
8363     {
8364       if(nbOfComp2==nbOfComp)
8365         {
8366           int *ptr=getPointer();
8367           const int *ptrc=other->getConstPointer();
8368           for(int i=0;i<nbOfTuple;i++)
8369             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8370         }
8371       else
8372         throw INTERP_KERNEL::Exception(msg);
8373     }
8374   else
8375     throw INTERP_KERNEL::Exception(msg);
8376   declareAsNew();
8377 }
8378
8379 /*!
8380  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8381  * valid cases.
8382  * 1.  The arrays have same number of tuples and components. Then each value of
8383  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8384  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8385  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8386  *   component. Then
8387  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8388  * 3.  The arrays have same number of components and one array, say _a2_, has one
8389  *   tuple. Then
8390  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8391  *
8392  * Info on components is copied either from the first array (in the first case) or from
8393  * the array with maximal number of elements (getNbOfElems()).
8394  *  \param [in] a1 - an array to subtract from.
8395  *  \param [in] a2 - an array to subtract.
8396  *  \return DataArrayInt * - the new instance of DataArrayInt.
8397  *          The caller is to delete this result array using decrRef() as it is no more
8398  *          needed.
8399  *  \throw If either \a a1 or \a a2 is NULL.
8400  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8401  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8402  *         none of them has number of tuples or components equal to 1.
8403  */
8404 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8405 {
8406   if(!a1 || !a2)
8407     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8408   int nbOfTuple1=a1->getNumberOfTuples();
8409   int nbOfTuple2=a2->getNumberOfTuples();
8410   int nbOfComp1=a1->getNumberOfComponents();
8411   int nbOfComp2=a2->getNumberOfComponents();
8412   if(nbOfTuple2==nbOfTuple1)
8413     {
8414       if(nbOfComp1==nbOfComp2)
8415         {
8416           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8417           ret->alloc(nbOfTuple2,nbOfComp1);
8418           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8419           ret->copyStringInfoFrom(*a1);
8420           return ret.retn();
8421         }
8422       else if(nbOfComp2==1)
8423         {
8424           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8425           ret->alloc(nbOfTuple1,nbOfComp1);
8426           const int *a2Ptr=a2->getConstPointer();
8427           const int *a1Ptr=a1->getConstPointer();
8428           int *res=ret->getPointer();
8429           for(int i=0;i<nbOfTuple1;i++)
8430             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8431           ret->copyStringInfoFrom(*a1);
8432           return ret.retn();
8433         }
8434       else
8435         {
8436           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8437           return 0;
8438         }
8439     }
8440   else if(nbOfTuple2==1)
8441     {
8442       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8443       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8444       ret->alloc(nbOfTuple1,nbOfComp1);
8445       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8446       int *pt=ret->getPointer();
8447       for(int i=0;i<nbOfTuple1;i++)
8448         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8449       ret->copyStringInfoFrom(*a1);
8450       return ret.retn();
8451     }
8452   else
8453     {
8454       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8455       return 0;
8456     }
8457 }
8458
8459 /*!
8460  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8461  * valid cases.
8462  * 1.  The arrays have same number of tuples and components. Then each value of
8463  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8464  *   _a_ [ i, j ] -= _other_ [ i, j ].
8465  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8466  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8467  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8468  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8469  *
8470  *  \param [in] other - an array to subtract from \a this one.
8471  *  \throw If \a other is NULL.
8472  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8473  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8474  *         \a other has number of both tuples and components not equal to 1.
8475  */
8476 void DataArrayInt::substractEqual(const DataArrayInt *other)
8477 {
8478   if(!other)
8479     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8480   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8481   checkAllocated(); other->checkAllocated();
8482   int nbOfTuple=getNumberOfTuples();
8483   int nbOfTuple2=other->getNumberOfTuples();
8484   int nbOfComp=getNumberOfComponents();
8485   int nbOfComp2=other->getNumberOfComponents();
8486   if(nbOfTuple==nbOfTuple2)
8487     {
8488       if(nbOfComp==nbOfComp2)
8489         {
8490           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8491         }
8492       else if(nbOfComp2==1)
8493         {
8494           int *ptr=getPointer();
8495           const int *ptrc=other->getConstPointer();
8496           for(int i=0;i<nbOfTuple;i++)
8497             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8498         }
8499       else
8500         throw INTERP_KERNEL::Exception(msg);
8501     }
8502   else if(nbOfTuple2==1)
8503     {
8504       int *ptr=getPointer();
8505       const int *ptrc=other->getConstPointer();
8506       for(int i=0;i<nbOfTuple;i++)
8507         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8508     }
8509   else
8510     throw INTERP_KERNEL::Exception(msg);
8511   declareAsNew();
8512 }
8513
8514 /*!
8515  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8516  * valid cases.
8517  * 1.  The arrays have same number of tuples and components. Then each value of
8518  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8519  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8520  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8521  *   component. Then
8522  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8523  * 3.  The arrays have same number of components and one array, say _a2_, has one
8524  *   tuple. Then
8525  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8526  *
8527  * Info on components is copied either from the first array (in the first case) or from
8528  * the array with maximal number of elements (getNbOfElems()).
8529  *  \param [in] a1 - a factor array.
8530  *  \param [in] a2 - another factor array.
8531  *  \return DataArrayInt * - the new instance of DataArrayInt.
8532  *          The caller is to delete this result array using decrRef() as it is no more
8533  *          needed.
8534  *  \throw If either \a a1 or \a a2 is NULL.
8535  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8536  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8537  *         none of them has number of tuples or components equal to 1.
8538  */
8539 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8540 {
8541   if(!a1 || !a2)
8542     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8543   int nbOfTuple=a1->getNumberOfTuples();
8544   int nbOfTuple2=a2->getNumberOfTuples();
8545   int nbOfComp=a1->getNumberOfComponents();
8546   int nbOfComp2=a2->getNumberOfComponents();
8547   MCAuto<DataArrayInt> ret=0;
8548   if(nbOfTuple==nbOfTuple2)
8549     {
8550       if(nbOfComp==nbOfComp2)
8551         {
8552           ret=DataArrayInt::New();
8553           ret->alloc(nbOfTuple,nbOfComp);
8554           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8555           ret->copyStringInfoFrom(*a1);
8556         }
8557       else
8558         {
8559           int nbOfCompMin,nbOfCompMax;
8560           const DataArrayInt *aMin, *aMax;
8561           if(nbOfComp>nbOfComp2)
8562             {
8563               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8564               aMin=a2; aMax=a1;
8565             }
8566           else
8567             {
8568               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8569               aMin=a1; aMax=a2;
8570             }
8571           if(nbOfCompMin==1)
8572             {
8573               ret=DataArrayInt::New();
8574               ret->alloc(nbOfTuple,nbOfCompMax);
8575               const int *aMinPtr=aMin->getConstPointer();
8576               const int *aMaxPtr=aMax->getConstPointer();
8577               int *res=ret->getPointer();
8578               for(int i=0;i<nbOfTuple;i++)
8579                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8580               ret->copyStringInfoFrom(*aMax);
8581             }
8582           else
8583             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8584         }
8585     }
8586   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8587     {
8588       if(nbOfComp==nbOfComp2)
8589         {
8590           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8591           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8592           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8593           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8594           ret=DataArrayInt::New();
8595           ret->alloc(nbOfTupleMax,nbOfComp);
8596           int *res=ret->getPointer();
8597           for(int i=0;i<nbOfTupleMax;i++)
8598             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8599           ret->copyStringInfoFrom(*aMax);
8600         }
8601       else
8602         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8603     }
8604   else
8605     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8606   return ret.retn();
8607 }
8608
8609
8610 /*!
8611  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8612  * valid cases.
8613  * 1.  The arrays have same number of tuples and components. Then each value of
8614  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8615  *   _a_ [ i, j ] *= _other_ [ i, j ].
8616  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8617  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8618  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8619  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8620  *
8621  *  \param [in] other - an array to multiply to \a this one.
8622  *  \throw If \a other is NULL.
8623  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8624  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8625  *         \a other has number of both tuples and components not equal to 1.
8626  */
8627 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8628 {
8629   if(!other)
8630     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8631   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8632   checkAllocated(); other->checkAllocated();
8633   int nbOfTuple=getNumberOfTuples();
8634   int nbOfTuple2=other->getNumberOfTuples();
8635   int nbOfComp=getNumberOfComponents();
8636   int nbOfComp2=other->getNumberOfComponents();
8637   if(nbOfTuple==nbOfTuple2)
8638     {
8639       if(nbOfComp==nbOfComp2)
8640         {
8641           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8642         }
8643       else if(nbOfComp2==1)
8644         {
8645           int *ptr=getPointer();
8646           const int *ptrc=other->getConstPointer();
8647           for(int i=0;i<nbOfTuple;i++)
8648             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8649         }
8650       else
8651         throw INTERP_KERNEL::Exception(msg);
8652     }
8653   else if(nbOfTuple2==1)
8654     {
8655       if(nbOfComp2==nbOfComp)
8656         {
8657           int *ptr=getPointer();
8658           const int *ptrc=other->getConstPointer();
8659           for(int i=0;i<nbOfTuple;i++)
8660             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8661         }
8662       else
8663         throw INTERP_KERNEL::Exception(msg);
8664     }
8665   else
8666     throw INTERP_KERNEL::Exception(msg);
8667   declareAsNew();
8668 }
8669
8670
8671 /*!
8672  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8673  * valid cases.
8674  * 1.  The arrays have same number of tuples and components. Then each value of
8675  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8676  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8677  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8678  *   component. Then
8679  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8680  * 3.  The arrays have same number of components and one array, say _a2_, has one
8681  *   tuple. Then
8682  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8683  *
8684  * Info on components is copied either from the first array (in the first case) or from
8685  * the array with maximal number of elements (getNbOfElems()).
8686  *  \warning No check of division by zero is performed!
8687  *  \param [in] a1 - a numerator array.
8688  *  \param [in] a2 - a denominator array.
8689  *  \return DataArrayInt * - the new instance of DataArrayInt.
8690  *          The caller is to delete this result array using decrRef() as it is no more
8691  *          needed.
8692  *  \throw If either \a a1 or \a a2 is NULL.
8693  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8694  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8695  *         none of them has number of tuples or components equal to 1.
8696  */
8697 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8698 {
8699   if(!a1 || !a2)
8700     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8701   int nbOfTuple1=a1->getNumberOfTuples();
8702   int nbOfTuple2=a2->getNumberOfTuples();
8703   int nbOfComp1=a1->getNumberOfComponents();
8704   int nbOfComp2=a2->getNumberOfComponents();
8705   if(nbOfTuple2==nbOfTuple1)
8706     {
8707       if(nbOfComp1==nbOfComp2)
8708         {
8709           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8710           ret->alloc(nbOfTuple2,nbOfComp1);
8711           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8712           ret->copyStringInfoFrom(*a1);
8713           return ret.retn();
8714         }
8715       else if(nbOfComp2==1)
8716         {
8717           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8718           ret->alloc(nbOfTuple1,nbOfComp1);
8719           const int *a2Ptr=a2->getConstPointer();
8720           const int *a1Ptr=a1->getConstPointer();
8721           int *res=ret->getPointer();
8722           for(int i=0;i<nbOfTuple1;i++)
8723             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8724           ret->copyStringInfoFrom(*a1);
8725           return ret.retn();
8726         }
8727       else
8728         {
8729           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8730           return 0;
8731         }
8732     }
8733   else if(nbOfTuple2==1)
8734     {
8735       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8736       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8737       ret->alloc(nbOfTuple1,nbOfComp1);
8738       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8739       int *pt=ret->getPointer();
8740       for(int i=0;i<nbOfTuple1;i++)
8741         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8742       ret->copyStringInfoFrom(*a1);
8743       return ret.retn();
8744     }
8745   else
8746     {
8747       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8748       return 0;
8749     }
8750 }
8751
8752 /*!
8753  * Divide values of \a this array by values of another DataArrayInt. There are 3
8754  * valid cases.
8755  * 1.  The arrays have same number of tuples and components. Then each value of
8756  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8757  *   _a_ [ i, j ] /= _other_ [ i, j ].
8758  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8759  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8760  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8761  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8762  *
8763  *  \warning No check of division by zero is performed!
8764  *  \param [in] other - an array to divide \a this one by.
8765  *  \throw If \a other is NULL.
8766  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8767  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8768  *         \a other has number of both tuples and components not equal to 1.
8769  */
8770 void DataArrayInt::divideEqual(const DataArrayInt *other)
8771 {
8772   if(!other)
8773     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8774   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8775   checkAllocated(); other->checkAllocated();
8776   int nbOfTuple=getNumberOfTuples();
8777   int nbOfTuple2=other->getNumberOfTuples();
8778   int nbOfComp=getNumberOfComponents();
8779   int nbOfComp2=other->getNumberOfComponents();
8780   if(nbOfTuple==nbOfTuple2)
8781     {
8782       if(nbOfComp==nbOfComp2)
8783         {
8784           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8785         }
8786       else if(nbOfComp2==1)
8787         {
8788           int *ptr=getPointer();
8789           const int *ptrc=other->getConstPointer();
8790           for(int i=0;i<nbOfTuple;i++)
8791             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8792         }
8793       else
8794         throw INTERP_KERNEL::Exception(msg);
8795     }
8796   else if(nbOfTuple2==1)
8797     {
8798       if(nbOfComp2==nbOfComp)
8799         {
8800           int *ptr=getPointer();
8801           const int *ptrc=other->getConstPointer();
8802           for(int i=0;i<nbOfTuple;i++)
8803             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8804         }
8805       else
8806         throw INTERP_KERNEL::Exception(msg);
8807     }
8808   else
8809     throw INTERP_KERNEL::Exception(msg);
8810   declareAsNew();
8811 }
8812
8813
8814 /*!
8815  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8816  * valid cases.
8817  * 1.  The arrays have same number of tuples and components. Then each value of
8818  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8819  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8820  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8821  *   component. Then
8822  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8823  * 3.  The arrays have same number of components and one array, say _a2_, has one
8824  *   tuple. Then
8825  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8826  *
8827  * Info on components is copied either from the first array (in the first case) or from
8828  * the array with maximal number of elements (getNbOfElems()).
8829  *  \warning No check of division by zero is performed!
8830  *  \param [in] a1 - a dividend array.
8831  *  \param [in] a2 - a divisor array.
8832  *  \return DataArrayInt * - the new instance of DataArrayInt.
8833  *          The caller is to delete this result array using decrRef() as it is no more
8834  *          needed.
8835  *  \throw If either \a a1 or \a a2 is NULL.
8836  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8837  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8838  *         none of them has number of tuples or components equal to 1.
8839  */
8840 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8841 {
8842   if(!a1 || !a2)
8843     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8844   int nbOfTuple1=a1->getNumberOfTuples();
8845   int nbOfTuple2=a2->getNumberOfTuples();
8846   int nbOfComp1=a1->getNumberOfComponents();
8847   int nbOfComp2=a2->getNumberOfComponents();
8848   if(nbOfTuple2==nbOfTuple1)
8849     {
8850       if(nbOfComp1==nbOfComp2)
8851         {
8852           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8853           ret->alloc(nbOfTuple2,nbOfComp1);
8854           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8855           ret->copyStringInfoFrom(*a1);
8856           return ret.retn();
8857         }
8858       else if(nbOfComp2==1)
8859         {
8860           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8861           ret->alloc(nbOfTuple1,nbOfComp1);
8862           const int *a2Ptr=a2->getConstPointer();
8863           const int *a1Ptr=a1->getConstPointer();
8864           int *res=ret->getPointer();
8865           for(int i=0;i<nbOfTuple1;i++)
8866             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8867           ret->copyStringInfoFrom(*a1);
8868           return ret.retn();
8869         }
8870       else
8871         {
8872           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8873           return 0;
8874         }
8875     }
8876   else if(nbOfTuple2==1)
8877     {
8878       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8879       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8880       ret->alloc(nbOfTuple1,nbOfComp1);
8881       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8882       int *pt=ret->getPointer();
8883       for(int i=0;i<nbOfTuple1;i++)
8884         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8885       ret->copyStringInfoFrom(*a1);
8886       return ret.retn();
8887     }
8888   else
8889     {
8890       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8891       return 0;
8892     }
8893 }
8894
8895 /*!
8896  * Modify \a this array so that each value becomes a modulus of division of this value by
8897  * a value of another DataArrayInt. There are 3 valid cases.
8898  * 1.  The arrays have same number of tuples and components. Then each value of
8899  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8900  *   _a_ [ i, j ] %= _other_ [ i, j ].
8901  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8902  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8903  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8904  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8905  *
8906  *  \warning No check of division by zero is performed!
8907  *  \param [in] other - a divisor array.
8908  *  \throw If \a other is NULL.
8909  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8910  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8911  *         \a other has number of both tuples and components not equal to 1.
8912  */
8913 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8914 {
8915   if(!other)
8916     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8917   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8918   checkAllocated(); other->checkAllocated();
8919   int nbOfTuple=getNumberOfTuples();
8920   int nbOfTuple2=other->getNumberOfTuples();
8921   int nbOfComp=getNumberOfComponents();
8922   int nbOfComp2=other->getNumberOfComponents();
8923   if(nbOfTuple==nbOfTuple2)
8924     {
8925       if(nbOfComp==nbOfComp2)
8926         {
8927           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8928         }
8929       else if(nbOfComp2==1)
8930         {
8931           if(nbOfComp2==nbOfComp)
8932             {
8933               int *ptr=getPointer();
8934               const int *ptrc=other->getConstPointer();
8935               for(int i=0;i<nbOfTuple;i++)
8936                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8937             }
8938           else
8939             throw INTERP_KERNEL::Exception(msg);
8940         }
8941       else
8942         throw INTERP_KERNEL::Exception(msg);
8943     }
8944   else if(nbOfTuple2==1)
8945     {
8946       int *ptr=getPointer();
8947       const int *ptrc=other->getConstPointer();
8948       for(int i=0;i<nbOfTuple;i++)
8949         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8950     }
8951   else
8952     throw INTERP_KERNEL::Exception(msg);
8953   declareAsNew();
8954 }
8955
8956 /*!
8957  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8958  * valid cases.
8959  *
8960  *  \param [in] a1 - an array to pow up.
8961  *  \param [in] a2 - another array to sum up.
8962  *  \return DataArrayInt * - the new instance of DataArrayInt.
8963  *          The caller is to delete this result array using decrRef() as it is no more
8964  *          needed.
8965  *  \throw If either \a a1 or \a a2 is NULL.
8966  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8967  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8968  *  \throw If there is a negative value in \a a2.
8969  */
8970 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8971 {
8972   if(!a1 || !a2)
8973     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8974   int nbOfTuple=a1->getNumberOfTuples();
8975   int nbOfTuple2=a2->getNumberOfTuples();
8976   int nbOfComp=a1->getNumberOfComponents();
8977   int nbOfComp2=a2->getNumberOfComponents();
8978   if(nbOfTuple!=nbOfTuple2)
8979     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8980   if(nbOfComp!=1 || nbOfComp2!=1)
8981     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8982   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8983   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8984   int *ptr=ret->getPointer();
8985   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8986     {
8987       if(*ptr2>=0)
8988         {
8989           int tmp=1;
8990           for(int j=0;j<*ptr2;j++)
8991             tmp*=*ptr1;
8992           *ptr=tmp;
8993         }
8994       else
8995         {
8996           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8997           throw INTERP_KERNEL::Exception(oss.str().c_str());
8998         }
8999     }
9000   return ret.retn();
9001 }
9002
9003 /*!
9004  * Apply pow on values of another DataArrayInt to values of \a this one.
9005  *
9006  *  \param [in] other - an array to pow to \a this one.
9007  *  \throw If \a other is NULL.
9008  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
9009  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
9010  *  \throw If there is a negative value in \a other.
9011  */
9012 void DataArrayInt::powEqual(const DataArrayInt *other)
9013 {
9014   if(!other)
9015     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
9016   int nbOfTuple=getNumberOfTuples();
9017   int nbOfTuple2=other->getNumberOfTuples();
9018   int nbOfComp=getNumberOfComponents();
9019   int nbOfComp2=other->getNumberOfComponents();
9020   if(nbOfTuple!=nbOfTuple2)
9021     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
9022   if(nbOfComp!=1 || nbOfComp2!=1)
9023     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
9024   int *ptr=getPointer();
9025   const int *ptrc=other->begin();
9026   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
9027     {
9028       if(*ptrc>=0)
9029         {
9030           int tmp=1;
9031           for(int j=0;j<*ptrc;j++)
9032             tmp*=*ptr;
9033           *ptr=tmp;
9034         }
9035       else
9036         {
9037           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
9038           throw INTERP_KERNEL::Exception(oss.str().c_str());
9039         }
9040     }
9041   declareAsNew();
9042 }
9043
9044 /*!
9045  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9046  * This map, if applied to \a start array, would make it sorted. For example, if
9047  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9048  * [5,6,0,3,2,7,1,4].
9049  *  \param [in] start - pointer to the first element of the array for which the
9050  *         permutation map is computed.
9051  *  \param [in] end - pointer specifying the end of the array \a start, so that
9052  *         the last value of \a start is \a end[ -1 ].
9053  *  \return int * - the result permutation array that the caller is to delete as it is no
9054  *         more needed.
9055  *  \throw If there are equal values in the input array.
9056  */
9057 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9058 {
9059   std::size_t sz=std::distance(start,end);
9060   int *ret=(int *)malloc(sz*sizeof(int));
9061   int *work=new int[sz];
9062   std::copy(start,end,work);
9063   std::sort(work,work+sz);
9064   if(std::unique(work,work+sz)!=work+sz)
9065     {
9066       delete [] work;
9067       free(ret);
9068       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9069     }
9070   std::map<int,int> m;
9071   for(int *workPt=work;workPt!=work+sz;workPt++)
9072     m[*workPt]=(int)std::distance(work,workPt);
9073   int *iter2=ret;
9074   for(const int *iter=start;iter!=end;iter++,iter2++)
9075     *iter2=m[*iter];
9076   delete [] work;
9077   return ret;
9078 }
9079
9080 /*!
9081  * Returns a new DataArrayInt containing an arithmetic progression
9082  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9083  * function.
9084  *  \param [in] begin - the start value of the result sequence.
9085  *  \param [in] end - limiting value, so that every value of the result array is less than
9086  *              \a end.
9087  *  \param [in] step - specifies the increment or decrement.
9088  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9089  *          array using decrRef() as it is no more needed.
9090  *  \throw If \a step == 0.
9091  *  \throw If \a end < \a begin && \a step > 0.
9092  *  \throw If \a end > \a begin && \a step < 0.
9093  */
9094 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9095 {
9096   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9097   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9098   ret->alloc(nbOfTuples,1);
9099   int *ptr=ret->getPointer();
9100   if(step>0)
9101     {
9102       for(int i=begin;i<end;i+=step,ptr++)
9103         *ptr=i;
9104     }
9105   else
9106     {
9107       for(int i=begin;i>end;i+=step,ptr++)
9108         *ptr=i;
9109     }
9110   return ret.retn();
9111 }
9112
9113 /*!
9114  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9115  * Server side.
9116  */
9117 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9118 {
9119   tinyInfo.resize(2);
9120   if(isAllocated())
9121     {
9122       tinyInfo[0]=getNumberOfTuples();
9123       tinyInfo[1]=getNumberOfComponents();
9124     }
9125   else
9126     {
9127       tinyInfo[0]=-1;
9128       tinyInfo[1]=-1;
9129     }
9130 }
9131
9132 /*!
9133  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9134  * Server side.
9135  */
9136 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9137 {
9138   if(isAllocated())
9139     {
9140       int nbOfCompo=getNumberOfComponents();
9141       tinyInfo.resize(nbOfCompo+1);
9142       tinyInfo[0]=getName();
9143       for(int i=0;i<nbOfCompo;i++)
9144         tinyInfo[i+1]=getInfoOnComponent(i);
9145     }
9146   else
9147     {
9148       tinyInfo.resize(1);
9149       tinyInfo[0]=getName();
9150     }
9151 }
9152
9153 /*!
9154  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9155  * This method returns if a feeding is needed.
9156  */
9157 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9158 {
9159   int nbOfTuple=tinyInfoI[0];
9160   int nbOfComp=tinyInfoI[1];
9161   if(nbOfTuple!=-1 || nbOfComp!=-1)
9162     {
9163       alloc(nbOfTuple,nbOfComp);
9164       return true;
9165     }
9166   return false;
9167 }
9168
9169 /*!
9170  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9171  * This method returns if a feeding is needed.
9172  */
9173 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9174 {
9175   setName(tinyInfoS[0]);
9176   if(isAllocated())
9177     {
9178       int nbOfCompo=tinyInfoI[1];
9179       for(int i=0;i<nbOfCompo;i++)
9180         setInfoOnComponent(i,tinyInfoS[i+1]);
9181     }
9182 }
9183
9184 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9185 {
9186   if(_da)
9187     {
9188       _da->incrRef();
9189       if(_da->isAllocated())
9190         {
9191           _nb_comp=da->getNumberOfComponents();
9192           _nb_tuple=da->getNumberOfTuples();
9193           _pt=da->getPointer();
9194         }
9195     }
9196 }
9197
9198 DataArrayIntIterator::~DataArrayIntIterator()
9199 {
9200   if(_da)
9201     _da->decrRef();
9202 }
9203
9204 DataArrayIntTuple *DataArrayIntIterator::nextt()
9205 {
9206   if(_tuple_id<_nb_tuple)
9207     {
9208       _tuple_id++;
9209       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9210       _pt+=_nb_comp;
9211       return ret;
9212     }
9213   else
9214     return 0;
9215 }
9216
9217 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9218 {
9219 }
9220
9221 std::string DataArrayIntTuple::repr() const
9222 {
9223   std::ostringstream oss; oss << "(";
9224   for(int i=0;i<_nb_of_compo-1;i++)
9225     oss << _pt[i] << ", ";
9226   oss << _pt[_nb_of_compo-1] << ")";
9227   return oss.str();
9228 }
9229
9230 int DataArrayIntTuple::intValue() const
9231 {
9232   if(_nb_of_compo==1)
9233     return *_pt;
9234   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9235 }
9236
9237 /*!
9238  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9239  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9240  * 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
9241  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9242  */
9243 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9244 {
9245   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9246     {
9247       DataArrayInt *ret=DataArrayInt::New();
9248       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9249       return ret;
9250     }
9251   else
9252     {
9253       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9254       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9255       throw INTERP_KERNEL::Exception(oss.str().c_str());
9256     }
9257 }