Salome HOME
Impl of methods cart->cyl cart->pol cart->spher
[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 DataArrayTemplate<int>;
40 template class DataArrayTemplate<double>;
41
42 template<int SPACEDIM>
43 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
44 {
45   const double *coordsPtr=getConstPointer();
46   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
47   std::vector<bool> isDone(nbNodes);
48   for(int i=0;i<nbNodes;i++)
49     {
50       if(!isDone[i])
51         {
52           std::vector<int> intersectingElems;
53           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
54           if(intersectingElems.size()>1)
55             {
56               std::vector<int> commonNodes;
57               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
58                 if(*it!=i)
59                   if(*it>=limitNodeId)
60                     {
61                       commonNodes.push_back(*it);
62                       isDone[*it]=true;
63                     }
64               if(!commonNodes.empty())
65                 {
66                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
67                   c->pushBackSilent(i);
68                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
69                 }
70             }
71         }
72     }
73 }
74
75 template<int SPACEDIM>
76 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
77                                                 DataArrayInt *c, DataArrayInt *cI)
78 {
79   for(int i=0;i<nbOfTuples;i++)
80     {
81       std::vector<int> intersectingElems;
82       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
83       std::vector<int> commonNodes;
84       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
85         commonNodes.push_back(*it);
86       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
87       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
88     }
89 }
90
91 template<int SPACEDIM>
92 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
93 {
94   double distOpt(dist);
95   const double *p(pos);
96   int *r(res);
97   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
98     {
99       while(true)
100         {
101           int elem=-1;
102           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
103           if(ret!=std::numeric_limits<double>::max())
104             {
105               distOpt=std::max(ret,1e-4);
106               *r=elem;
107               break;
108             }
109           else
110             { distOpt=2*distOpt; continue; }
111         }
112     }
113 }
114
115 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
116 {
117   std::size_t sz1=_name.capacity();
118   std::size_t sz2=_info_on_compo.capacity();
119   std::size_t sz3=0;
120   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
121     sz3+=(*it).capacity();
122   return sz1+sz2+sz3;
123 }
124
125 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
126 {
127   return std::vector<const BigMemoryObject *>();
128 }
129
130 /*!
131  * Sets the attribute \a _name of \a this array.
132  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
133  *  \param [in] name - new array name
134  */
135 void DataArray::setName(const std::string& name)
136 {
137   _name=name;
138 }
139
140 /*!
141  * Copies textual data from an \a other DataArray. The copied data are
142  * - the name attribute,
143  * - the information of components.
144  *
145  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
146  *
147  *  \param [in] other - another instance of DataArray to copy the textual data from.
148  *  \throw If number of components of \a this array differs from that of the \a other.
149  */
150 void DataArray::copyStringInfoFrom(const DataArray& other)
151 {
152   if(_info_on_compo.size()!=other._info_on_compo.size())
153     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
154   _name=other._name;
155   _info_on_compo=other._info_on_compo;
156 }
157
158 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
159 {
160   int nbOfCompoOth=other.getNumberOfComponents();
161   std::size_t newNbOfCompo=compoIds.size();
162   for(std::size_t i=0;i<newNbOfCompo;i++)
163     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
164       {
165         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
166         throw INTERP_KERNEL::Exception(oss.str().c_str());
167       }
168   for(std::size_t i=0;i<newNbOfCompo;i++)
169     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
170 }
171
172 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
173 {
174   int nbOfCompo=getNumberOfComponents();
175   std::size_t partOfCompoToSet=compoIds.size();
176   if((int)partOfCompoToSet!=other.getNumberOfComponents())
177     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
178   for(std::size_t i=0;i<partOfCompoToSet;i++)
179     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
180       {
181         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
182         throw INTERP_KERNEL::Exception(oss.str().c_str());
183       }
184   for(std::size_t i=0;i<partOfCompoToSet;i++)
185     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
186 }
187
188 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
189 {
190   std::ostringstream oss;
191   if(_name!=other._name)
192     {
193       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
194       reason=oss.str();
195       return false;
196     }
197   if(_info_on_compo!=other._info_on_compo)
198     {
199       oss << "Components DataArray mismatch : \nThis components=";
200       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
201         oss << "\"" << *it << "\",";
202       oss << "\nOther components=";
203       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
204         oss << "\"" << *it << "\",";
205       reason=oss.str();
206       return false;
207     }
208   return true;
209 }
210
211 /*!
212  * Compares textual information of \a this DataArray with that of an \a other one.
213  * The compared data are
214  * - the name attribute,
215  * - the information of components.
216  *
217  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
218  *  \param [in] other - another instance of DataArray to compare the textual data of.
219  *  \return bool - \a true if the textual information is same, \a false else.
220  */
221 bool DataArray::areInfoEquals(const DataArray& other) const
222 {
223   std::string tmp;
224   return areInfoEqualsIfNotWhy(other,tmp);
225 }
226
227 void DataArray::reprWithoutNameStream(std::ostream& stream) const
228 {
229   stream << "Number of components : "<< getNumberOfComponents() << "\n";
230   stream << "Info of these components : ";
231   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
232     stream << "\"" << *iter << "\"   ";
233   stream << "\n";
234 }
235
236 std::string DataArray::cppRepr(const std::string& varName) const
237 {
238   std::ostringstream ret;
239   reprCppStream(varName,ret);
240   return ret.str();
241 }
242
243 /*!
244  * Sets information on all components. To know more on format of this information
245  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
246  *  \param [in] info - a vector of strings.
247  *  \throw If size of \a info differs from the number of components of \a this.
248  */
249 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
250 {
251   if(getNumberOfComponents()!=(int)info.size())
252     {
253       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
254       throw INTERP_KERNEL::Exception(oss.str().c_str());
255     }
256   _info_on_compo=info;
257 }
258
259 /*!
260  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
261  * type of \a this and \a aBase.
262  *
263  * \throw If \a aBase and \a this do not have the same type.
264  *
265  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
266  */
267 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
268 {
269   if(!aBase)
270     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
271   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
272   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
273   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
274   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
275   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
276   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
277   if(this1 && a1)
278     {
279       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
280       return ;
281     }
282   if(this2 && a2)
283     {
284       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
285       return ;
286     }
287   if(this3 && a3)
288     {
289       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
290       return ;
291     }
292   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
293 }
294
295 std::vector<std::string> DataArray::getVarsOnComponent() const
296 {
297   int nbOfCompo=(int)_info_on_compo.size();
298   std::vector<std::string> ret(nbOfCompo);
299   for(int i=0;i<nbOfCompo;i++)
300     ret[i]=getVarOnComponent(i);
301   return ret;
302 }
303
304 std::vector<std::string> DataArray::getUnitsOnComponent() const
305 {
306   int nbOfCompo=(int)_info_on_compo.size();
307   std::vector<std::string> ret(nbOfCompo);
308   for(int i=0;i<nbOfCompo;i++)
309     ret[i]=getUnitOnComponent(i);
310   return ret;
311 }
312
313 /*!
314  * Returns information on a component specified by an index.
315  * To know more on format of this information
316  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
317  *  \param [in] i - the index (zero based) of the component of interest.
318  *  \return std::string - a string containing the information on \a i-th component.
319  *  \throw If \a i is not a valid component index.
320  */
321 std::string DataArray::getInfoOnComponent(int i) const
322 {
323   if(i<(int)_info_on_compo.size() && i>=0)
324     return _info_on_compo[i];
325   else
326     {
327       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();
328       throw INTERP_KERNEL::Exception(oss.str().c_str());
329     }
330 }
331
332 /*!
333  * Returns the var part of the full information of the \a i-th component.
334  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
335  * \c getVarOnComponent(0) returns "SIGXY".
336  * If a unit part of information is not detected by presence of
337  * two square brackets, then the full information is returned.
338  * To read more about the component information format, see
339  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
340  *  \param [in] i - the index (zero based) of the component of interest.
341  *  \return std::string - a string containing the var information, or the full info.
342  *  \throw If \a i is not a valid component index.
343  */
344 std::string DataArray::getVarOnComponent(int i) const
345 {
346   if(i<(int)_info_on_compo.size() && i>=0)
347     {
348       return GetVarNameFromInfo(_info_on_compo[i]);
349     }
350   else
351     {
352       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();
353       throw INTERP_KERNEL::Exception(oss.str().c_str());
354     }
355 }
356
357 /*!
358  * Returns the unit part of the full information of the \a i-th component.
359  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
360  * \c getUnitOnComponent(0) returns " N/m^2".
361  * If a unit part of information is not detected by presence of
362  * two square brackets, then an empty string is returned.
363  * To read more about the component information format, see
364  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
365  *  \param [in] i - the index (zero based) of the component of interest.
366  *  \return std::string - a string containing the unit information, if any, or "".
367  *  \throw If \a i is not a valid component index.
368  */
369 std::string DataArray::getUnitOnComponent(int i) const
370 {
371   if(i<(int)_info_on_compo.size() && i>=0)
372     {
373       return GetUnitFromInfo(_info_on_compo[i]);
374     }
375   else
376     {
377       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();
378       throw INTERP_KERNEL::Exception(oss.str().c_str());
379     }
380 }
381
382 /*!
383  * Returns the var part of the full component information.
384  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
385  * If a unit part of information is not detected by presence of
386  * two square brackets, then the whole \a info is returned.
387  * To read more about the component information format, see
388  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
389  *  \param [in] info - the full component information.
390  *  \return std::string - a string containing only var information, or the \a info.
391  */
392 std::string DataArray::GetVarNameFromInfo(const std::string& info)
393 {
394   std::size_t p1=info.find_last_of('[');
395   std::size_t p2=info.find_last_of(']');
396   if(p1==std::string::npos || p2==std::string::npos)
397     return info;
398   if(p1>p2)
399     return info;
400   if(p1==0)
401     return std::string();
402   std::size_t p3=info.find_last_not_of(' ',p1-1);
403   return info.substr(0,p3+1);
404 }
405
406 /*!
407  * Returns the unit part of the full component information.
408  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
409  * If a unit part of information is not detected by presence of
410  * two square brackets, then an empty string is returned.
411  * To read more about the component information format, see
412  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
413  *  \param [in] info - the full component information.
414  *  \return std::string - a string containing only unit information, if any, or "".
415  */
416 std::string DataArray::GetUnitFromInfo(const std::string& info)
417 {
418   std::size_t p1=info.find_last_of('[');
419   std::size_t p2=info.find_last_of(']');
420   if(p1==std::string::npos || p2==std::string::npos)
421     return std::string();
422   if(p1>p2)
423     return std::string();
424   return info.substr(p1+1,p2-p1-1);
425 }
426
427 /*!
428  * This method put in info format the result of the merge of \a var and \a unit.
429  * The standard format for that is "var [unit]".
430  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
431  */
432 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
433 {
434   std::ostringstream oss;
435   oss << var << " [" << unit << "]";
436   return oss.str();
437 }
438
439 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
440 {
441   switch(at)
442     {
443     case AX_CART:
444       return std::string("AX_CART");
445     case AX_CYL:
446       return std::string("AX_CYL");
447     case AX_SPHER:
448       return std::string("AX_SPHER");
449     default:
450       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
451     }
452 }
453
454 /*!
455  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
456  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
457  * the number of component in the result array is same as that of each of given arrays.
458  * Info on components is copied from the first of the given arrays. Number of components
459  * in the given arrays must be  the same.
460  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
461  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
462  *          The caller is to delete this result array using decrRef() as it is no more
463  *          needed.
464  *  \throw If all arrays within \a arrs are NULL.
465  *  \throw If all not null arrays in \a arrs have not the same type.
466  *  \throw If getNumberOfComponents() of arrays within \a arrs.
467  */
468 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
469 {
470   std::vector<const DataArray *> arr2;
471   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
472     if(*it)
473       arr2.push_back(*it);
474   if(arr2.empty())
475     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
476   std::vector<const DataArrayDouble *> arrd;
477   std::vector<const DataArrayInt *> arri;
478   std::vector<const DataArrayChar *> arrc;
479   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
480     {
481       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
482       if(a)
483         { arrd.push_back(a); continue; }
484       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
485       if(b)
486         { arri.push_back(b); continue; }
487       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
488       if(c)
489         { arrc.push_back(c); continue; }
490       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
491     }
492   if(arr2.size()==arrd.size())
493     return DataArrayDouble::Aggregate(arrd);
494   if(arr2.size()==arri.size())
495     return DataArrayInt::Aggregate(arri);
496   if(arr2.size()==arrc.size())
497     return DataArrayChar::Aggregate(arrc);
498   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
499 }
500
501 /*!
502  * Sets information on a component specified by an index.
503  * To know more on format of this information
504  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
505  *  \warning Don't pass NULL as \a info!
506  *  \param [in] i - the index (zero based) of the component of interest.
507  *  \param [in] info - the string containing the information.
508  *  \throw If \a i is not a valid component index.
509  */
510 void DataArray::setInfoOnComponent(int i, const std::string& info)
511 {
512   if(i<(int)_info_on_compo.size() && i>=0)
513     _info_on_compo[i]=info;
514   else
515     {
516       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();
517       throw INTERP_KERNEL::Exception(oss.str().c_str());
518     }
519 }
520
521 /*!
522  * Sets information on all components. This method can change number of components
523  * at certain conditions; if the conditions are not respected, an exception is thrown.
524  * The number of components can be changed in \a this only if \a this is not allocated.
525  * The condition of number of components must not be changed.
526  *
527  * To know more on format of the component information see
528  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
529  *  \param [in] info - a vector of component infos.
530  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
531  */
532 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
533 {
534   if(getNumberOfComponents()!=(int)info.size())
535     {
536       if(!isAllocated())
537         _info_on_compo=info;
538       else
539         {
540           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 !";
541           throw INTERP_KERNEL::Exception(oss.str().c_str());
542         }
543     }
544   else
545     _info_on_compo=info;
546 }
547
548 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
549 {
550   if(getNumberOfTuples()!=nbOfTuples)
551     {
552       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
553       throw INTERP_KERNEL::Exception(oss.str().c_str());
554     }
555 }
556
557 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
558 {
559   if(getNumberOfComponents()!=nbOfCompo)
560     {
561       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
562       throw INTERP_KERNEL::Exception(oss.str().c_str());
563     }
564 }
565
566 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
567 {
568   if(getNbOfElems()!=nbOfElems)
569     {
570       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
571       throw INTERP_KERNEL::Exception(oss.str().c_str());
572     }
573 }
574
575 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
576 {
577   if(getNumberOfTuples()!=other.getNumberOfTuples())
578     {
579       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582   if(getNumberOfComponents()!=other.getNumberOfComponents())
583     {
584       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
585       throw INTERP_KERNEL::Exception(oss.str().c_str());
586     }
587 }
588
589 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
590 {
591   checkNbOfTuples(nbOfTuples,msg);
592   checkNbOfComps(nbOfCompo,msg);
593 }
594
595 /*!
596  * Simply this method checks that \b value is in [0,\b ref).
597  */
598 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
599 {
600   if(value<0 || value>=ref)
601     {
602       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
603       throw INTERP_KERNEL::Exception(oss.str().c_str());
604     }
605 }
606
607 /*!
608  * This method checks that [\b start, \b end) is compliant with ref length \b value.
609  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
610  */
611 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
612 {
613   if(start<0 || start>=value)
614     {
615       if(value!=start || end!=start)
616         {
617           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
618           throw INTERP_KERNEL::Exception(oss.str().c_str());
619         }
620     }
621   if(end<0 || end>value)
622     {
623       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
624       throw INTERP_KERNEL::Exception(oss.str().c_str());
625     }
626 }
627
628 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
629 {
630   if(value<0 || value>ref)
631     {
632       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
633       throw INTERP_KERNEL::Exception(oss.str().c_str());
634     }
635 }
636
637 /*!
638  * 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, 
639  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
640  *
641  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
642  *
643  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
644  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
645  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
646  * \param [in] sliceId - the slice id considered
647  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
648  * \param [out] startSlice - the start of the slice considered
649  * \param [out] stopSlice - the stop of the slice consided
650  * 
651  * \throw If \a step == 0
652  * \throw If \a nbOfSlices not > 0
653  * \throw If \a sliceId not in [0,nbOfSlices)
654  */
655 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
656 {
657   if(nbOfSlices<=0)
658     {
659       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
660       throw INTERP_KERNEL::Exception(oss.str().c_str());
661     }
662   if(sliceId<0 || sliceId>=nbOfSlices)
663     {
664       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
665       throw INTERP_KERNEL::Exception(oss.str().c_str());
666     }
667   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
668   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
669   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
670   if(sliceId<nbOfSlices-1)
671     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
672   else
673     stopSlice=stop;
674 }
675
676 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
677 {
678   if(end<begin)
679     {
680       std::ostringstream oss; oss << msg << " : end before begin !";
681       throw INTERP_KERNEL::Exception(oss.str().c_str());
682     }
683   if(end==begin)
684     return 0;
685   if(step<=0)
686     {
687       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   return (end-1-begin)/step+1;
691 }
692
693 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
694 {
695   if(step==0)
696     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
697   if(end<begin && step>0)
698     {
699       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
700       throw INTERP_KERNEL::Exception(oss.str().c_str());
701     }
702   if(begin<end && step<0)
703     {
704       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
705       throw INTERP_KERNEL::Exception(oss.str().c_str());
706     }
707   if(begin!=end)
708     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
709   else
710     return 0;
711 }
712
713 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
714 {
715   if(step!=0)
716     {
717       if(step>0)
718         {
719           if(begin<=value && value<end)
720             {
721               if((value-begin)%step==0)
722                 return (value-begin)/step;
723               else
724                 return -1;
725             }
726           else
727             return -1;
728         }
729       else
730         {
731           if(begin>=value && value>end)
732             {
733               if((begin-value)%(-step)==0)
734                 return (begin-value)/(-step);
735               else
736                 return -1;
737             }
738           else
739             return -1;
740         }
741     }
742   else
743     return -1;
744 }
745
746 /*!
747  * Returns a new instance of DataArrayDouble. The caller is to delete this array
748  * using decrRef() as it is no more needed. 
749  */
750 DataArrayDouble *DataArrayDouble::New()
751 {
752   return new DataArrayDouble;
753 }
754
755 /*!
756  * Returns the only one value in \a this, if and only if number of elements
757  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
758  *  \return double - the sole value stored in \a this array.
759  *  \throw If at least one of conditions stated above is not fulfilled.
760  */
761 double DataArrayDouble::doubleValue() const
762 {
763   if(isAllocated())
764     {
765       if(getNbOfElems()==1)
766         {
767           return *getConstPointer();
768         }
769       else
770         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
771     }
772   else
773     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
774 }
775
776 /*!
777  * Returns a full copy of \a this. For more info on copying data arrays see
778  * \ref MEDCouplingArrayBasicsCopyDeep.
779  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
780  *          delete this array using decrRef() as it is no more needed. 
781  */
782 DataArrayDouble *DataArrayDouble::deepCopy() const
783 {
784   return new DataArrayDouble(*this);
785 }
786
787 /*!
788  * Returns either a \a deep or \a shallow copy of this array. For more info see
789  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
790  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
791  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
792  *          == \a true) or \a this instance (if \a dCpy == \a false).
793  */
794 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
795 {
796   if(dCpy)
797     return deepCopy();
798   else
799     {
800       incrRef();
801       return const_cast<DataArrayDouble *>(this);
802     }
803 }
804
805 /*!
806  * Assign zero to all values in \a this array. To know more on filling arrays see
807  * \ref MEDCouplingArrayFill.
808  * \throw If \a this is not allocated.
809  */
810 void DataArrayDouble::fillWithZero()
811 {
812   fillWithValue(0.);
813 }
814
815 /*!
816  * Set all values in \a this array so that the i-th element equals to \a init + i
817  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
818  *  \param [in] init - value to assign to the first element of array.
819  *  \throw If \a this->getNumberOfComponents() != 1
820  *  \throw If \a this is not allocated.
821  */
822 void DataArrayDouble::iota(double init)
823 {
824   checkAllocated();
825   if(getNumberOfComponents()!=1)
826     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
827   double *ptr=getPointer();
828   int ntuples=getNumberOfTuples();
829   for(int i=0;i<ntuples;i++)
830     ptr[i]=init+double(i);
831   declareAsNew();
832 }
833
834 /*!
835  * Checks if all values in \a this array are equal to \a val at precision \a eps.
836  *  \param [in] val - value to check equality of array values to.
837  *  \param [in] eps - precision to check the equality.
838  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
839  *                 \a false else.
840  *  \throw If \a this->getNumberOfComponents() != 1
841  *  \throw If \a this is not allocated.
842  */
843 bool DataArrayDouble::isUniform(double val, double eps) const
844 {
845   checkAllocated();
846   if(getNumberOfComponents()!=1)
847     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
848   int nbOfTuples=getNumberOfTuples();
849   const double *w=getConstPointer();
850   const double *end2=w+nbOfTuples;
851   const double vmin=val-eps;
852   const double vmax=val+eps;
853   for(;w!=end2;w++)
854     if(*w<vmin || *w>vmax)
855       return false;
856   return true;
857 }
858
859 /*!
860  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
861  * with at least absolute difference value of |\a eps| at each step.
862  * If not an exception is thrown.
863  *  \param [in] increasing - if \a true, the array values should be increasing.
864  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
865  *                    the values are considered different.
866  *  \throw If sequence of values is not strictly monotonic in agreement with \a
867  *         increasing arg.
868  *  \throw If \a this->getNumberOfComponents() != 1.
869  *  \throw If \a this is not allocated.
870  */
871 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
872 {
873   if(!isMonotonic(increasing,eps))
874     {
875       if (increasing)
876         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
877       else
878         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
879     }
880 }
881
882 /*!
883  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
884  * with at least absolute difference value of |\a eps| at each step.
885  *  \param [in] increasing - if \a true, array values should be increasing.
886  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
887  *                    the values are considered different.
888  *  \return bool - \a true if values change in accordance with \a increasing arg.
889  *  \throw If \a this->getNumberOfComponents() != 1.
890  *  \throw If \a this is not allocated.
891  */
892 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
893 {
894   checkAllocated();
895   if(getNumberOfComponents()!=1)
896     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
897   int nbOfElements=getNumberOfTuples();
898   const double *ptr=getConstPointer();
899   if(nbOfElements==0)
900     return true;
901   double ref=ptr[0];
902   double absEps=fabs(eps);
903   if(increasing)
904     {
905       for(int i=1;i<nbOfElements;i++)
906         {
907           if(ptr[i]<(ref+absEps))
908             return false;
909           ref=ptr[i];
910         }
911       return true;
912     }
913   else
914     {
915       for(int i=1;i<nbOfElements;i++)
916         {
917           if(ptr[i]>(ref-absEps))
918             return false;
919           ref=ptr[i];
920         }
921       return true;
922     }
923 }
924
925 /*!
926  * Returns a textual and human readable representation of \a this instance of
927  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
928  * \return std::string - text describing \a this DataArrayDouble.
929  *
930  * \sa reprNotTooLong, reprZip
931  */
932 std::string DataArrayDouble::repr() const
933 {
934   std::ostringstream ret;
935   reprStream(ret);
936   return ret.str();
937 }
938
939 std::string DataArrayDouble::reprZip() const
940 {
941   std::ostringstream ret;
942   reprZipStream(ret);
943   return ret.str();
944 }
945
946 /*!
947  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
948  * printed out to avoid to consume too much space in interpretor.
949  * \sa repr
950  */
951 std::string DataArrayDouble::reprNotTooLong() const
952 {
953   std::ostringstream ret;
954   reprNotTooLongStream(ret);
955   return ret.str();
956 }
957
958 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
959 {
960   static const char SPACE[4]={' ',' ',' ',' '};
961   checkAllocated();
962   std::string idt(indent,' ');
963   ofs.precision(17);
964   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
965   //
966   bool areAllEmpty(true);
967   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
968     if(!(*it).empty())
969       areAllEmpty=false;
970   if(!areAllEmpty)
971     for(std::size_t i=0;i<_info_on_compo.size();i++)
972       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
973   //
974   if(byteArr)
975     {
976       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
977       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
978       float *pt(tmp);
979       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
980       for(const double *src=begin();src!=end();src++,pt++)
981         *pt=float(*src);
982       const char *data(reinterpret_cast<const char *>((float *)tmp));
983       std::size_t sz(getNbOfElems()*sizeof(float));
984       byteArr->insertAtTheEnd(data,data+sz);
985       byteArr->insertAtTheEnd(SPACE,SPACE+4);
986     }
987   else
988     {
989       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
990       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
991     }
992   ofs << std::endl << idt << "</DataArray>\n";
993 }
994
995 void DataArrayDouble::reprStream(std::ostream& stream) const
996 {
997   stream << "Name of double array : \"" << _name << "\"\n";
998   reprWithoutNameStream(stream);
999 }
1000
1001 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1002 {
1003   stream << "Name of double array : \"" << _name << "\"\n";
1004   reprZipWithoutNameStream(stream);
1005 }
1006
1007 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1008 {
1009   stream << "Name of double array : \"" << _name << "\"\n";
1010   reprNotTooLongWithoutNameStream(stream);
1011 }
1012
1013 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1014 {
1015   DataArray::reprWithoutNameStream(stream);
1016   stream.precision(17);
1017   _mem.repr(getNumberOfComponents(),stream);
1018 }
1019
1020 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1021 {
1022   DataArray::reprWithoutNameStream(stream);
1023   stream.precision(17);
1024   _mem.reprZip(getNumberOfComponents(),stream);
1025 }
1026
1027 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1028 {
1029   DataArray::reprWithoutNameStream(stream);
1030   stream.precision(17);
1031   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1032 }
1033
1034 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1035 {
1036   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1037   const double *data=getConstPointer();
1038   stream.precision(17);
1039   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1040   if(nbTuples*nbComp>=1)
1041     {
1042       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1043       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1044       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1045       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1046     }
1047   else
1048     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1049   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1050 }
1051
1052 /*!
1053  * Method that gives a quick overvien of \a this for python.
1054  */
1055 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1056 {
1057   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1058   stream << "DataArrayDouble C++ instance at " << this << ". ";
1059   if(isAllocated())
1060     {
1061       int nbOfCompo=(int)_info_on_compo.size();
1062       if(nbOfCompo>=1)
1063         {
1064           int nbOfTuples=getNumberOfTuples();
1065           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1066           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1067         }
1068       else
1069         stream << "Number of components : 0.";
1070     }
1071   else
1072     stream << "*** No data allocated ****";
1073 }
1074
1075 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1076 {
1077   const double *data=begin();
1078   int nbOfTuples=getNumberOfTuples();
1079   int nbOfCompo=(int)_info_on_compo.size();
1080   std::ostringstream oss2; oss2 << "[";
1081   oss2.precision(17);
1082   std::string oss2Str(oss2.str());
1083   bool isFinished=true;
1084   for(int i=0;i<nbOfTuples && isFinished;i++)
1085     {
1086       if(nbOfCompo>1)
1087         {
1088           oss2 << "(";
1089           for(int j=0;j<nbOfCompo;j++,data++)
1090             {
1091               oss2 << *data;
1092               if(j!=nbOfCompo-1) oss2 << ", ";
1093             }
1094           oss2 << ")";
1095         }
1096       else
1097         oss2 << *data++;
1098       if(i!=nbOfTuples-1) oss2 << ", ";
1099       std::string oss3Str(oss2.str());
1100       if(oss3Str.length()<maxNbOfByteInRepr)
1101         oss2Str=oss3Str;
1102       else
1103         isFinished=false;
1104     }
1105   stream << oss2Str;
1106   if(!isFinished)
1107     stream << "... ";
1108   stream << "]";
1109 }
1110
1111 /*!
1112  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1113  * mismatch is given.
1114  * 
1115  * \param [in] other the instance to be compared with \a this
1116  * \param [in] prec the precision to compare numeric data of the arrays.
1117  * \param [out] reason In case of inequality returns the reason.
1118  * \sa DataArrayDouble::isEqual
1119  */
1120 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1121 {
1122   if(!areInfoEqualsIfNotWhy(other,reason))
1123     return false;
1124   return _mem.isEqual(other._mem,prec,reason);
1125 }
1126
1127 /*!
1128  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1129  * \ref MEDCouplingArrayBasicsCompare.
1130  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1131  *  \param [in] prec - precision value to compare numeric data of the arrays.
1132  *  \return bool - \a true if the two arrays are equal, \a false else.
1133  */
1134 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1135 {
1136   std::string tmp;
1137   return isEqualIfNotWhy(other,prec,tmp);
1138 }
1139
1140 /*!
1141  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1142  * \ref MEDCouplingArrayBasicsCompare.
1143  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1144  *  \param [in] prec - precision value to compare numeric data of the arrays.
1145  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1146  */
1147 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1148 {
1149   std::string tmp;
1150   return _mem.isEqual(other._mem,prec,tmp);
1151 }
1152
1153 /*!
1154  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1155  * array to the new one.
1156  *  \return DataArrayInt * - the new instance of DataArrayInt.
1157  */
1158 DataArrayInt *DataArrayDouble::convertToIntArr() const
1159 {
1160   DataArrayInt *ret=DataArrayInt::New();
1161   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1162   int *dest=ret->getPointer();
1163   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1164   for(const double *src=begin();src!=end();src++,dest++)
1165     *dest=(int)*src;
1166   ret->copyStringInfoFrom(*this);
1167   return ret;
1168 }
1169
1170 /*!
1171  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1172  * arranged in memory. If \a this array holds 2 components of 3 values:
1173  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1174  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1175  *  \warning Do not confuse this method with transpose()!
1176  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1177  *          is to delete using decrRef() as it is no more needed.
1178  *  \throw If \a this is not allocated.
1179  */
1180 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1181 {
1182   if(_mem.isNull())
1183     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1184   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1185   DataArrayDouble *ret=DataArrayDouble::New();
1186   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1187   return ret;
1188 }
1189
1190 /*!
1191  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1192  * arranged in memory. If \a this array holds 2 components of 3 values:
1193  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1194  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1195  *  \warning Do not confuse this method with transpose()!
1196  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1197  *          is to delete using decrRef() as it is no more needed.
1198  *  \throw If \a this is not allocated.
1199  */
1200 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1201 {
1202   if(_mem.isNull())
1203     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1204   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1205   DataArrayDouble *ret=DataArrayDouble::New();
1206   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1207   return ret;
1208 }
1209
1210 /*!
1211  * Appends components of another array to components of \a this one, tuple by tuple.
1212  * So that the number of tuples of \a this array remains the same and the number of 
1213  * components increases.
1214  *  \param [in] other - the DataArrayDouble to append to \a this one.
1215  *  \throw If \a this is not allocated.
1216  *  \throw If \a this and \a other arrays have different number of tuples.
1217  *
1218  *  \if ENABLE_EXAMPLES
1219  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1220  *
1221  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1222  *  \endif
1223  */
1224 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1225 {
1226   checkAllocated();
1227   other->checkAllocated();
1228   int nbOfTuples=getNumberOfTuples();
1229   if(nbOfTuples!=other->getNumberOfTuples())
1230     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1231   int nbOfComp1=getNumberOfComponents();
1232   int nbOfComp2=other->getNumberOfComponents();
1233   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1234   double *w=newArr;
1235   const double *inp1=getConstPointer();
1236   const double *inp2=other->getConstPointer();
1237   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1238     {
1239       w=std::copy(inp1,inp1+nbOfComp1,w);
1240       w=std::copy(inp2,inp2+nbOfComp2,w);
1241     }
1242   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1243   std::vector<int> compIds(nbOfComp2);
1244   for(int i=0;i<nbOfComp2;i++)
1245     compIds[i]=nbOfComp1+i;
1246   copyPartOfStringInfoFrom2(compIds,*other);
1247 }
1248
1249 /*!
1250  * This method checks that all tuples in \a other are in \a this.
1251  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1252  * 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.
1253  *
1254  * \param [in] other - the array having the same number of components than \a this.
1255  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1256  * \sa DataArrayDouble::findCommonTuples
1257  */
1258 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1259 {
1260   if(!other)
1261     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1262   checkAllocated(); other->checkAllocated();
1263   if(getNumberOfComponents()!=other->getNumberOfComponents())
1264     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1265   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1266   DataArrayInt *c=0,*ci=0;
1267   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1268   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1269   int newNbOfTuples=-1;
1270   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1271   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1272   tupleIds=ret1.retn();
1273   return newNbOfTuples==getNumberOfTuples();
1274 }
1275
1276 /*!
1277  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1278  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1279  * distance separating two points is computed with the infinite norm.
1280  *
1281  * Indices of coincident tuples are stored in output arrays.
1282  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1283  *
1284  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1285  * MEDCouplingUMesh::mergeNodes().
1286  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1287  *              considered not coincident.
1288  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1289  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1290  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1291  *               \a comm->getNumberOfComponents() == 1. 
1292  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1293  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1294  *               groups of (indices of) coincident tuples. Its every value is a tuple
1295  *               index where a next group of tuples begins. For example the second
1296  *               group of tuples in \a comm is described by following range of indices:
1297  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1298  *               gives the number of groups of coincident tuples.
1299  *  \throw If \a this is not allocated.
1300  *  \throw If the number of components is not in [1,2,3,4].
1301  *
1302  *  \if ENABLE_EXAMPLES
1303  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1304  *
1305  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1306  *  \endif
1307  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1308  */
1309 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1310 {
1311   checkAllocated();
1312   int nbOfCompo=getNumberOfComponents();
1313   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1314     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1315
1316   int nbOfTuples=getNumberOfTuples();
1317   //
1318   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1319   switch(nbOfCompo)
1320   {
1321     case 4:
1322       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1323       break;
1324     case 3:
1325       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1326       break;
1327     case 2:
1328       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1329       break;
1330     case 1:
1331       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1332       break;
1333     default:
1334       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1335   }
1336   comm=c.retn();
1337   commIndex=cI.retn();
1338 }
1339
1340 /*!
1341  * 
1342  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1343  *             \a nbTimes  should be at least equal to 1.
1344  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1345  * \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.
1346  */
1347 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1348 {
1349   checkAllocated();
1350   if(getNumberOfComponents()!=1)
1351     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1352   if(nbTimes<1)
1353     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1354   int nbTuples=getNumberOfTuples();
1355   const double *inPtr=getConstPointer();
1356   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1357   double *retPtr=ret->getPointer();
1358   for(int i=0;i<nbTuples;i++,inPtr++)
1359     {
1360       double val=*inPtr;
1361       for(int j=0;j<nbTimes;j++,retPtr++)
1362         *retPtr=val;
1363     }
1364   ret->copyStringInfoFrom(*this);
1365   return ret.retn();
1366 }
1367
1368 /*!
1369  * This methods returns the minimal distance between the two set of points \a this and \a other.
1370  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1371  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1372  *
1373  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1374  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1375  * \return the minimal distance between the two set of points \a this and \a other.
1376  * \sa DataArrayDouble::findClosestTupleId
1377  */
1378 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1379 {
1380   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1381   int nbOfCompo(getNumberOfComponents());
1382   int otherNbTuples(other->getNumberOfTuples());
1383   const double *thisPt(begin()),*otherPt(other->begin());
1384   const int *part1Pt(part1->begin());
1385   double ret=std::numeric_limits<double>::max();
1386   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1387     {
1388       double tmp(0.);
1389       for(int j=0;j<nbOfCompo;j++)
1390         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1391       if(tmp<ret)
1392         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1393     }
1394   return sqrt(ret);
1395 }
1396
1397 /*!
1398  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1399  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1400  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1401  *
1402  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1403  * \sa DataArrayDouble::minimalDistanceTo
1404  */
1405 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1406 {
1407   if(!other)
1408     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1409   checkAllocated(); other->checkAllocated();
1410   int nbOfCompo=getNumberOfComponents();
1411   if(nbOfCompo!=other->getNumberOfComponents())
1412     {
1413       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1414       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1415       throw INTERP_KERNEL::Exception(oss.str().c_str());
1416     }
1417   int nbOfTuples=other->getNumberOfTuples();
1418   int thisNbOfTuples=getNumberOfTuples();
1419   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1420   double bounds[6];
1421   getMinMaxPerComponent(bounds);
1422   switch(nbOfCompo)
1423   {
1424     case 3:
1425       {
1426         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1427         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1428         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1429         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1430         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1431         break;
1432       }
1433     case 2:
1434       {
1435         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1436         double delta=std::max(xDelta,yDelta);
1437         double characSize=sqrt(delta/(double)thisNbOfTuples);
1438         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1439         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1440         break;
1441       }
1442     case 1:
1443       {
1444         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1445         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1446         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1447         break;
1448       }
1449     default:
1450       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1451   }
1452   return ret.retn();
1453 }
1454
1455 /*!
1456  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1457  * 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
1458  * how many bounding boxes in \a otherBBoxFrmt.
1459  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1460  *
1461  * \param [in] otherBBoxFrmt - It is an array .
1462  * \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.
1463  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1464  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1465  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1466  */
1467 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1468 {
1469   if(!otherBBoxFrmt)
1470     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1471   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1472     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1473   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1474   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1475     {
1476       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1477       throw INTERP_KERNEL::Exception(oss.str().c_str());
1478     }
1479   if(nbOfComp%2!=0)
1480     {
1481       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1482       throw INTERP_KERNEL::Exception(oss.str().c_str());
1483     }
1484   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1485   const double *thisBBPtr(begin());
1486   int *retPtr(ret->getPointer());
1487   switch(nbOfComp/2)
1488   {
1489     case 3:
1490       {
1491         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1492         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1493           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1494         break;
1495       }
1496     case 2:
1497       {
1498         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1499         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1500           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1501         break;
1502       }
1503     case 1:
1504       {
1505         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1506         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1507           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1508         break;
1509       }
1510     default:
1511       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1512   }
1513
1514   return ret.retn();
1515 }
1516
1517 /*!
1518  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1519  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1520  * space. The distance between tuples is computed using norm2. If several tuples are
1521  * not far each from other than \a prec, only one of them remains in the result
1522  * array. The order of tuples in the result array is same as in \a this one except
1523  * that coincident tuples are excluded.
1524  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1525  *              considered not coincident.
1526  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1527  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1528  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1529  *          is to delete using decrRef() as it is no more needed.
1530  *  \throw If \a this is not allocated.
1531  *  \throw If the number of components is not in [1,2,3,4].
1532  *
1533  *  \if ENABLE_EXAMPLES
1534  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1535  *  \endif
1536  */
1537 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1538 {
1539   checkAllocated();
1540   DataArrayInt *c0=0,*cI0=0;
1541   findCommonTuples(prec,limitTupleId,c0,cI0);
1542   MCAuto<DataArrayInt> c(c0),cI(cI0);
1543   int newNbOfTuples=-1;
1544   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1545   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1546 }
1547
1548 /*!
1549  * Copy all components in a specified order from another DataArrayDouble.
1550  * Both numerical and textual data is copied. The number of tuples in \a this and
1551  * the other array can be different.
1552  *  \param [in] a - the array to copy data from.
1553  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1554  *              to be copied.
1555  *  \throw If \a a is NULL.
1556  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1557  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1558  *
1559  *  \if ENABLE_EXAMPLES
1560  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1561  *  \endif
1562  */
1563 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1564 {
1565   if(!a)
1566     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1567   checkAllocated();
1568   copyPartOfStringInfoFrom2(compoIds,*a);
1569   std::size_t partOfCompoSz=compoIds.size();
1570   int nbOfCompo=getNumberOfComponents();
1571   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1572   const double *ac=a->getConstPointer();
1573   double *nc=getPointer();
1574   for(int i=0;i<nbOfTuples;i++)
1575     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1576       nc[nbOfCompo*i+compoIds[j]]=*ac;
1577 }
1578
1579 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1580 {
1581   if(newArray!=arrayToSet)
1582     {
1583       if(arrayToSet)
1584         arrayToSet->decrRef();
1585       arrayToSet=newArray;
1586       if(arrayToSet)
1587         arrayToSet->incrRef();
1588     }
1589 }
1590
1591 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1592 {
1593   if(!other)
1594     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1595   if(getNumberOfComponents()!=other->getNumberOfComponents())
1596     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1597   _mem.insertAtTheEnd(other->begin(),other->end());
1598 }
1599
1600 /*!
1601  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1602  * is thrown.
1603  * \throw If zero is found in \a this array.
1604  */
1605 void DataArrayDouble::checkNoNullValues() const
1606 {
1607   const double *tmp=getConstPointer();
1608   std::size_t nbOfElems=getNbOfElems();
1609   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1610   if(where!=tmp+nbOfElems)
1611     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1612 }
1613
1614 /*!
1615  * Computes minimal and maximal value in each component. An output array is filled
1616  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1617  * enough memory before calling this method.
1618  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1619  *               It is filled as follows:<br>
1620  *               \a bounds[0] = \c min_of_component_0 <br>
1621  *               \a bounds[1] = \c max_of_component_0 <br>
1622  *               \a bounds[2] = \c min_of_component_1 <br>
1623  *               \a bounds[3] = \c max_of_component_1 <br>
1624  *               ...
1625  */
1626 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1627 {
1628   checkAllocated();
1629   int dim=getNumberOfComponents();
1630   for (int idim=0; idim<dim; idim++)
1631     {
1632       bounds[idim*2]=std::numeric_limits<double>::max();
1633       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1634     } 
1635   const double *ptr=getConstPointer();
1636   int nbOfTuples=getNumberOfTuples();
1637   for(int i=0;i<nbOfTuples;i++)
1638     {
1639       for(int idim=0;idim<dim;idim++)
1640         {
1641           if(bounds[idim*2]>ptr[i*dim+idim])
1642             {
1643               bounds[idim*2]=ptr[i*dim+idim];
1644             }
1645           if(bounds[idim*2+1]<ptr[i*dim+idim])
1646             {
1647               bounds[idim*2+1]=ptr[i*dim+idim];
1648             }
1649         }
1650     }
1651 }
1652
1653 /*!
1654  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1655  * to store both the min and max per component of each tuples. 
1656  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1657  *
1658  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1659  *
1660  * \throw If \a this is not allocated yet.
1661  */
1662 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1663 {
1664   checkAllocated();
1665   const double *dataPtr=getConstPointer();
1666   int nbOfCompo=getNumberOfComponents();
1667   int nbTuples=getNumberOfTuples();
1668   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1669   bbox->alloc(nbTuples,2*nbOfCompo);
1670   double *bboxPtr=bbox->getPointer();
1671   for(int i=0;i<nbTuples;i++)
1672     {
1673       for(int j=0;j<nbOfCompo;j++)
1674         {
1675           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1676           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1677         }
1678     }
1679   return bbox.retn();
1680 }
1681
1682 /*!
1683  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1684  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1685  * 
1686  * \param [in] other a DataArrayDouble having same number of components than \a this.
1687  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1688  * \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.
1689  *             \a cI allows to extract information in \a c.
1690  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1691  *
1692  * \throw In case of:
1693  *  - \a this is not allocated
1694  *  - \a other is not allocated or null
1695  *  - \a this and \a other do not have the same number of components
1696  *  - if number of components of \a this is not in [1,2,3]
1697  *
1698  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1699  */
1700 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1701 {
1702   if(!other)
1703     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1704   checkAllocated();
1705   other->checkAllocated();
1706   int nbOfCompo=getNumberOfComponents();
1707   int otherNbOfCompo=other->getNumberOfComponents();
1708   if(nbOfCompo!=otherNbOfCompo)
1709     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1710   int nbOfTuplesOther=other->getNumberOfTuples();
1711   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1712   switch(nbOfCompo)
1713   {
1714     case 3:
1715       {
1716         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1717         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1718         break;
1719       }
1720     case 2:
1721       {
1722         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1723         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1724         break;
1725       }
1726     case 1:
1727       {
1728         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1729         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1730         break;
1731       }
1732     default:
1733       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1734   }
1735   c=cArr.retn(); cI=cIArr.retn();
1736 }
1737
1738 /*!
1739  * 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
1740  * around origin of 'radius' 1.
1741  * 
1742  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1743  */
1744 void DataArrayDouble::recenterForMaxPrecision(double eps)
1745 {
1746   checkAllocated();
1747   int dim=getNumberOfComponents();
1748   std::vector<double> bounds(2*dim);
1749   getMinMaxPerComponent(&bounds[0]);
1750   for(int i=0;i<dim;i++)
1751     {
1752       double delta=bounds[2*i+1]-bounds[2*i];
1753       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1754       if(delta>eps)
1755         applyLin(1./delta,-offset/delta,i);
1756       else
1757         applyLin(1.,-offset,i);
1758     }
1759 }
1760
1761 /*!
1762  * Returns the maximal value and all its locations within \a this one-dimensional array.
1763  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1764  *               tuples holding the maximal value. The caller is to delete it using
1765  *               decrRef() as it is no more needed.
1766  *  \return double - the maximal value among all values of \a this array.
1767  *  \throw If \a this->getNumberOfComponents() != 1
1768  *  \throw If \a this->getNumberOfTuples() < 1
1769  */
1770 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1771 {
1772   int tmp;
1773   tupleIds=0;
1774   double ret=getMaxValue(tmp);
1775   tupleIds=findIdsInRange(ret,ret);
1776   return ret;
1777 }
1778
1779 /*!
1780  * Returns the minimal 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 minimal value. The caller is to delete it using
1783  *               decrRef() as it is no more needed.
1784  *  \return double - the minimal 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::getMinValue2(DataArrayInt*& tupleIds) const
1789 {
1790   int tmp;
1791   tupleIds=0;
1792   double ret=getMinValue(tmp);
1793   tupleIds=findIdsInRange(ret,ret);
1794   return ret;
1795 }
1796
1797 /*!
1798  * 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.
1799  * This method only works for single component array.
1800  *
1801  * \return a value in [ 0, \c this->getNumberOfTuples() )
1802  *
1803  * \throw If \a this is not allocated
1804  *
1805  */
1806 int DataArrayDouble::count(double value, double eps) const
1807 {
1808   int ret=0;
1809   checkAllocated();
1810   if(getNumberOfComponents()!=1)
1811     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1812   const double *vals=begin();
1813   int nbOfTuples=getNumberOfTuples();
1814   for(int i=0;i<nbOfTuples;i++,vals++)
1815     if(fabs(*vals-value)<=eps)
1816       ret++;
1817   return ret;
1818 }
1819
1820 /*!
1821  * Returns the average value of \a this one-dimensional array.
1822  *  \return double - the average value over all values of \a this array.
1823  *  \throw If \a this->getNumberOfComponents() != 1
1824  *  \throw If \a this->getNumberOfTuples() < 1
1825  */
1826 double DataArrayDouble::getAverageValue() const
1827 {
1828   if(getNumberOfComponents()!=1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1830   int nbOfTuples=getNumberOfTuples();
1831   if(nbOfTuples<=0)
1832     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1833   const double *vals=getConstPointer();
1834   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1835   return ret/nbOfTuples;
1836 }
1837
1838 /*!
1839  * Returns the Euclidean norm of the vector defined by \a this array.
1840  *  \return double - the value of the Euclidean norm, i.e.
1841  *          the square root of the inner product of vector.
1842  *  \throw If \a this is not allocated.
1843  */
1844 double DataArrayDouble::norm2() const
1845 {
1846   checkAllocated();
1847   double ret=0.;
1848   std::size_t nbOfElems=getNbOfElems();
1849   const double *pt=getConstPointer();
1850   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1851     ret+=(*pt)*(*pt);
1852   return sqrt(ret);
1853 }
1854
1855 /*!
1856  * Returns the maximum norm of the vector defined by \a this array.
1857  * This method works even if the number of components is diferent from one.
1858  * If the number of elements in \a this is 0, -1. is returned.
1859  *  \return double - the value of the maximum norm, i.e.
1860  *          the maximal absolute value among values of \a this array (whatever its number of components).
1861  *  \throw If \a this is not allocated.
1862  */
1863 double DataArrayDouble::normMax() const
1864 {
1865   checkAllocated();
1866   double ret(-1.);
1867   std::size_t nbOfElems(getNbOfElems());
1868   const double *pt(getConstPointer());
1869   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1870     {
1871       double val(std::abs(*pt));
1872       if(val>ret)
1873         ret=val;
1874     }
1875   return ret;
1876 }
1877
1878 /*!
1879  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1880  * This method works even if the number of components is diferent from one.
1881  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1882  *  \return double - the value of the minimum norm, i.e.
1883  *          the minimal absolute value among values of \a this array (whatever its number of components).
1884  *  \throw If \a this is not allocated.
1885  */
1886 double DataArrayDouble::normMin() const
1887 {
1888   checkAllocated();
1889   double ret(std::numeric_limits<double>::max());
1890   std::size_t nbOfElems(getNbOfElems());
1891   const double *pt(getConstPointer());
1892   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1893     {
1894       double val(std::abs(*pt));
1895       if(val<ret)
1896         ret=val;
1897     }
1898   return ret;
1899 }
1900
1901 /*!
1902  * Accumulates values of each component of \a this array.
1903  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1904  *         by the caller, that is filled by this method with sum value for each
1905  *         component.
1906  *  \throw If \a this is not allocated.
1907  */
1908 void DataArrayDouble::accumulate(double *res) const
1909 {
1910   checkAllocated();
1911   const double *ptr=getConstPointer();
1912   int nbTuple=getNumberOfTuples();
1913   int nbComps=getNumberOfComponents();
1914   std::fill(res,res+nbComps,0.);
1915   for(int i=0;i<nbTuple;i++)
1916     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1917 }
1918
1919 /*!
1920  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1921  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1922  *
1923  *
1924  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1925  * \a tupleEnd. If not an exception will be thrown.
1926  *
1927  * \param [in] tupleBg start pointer (included) of input external tuple
1928  * \param [in] tupleEnd end pointer (not included) of input external tuple
1929  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1930  * \return the min distance.
1931  * \sa MEDCouplingUMesh::distanceToPoint
1932  */
1933 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1934 {
1935   checkAllocated();
1936   int nbTuple=getNumberOfTuples();
1937   int nbComps=getNumberOfComponents();
1938   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1939     { 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()); }
1940   if(nbTuple==0)
1941     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1942   double ret0=std::numeric_limits<double>::max();
1943   tupleId=-1;
1944   const double *work=getConstPointer();
1945   for(int i=0;i<nbTuple;i++)
1946     {
1947       double val=0.;
1948       for(int j=0;j<nbComps;j++,work++) 
1949         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1950       if(val>=ret0)
1951         continue;
1952       else
1953         { ret0=val; tupleId=i; }
1954     }
1955   return sqrt(ret0);
1956 }
1957
1958 /*!
1959  * Accumulate values of the given component of \a this array.
1960  *  \param [in] compId - the index of the component of interest.
1961  *  \return double - a sum value of \a compId-th component.
1962  *  \throw If \a this is not allocated.
1963  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1964  *         not respected.
1965  */
1966 double DataArrayDouble::accumulate(int compId) const
1967 {
1968   checkAllocated();
1969   const double *ptr=getConstPointer();
1970   int nbTuple=getNumberOfTuples();
1971   int nbComps=getNumberOfComponents();
1972   if(compId<0 || compId>=nbComps)
1973     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1974   double ret=0.;
1975   for(int i=0;i<nbTuple;i++)
1976     ret+=ptr[i*nbComps+compId];
1977   return ret;
1978 }
1979
1980 /*!
1981  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1982  * The returned array will have same number of components than \a this and number of tuples equal to
1983  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1984  *
1985  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1986  * 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.
1987  *
1988  * \param [in] bgOfIndex - begin (included) of the input index array.
1989  * \param [in] endOfIndex - end (excluded) of the input index array.
1990  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1991  * 
1992  * \throw If bgOfIndex or end is NULL.
1993  * \throw If input index array is not ascendingly sorted.
1994  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1995  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1996  */
1997 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1998 {
1999   if(!bgOfIndex || !endOfIndex)
2000     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
2001   checkAllocated();
2002   int nbCompo=getNumberOfComponents();
2003   int nbOfTuples=getNumberOfTuples();
2004   int sz=(int)std::distance(bgOfIndex,endOfIndex);
2005   if(sz<1)
2006     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
2007   sz--;
2008   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
2009   const int *w=bgOfIndex;
2010   if(*w<0 || *w>=nbOfTuples)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
2012   const double *srcPt=begin()+(*w)*nbCompo;
2013   double *tmp=ret->getPointer();
2014   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
2015     {
2016       std::fill(tmp,tmp+nbCompo,0.);
2017       if(w[1]>=w[0])
2018         {
2019           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
2020             {
2021               if(j>=0 && j<nbOfTuples)
2022                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
2023               else
2024                 {
2025                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2026                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2027                 }
2028             }
2029         }
2030       else
2031         {
2032           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2033           throw INTERP_KERNEL::Exception(oss.str().c_str());
2034         }
2035     }
2036   ret->copyStringInfoFrom(*this);
2037   return ret.retn();
2038 }
2039
2040 /*!
2041  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2042  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2043  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2044  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2045  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2046  *          is to delete this array using decrRef() as it is no more needed. The array
2047  *          does not contain any textual info on components.
2048  *  \throw If \a this->getNumberOfComponents() != 2.
2049  * \sa fromCartToPolar
2050  */
2051 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2052 {
2053   checkAllocated();
2054   int nbOfComp(getNumberOfComponents());
2055   if(nbOfComp!=2)
2056     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2057   int nbOfTuple(getNumberOfTuples());
2058   DataArrayDouble *ret(DataArrayDouble::New());
2059   ret->alloc(nbOfTuple,2);
2060   double *w(ret->getPointer());
2061   const double *wIn(getConstPointer());
2062   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2063     {
2064       w[0]=wIn[0]*cos(wIn[1]);
2065       w[1]=wIn[0]*sin(wIn[1]);
2066     }
2067   return ret;
2068 }
2069
2070 /*!
2071  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2072  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2073  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2074  * the Cylindrical CS.
2075  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2076  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2077  *          on the third component is copied from \a this array. The caller
2078  *          is to delete this array using decrRef() as it is no more needed. 
2079  *  \throw If \a this->getNumberOfComponents() != 3.
2080  * \sa fromCartToCyl
2081  */
2082 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2083 {
2084   checkAllocated();
2085   int nbOfComp(getNumberOfComponents());
2086   if(nbOfComp!=3)
2087     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2088   int nbOfTuple(getNumberOfTuples());
2089   DataArrayDouble *ret(DataArrayDouble::New());
2090   ret->alloc(getNumberOfTuples(),3);
2091   double *w(ret->getPointer());
2092   const double *wIn(getConstPointer());
2093   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2094     {
2095       w[0]=wIn[0]*cos(wIn[1]);
2096       w[1]=wIn[0]*sin(wIn[1]);
2097       w[2]=wIn[2];
2098     }
2099   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2100   return ret;
2101 }
2102
2103 /*!
2104  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2105  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2106  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2107  * point in the Cylindrical CS.
2108  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2109  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2110  *          on the third component is copied from \a this array. The caller
2111  *          is to delete this array using decrRef() as it is no more needed.
2112  *  \throw If \a this->getNumberOfComponents() != 3.
2113  * \sa fromCartToSpher
2114  */
2115 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2116 {
2117   checkAllocated();
2118   int nbOfComp(getNumberOfComponents());
2119   if(nbOfComp!=3)
2120     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2121   int nbOfTuple(getNumberOfTuples());
2122   DataArrayDouble *ret(DataArrayDouble::New());
2123   ret->alloc(getNumberOfTuples(),3);
2124   double *w(ret->getPointer());
2125   const double *wIn(getConstPointer());
2126   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2127     {
2128       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2129       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2130       w[2]=wIn[0]*cos(wIn[1]);
2131     }
2132   return ret;
2133 }
2134
2135 /*!
2136  * 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.
2137  * 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.
2138  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2139  *
2140  * \param [in] atOfThis - The axis type of \a this.
2141  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2142  */
2143 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2144 {
2145   checkAllocated();
2146   int nbOfComp(getNumberOfComponents());
2147   MCAuto<DataArrayDouble> ret;
2148   switch(atOfThis)
2149     {
2150     case AX_CART:
2151       ret=deepCopy();
2152     case AX_CYL:
2153       if(nbOfComp==3)
2154         {
2155           ret=fromCylToCart();
2156           break;
2157         }
2158       if(nbOfComp==2)
2159         {
2160           ret=fromPolarToCart();
2161           break;
2162         }
2163       else
2164         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2165     case AX_SPHER:
2166       if(nbOfComp==3)
2167         {
2168           ret=fromSpherToCart();
2169           break;
2170         }
2171       if(nbOfComp==2)
2172         {
2173           ret=fromPolarToCart();
2174           break;
2175         }
2176       else
2177         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2178     default:
2179       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2180     }
2181   ret->copyStringInfoFrom(*this);
2182   return ret.retn();
2183 }
2184
2185 /*!
2186  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2187  * This method expects that \a this has exactly 2 components.
2188  * \sa fromPolarToCart
2189  */
2190 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2191 {
2192   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2193   checkAllocated();
2194   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2195   if(nbOfComp!=2)
2196     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2197   ret->alloc(nbTuples,2);
2198   double *retPtr(ret->getPointer());
2199   const double *ptr(begin());
2200   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2201     {
2202       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2203       retPtr[1]=atan2(ptr[1],ptr[0]);
2204     }
2205   return ret.retn();
2206 }
2207
2208 /*!
2209  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2210  * This method expects that \a this has exactly 3 components.
2211  * \sa fromCylToCart
2212  */
2213 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2214 {
2215   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2216   checkAllocated();
2217   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2218   if(nbOfComp!=3)
2219     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2220   ret->alloc(nbTuples,3);
2221   double *retPtr(ret->getPointer());
2222   const double *ptr(begin());
2223   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2224     {
2225       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2226       retPtr[1]=atan2(ptr[1],ptr[0]);
2227       retPtr[2]=ptr[2];
2228     }
2229   return ret.retn();
2230 }
2231
2232 /*!
2233  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2234  * \sa fromSpherToCart
2235  */
2236 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2237 {
2238   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2239   checkAllocated();
2240   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2241   if(nbOfComp!=3)
2242     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2243   ret->alloc(nbTuples,3);
2244   double *retPtr(ret->getPointer());
2245   const double *ptr(begin());
2246   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2247     {
2248       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2249       retPtr[1]=acos(ptr[2]/retPtr[0]);
2250       retPtr[2]=atan2(ptr[1],ptr[0]);
2251     }
2252   return ret.retn();
2253 }
2254
2255 /*!
2256  * 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.
2257  * This method expects that \a this has exactly 3 components.
2258  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2259  */
2260 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2261 {
2262   if(!coords)
2263     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2264   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2265   checkAllocated(); coords->checkAllocated();
2266   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2267   if(nbOfComp!=3)
2268     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2269   if(coords->getNumberOfComponents()!=3)
2270     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2271   if(coords->getNumberOfTuples()!=nbTuples)
2272     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2273   ret->alloc(nbTuples,nbOfComp);
2274   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2275   if(magOfVect<1e-12)
2276     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2277   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2278   const double *coo(coords->begin()),*vectField(begin());
2279   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2280   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2281     {
2282       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2283       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];
2284       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2285       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2286       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];
2287       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2288       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2289       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2290     }
2291   ret->copyStringInfoFrom(*this);
2292   return ret.retn();
2293 }
2294
2295 /*!
2296  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2297  * array contating 6 components.
2298  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2299  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2300  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2301  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2302  *  \throw If \a this->getNumberOfComponents() != 6.
2303  */
2304 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2305 {
2306   checkAllocated();
2307   int nbOfComp(getNumberOfComponents());
2308   if(nbOfComp!=6)
2309     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2310   DataArrayDouble *ret=DataArrayDouble::New();
2311   int nbOfTuple=getNumberOfTuples();
2312   ret->alloc(nbOfTuple,1);
2313   const double *src=getConstPointer();
2314   double *dest=ret->getPointer();
2315   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2316     *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];
2317   return ret;
2318 }
2319
2320 /*!
2321  * Computes the determinant of every square matrix defined by the tuple of \a this
2322  * array, which contains either 4, 6 or 9 components. The case of 6 components
2323  * corresponds to that of the upper triangular matrix.
2324  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2325  *          is the determinant of matrix of the corresponding tuple of \a this array.
2326  *          The caller is to delete this result array using decrRef() as it is no more
2327  *          needed. 
2328  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2329  */
2330 DataArrayDouble *DataArrayDouble::determinant() const
2331 {
2332   checkAllocated();
2333   DataArrayDouble *ret=DataArrayDouble::New();
2334   int nbOfTuple=getNumberOfTuples();
2335   ret->alloc(nbOfTuple,1);
2336   const double *src=getConstPointer();
2337   double *dest=ret->getPointer();
2338   switch(getNumberOfComponents())
2339   {
2340     case 6:
2341       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2342         *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];
2343       return ret;
2344     case 4:
2345       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2346         *dest=src[0]*src[3]-src[1]*src[2];
2347       return ret;
2348     case 9:
2349       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2350         *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];
2351       return ret;
2352     default:
2353       ret->decrRef();
2354       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2355   }
2356 }
2357
2358 /*!
2359  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2360  * \a this array, which contains 6 components.
2361  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2362  *          components, whose each tuple contains the eigenvalues of the matrix of
2363  *          corresponding tuple of \a this array. 
2364  *          The caller is to delete this result array using decrRef() as it is no more
2365  *          needed. 
2366  *  \throw If \a this->getNumberOfComponents() != 6.
2367  */
2368 DataArrayDouble *DataArrayDouble::eigenValues() const
2369 {
2370   checkAllocated();
2371   int nbOfComp=getNumberOfComponents();
2372   if(nbOfComp!=6)
2373     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2374   DataArrayDouble *ret=DataArrayDouble::New();
2375   int nbOfTuple=getNumberOfTuples();
2376   ret->alloc(nbOfTuple,3);
2377   const double *src=getConstPointer();
2378   double *dest=ret->getPointer();
2379   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2380     INTERP_KERNEL::computeEigenValues6(src,dest);
2381   return ret;
2382 }
2383
2384 /*!
2385  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2386  * \a this array, which contains 6 components.
2387  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2388  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2389  *          corresponding tuple of \a this array.
2390  *          The caller is to delete this result array using decrRef() as it is no more
2391  *          needed.
2392  *  \throw If \a this->getNumberOfComponents() != 6.
2393  */
2394 DataArrayDouble *DataArrayDouble::eigenVectors() const
2395 {
2396   checkAllocated();
2397   int nbOfComp=getNumberOfComponents();
2398   if(nbOfComp!=6)
2399     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2400   DataArrayDouble *ret=DataArrayDouble::New();
2401   int nbOfTuple=getNumberOfTuples();
2402   ret->alloc(nbOfTuple,9);
2403   const double *src=getConstPointer();
2404   double *dest=ret->getPointer();
2405   for(int i=0;i<nbOfTuple;i++,src+=6)
2406     {
2407       double tmp[3];
2408       INTERP_KERNEL::computeEigenValues6(src,tmp);
2409       for(int j=0;j<3;j++,dest+=3)
2410         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2411     }
2412   return ret;
2413 }
2414
2415 /*!
2416  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2417  * array, which contains either 4, 6 or 9 components. The case of 6 components
2418  * corresponds to that of the upper triangular matrix.
2419  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2420  *          same number of components as \a this one, whose each tuple is the inverse
2421  *          matrix of the matrix of corresponding tuple of \a this array. 
2422  *          The caller is to delete this result array using decrRef() as it is no more
2423  *          needed. 
2424  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2425  */
2426 DataArrayDouble *DataArrayDouble::inverse() const
2427 {
2428   checkAllocated();
2429   int nbOfComp=getNumberOfComponents();
2430   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2431     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2432   DataArrayDouble *ret=DataArrayDouble::New();
2433   int nbOfTuple=getNumberOfTuples();
2434   ret->alloc(nbOfTuple,nbOfComp);
2435   const double *src=getConstPointer();
2436   double *dest=ret->getPointer();
2437   if(nbOfComp==6)
2438     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2439       {
2440         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];
2441         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2442         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2443         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2444         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2445         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2446         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2447       }
2448   else if(nbOfComp==4)
2449     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2450       {
2451         double det=src[0]*src[3]-src[1]*src[2];
2452         dest[0]=src[3]/det;
2453         dest[1]=-src[1]/det;
2454         dest[2]=-src[2]/det;
2455         dest[3]=src[0]/det;
2456       }
2457   else
2458     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2459       {
2460         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];
2461         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2462         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2463         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2464         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2465         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2466         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2467         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2468         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2469         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2470       }
2471   return ret;
2472 }
2473
2474 /*!
2475  * Computes the trace of every matrix defined by the tuple of \a this
2476  * array, which contains either 4, 6 or 9 components. The case of 6 components
2477  * corresponds to that of the upper triangular matrix.
2478  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2479  *          1 component, whose each tuple is the trace of
2480  *          the matrix of corresponding tuple of \a this array. 
2481  *          The caller is to delete this result array using decrRef() as it is no more
2482  *          needed. 
2483  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2484  */
2485 DataArrayDouble *DataArrayDouble::trace() const
2486 {
2487   checkAllocated();
2488   int nbOfComp=getNumberOfComponents();
2489   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2490     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2491   DataArrayDouble *ret=DataArrayDouble::New();
2492   int nbOfTuple=getNumberOfTuples();
2493   ret->alloc(nbOfTuple,1);
2494   const double *src=getConstPointer();
2495   double *dest=ret->getPointer();
2496   if(nbOfComp==6)
2497     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2498       *dest=src[0]+src[1]+src[2];
2499   else if(nbOfComp==4)
2500     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2501       *dest=src[0]+src[3];
2502   else
2503     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2504       *dest=src[0]+src[4]+src[8];
2505   return ret;
2506 }
2507
2508 /*!
2509  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2510  * \a this array, which contains 6 components.
2511  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2512  *          same number of components and tuples as \a this array.
2513  *          The caller is to delete this result array using decrRef() as it is no more
2514  *          needed.
2515  *  \throw If \a this->getNumberOfComponents() != 6.
2516  */
2517 DataArrayDouble *DataArrayDouble::deviator() const
2518 {
2519   checkAllocated();
2520   int nbOfComp=getNumberOfComponents();
2521   if(nbOfComp!=6)
2522     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2523   DataArrayDouble *ret=DataArrayDouble::New();
2524   int nbOfTuple=getNumberOfTuples();
2525   ret->alloc(nbOfTuple,6);
2526   const double *src=getConstPointer();
2527   double *dest=ret->getPointer();
2528   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2529     {
2530       double tr=(src[0]+src[1]+src[2])/3.;
2531       dest[0]=src[0]-tr;
2532       dest[1]=src[1]-tr;
2533       dest[2]=src[2]-tr;
2534       dest[3]=src[3];
2535       dest[4]=src[4];
2536       dest[5]=src[5];
2537     }
2538   return ret;
2539 }
2540
2541 /*!
2542  * Computes the magnitude of every vector defined by the tuple of
2543  * \a this array.
2544  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2545  *          same number of tuples as \a this array and one component.
2546  *          The caller is to delete this result array using decrRef() as it is no more
2547  *          needed.
2548  *  \throw If \a this is not allocated.
2549  */
2550 DataArrayDouble *DataArrayDouble::magnitude() const
2551 {
2552   checkAllocated();
2553   int nbOfComp=getNumberOfComponents();
2554   DataArrayDouble *ret=DataArrayDouble::New();
2555   int nbOfTuple=getNumberOfTuples();
2556   ret->alloc(nbOfTuple,1);
2557   const double *src=getConstPointer();
2558   double *dest=ret->getPointer();
2559   for(int i=0;i<nbOfTuple;i++,dest++)
2560     {
2561       double sum=0.;
2562       for(int j=0;j<nbOfComp;j++,src++)
2563         sum+=(*src)*(*src);
2564       *dest=sqrt(sum);
2565     }
2566   return ret;
2567 }
2568
2569 /*!
2570  * Computes for each tuple the sum of number of components values in the tuple and return it.
2571  * 
2572  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2573  *          same number of tuples as \a this array and one component.
2574  *          The caller is to delete this result array using decrRef() as it is no more
2575  *          needed.
2576  *  \throw If \a this is not allocated.
2577  */
2578 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2579 {
2580   checkAllocated();
2581   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2582   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2583   ret->alloc(nbOfTuple,1);
2584   const double *src(getConstPointer());
2585   double *dest(ret->getPointer());
2586   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2587     *dest=std::accumulate(src,src+nbOfComp,0.);
2588   return ret.retn();
2589 }
2590
2591 /*!
2592  * Computes the maximal value within every tuple of \a this array.
2593  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2594  *          same number of tuples as \a this array and one component.
2595  *          The caller is to delete this result array using decrRef() as it is no more
2596  *          needed.
2597  *  \throw If \a this is not allocated.
2598  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2599  */
2600 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2601 {
2602   checkAllocated();
2603   int nbOfComp=getNumberOfComponents();
2604   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2605   int nbOfTuple=getNumberOfTuples();
2606   ret->alloc(nbOfTuple,1);
2607   const double *src=getConstPointer();
2608   double *dest=ret->getPointer();
2609   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2610     *dest=*std::max_element(src,src+nbOfComp);
2611   return ret.retn();
2612 }
2613
2614 /*!
2615  * Computes the maximal value within every tuple of \a this array and it returns the first component
2616  * id for each tuple that corresponds to the maximal value within the tuple.
2617  * 
2618  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2619  *          same number of tuples and only one component.
2620  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2621  *          same number of tuples as \a this array and one component.
2622  *          The caller is to delete this result array using decrRef() as it is no more
2623  *          needed.
2624  *  \throw If \a this is not allocated.
2625  *  \sa DataArrayDouble::maxPerTuple
2626  */
2627 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2628 {
2629   checkAllocated();
2630   int nbOfComp=getNumberOfComponents();
2631   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2632   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2633   int nbOfTuple=getNumberOfTuples();
2634   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2635   const double *src=getConstPointer();
2636   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2637   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2638     {
2639       const double *loc=std::max_element(src,src+nbOfComp);
2640       *dest=*loc;
2641       *dest1=(int)std::distance(src,loc);
2642     }
2643   compoIdOfMaxPerTuple=ret1.retn();
2644   return ret0.retn();
2645 }
2646
2647 /*!
2648  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2649  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2650  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2651  * \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)
2652  *
2653  * \warning use this method with care because it can leads to big amount of consumed memory !
2654  * 
2655  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2656  *
2657  * \throw If \a this is not allocated.
2658  *
2659  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2660  */
2661 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2662 {
2663   checkAllocated();
2664   int nbOfComp=getNumberOfComponents();
2665   int nbOfTuples=getNumberOfTuples();
2666   const double *inData=getConstPointer();
2667   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2668   ret->alloc(nbOfTuples*nbOfTuples,1);
2669   double *outData=ret->getPointer();
2670   for(int i=0;i<nbOfTuples;i++)
2671     {
2672       outData[i*nbOfTuples+i]=0.;
2673       for(int j=i+1;j<nbOfTuples;j++)
2674         {
2675           double dist=0.;
2676           for(int k=0;k<nbOfComp;k++)
2677             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2678           dist=sqrt(dist);
2679           outData[i*nbOfTuples+j]=dist;
2680           outData[j*nbOfTuples+i]=dist;
2681         }
2682     }
2683   return ret.retn();
2684 }
2685
2686 /*!
2687  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2688  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2689  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2690  * \n Output rectangular matrix is sorted along rows.
2691  * \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)
2692  *
2693  * \warning use this method with care because it can leads to big amount of consumed memory !
2694  * 
2695  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2696  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2697  *
2698  * \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.
2699  *
2700  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2701  */
2702 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2703 {
2704   if(!other)
2705     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2706   checkAllocated();
2707   other->checkAllocated();
2708   int nbOfComp=getNumberOfComponents();
2709   int otherNbOfComp=other->getNumberOfComponents();
2710   if(nbOfComp!=otherNbOfComp)
2711     {
2712       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2713       throw INTERP_KERNEL::Exception(oss.str().c_str());
2714     }
2715   int nbOfTuples=getNumberOfTuples();
2716   int otherNbOfTuples=other->getNumberOfTuples();
2717   const double *inData=getConstPointer();
2718   const double *inDataOther=other->getConstPointer();
2719   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2720   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2721   double *outData=ret->getPointer();
2722   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2723     {
2724       for(int j=0;j<nbOfTuples;j++)
2725         {
2726           double dist=0.;
2727           for(int k=0;k<nbOfComp;k++)
2728             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2729           dist=sqrt(dist);
2730           outData[i*nbOfTuples+j]=dist;
2731         }
2732     }
2733   return ret.retn();
2734 }
2735
2736 /*!
2737  * Sorts value within every tuple of \a this array.
2738  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2739  *              in descending order.
2740  *  \throw If \a this is not allocated.
2741  */
2742 void DataArrayDouble::sortPerTuple(bool asc)
2743 {
2744   checkAllocated();
2745   double *pt=getPointer();
2746   int nbOfTuple=getNumberOfTuples();
2747   int nbOfComp=getNumberOfComponents();
2748   if(asc)
2749     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2750       std::sort(pt,pt+nbOfComp);
2751   else
2752     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2753       std::sort(pt,pt+nbOfComp,std::greater<double>());
2754   declareAsNew();
2755 }
2756
2757 /*!
2758  * Converts every value of \a this array to its absolute value.
2759  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2760  * should be called instead.
2761  *
2762  * \throw If \a this is not allocated.
2763  * \sa DataArrayDouble::computeAbs
2764  */
2765 void DataArrayDouble::abs()
2766 {
2767   checkAllocated();
2768   double *ptr(getPointer());
2769   std::size_t nbOfElems(getNbOfElems());
2770   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2771   declareAsNew();
2772 }
2773
2774 /*!
2775  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2776  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2777  *
2778  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2779  *         same number of tuples and component as \a this array.
2780  *         The caller is to delete this result array using decrRef() as it is no more
2781  *         needed.
2782  * \throw If \a this is not allocated.
2783  * \sa DataArrayDouble::abs
2784  */
2785 DataArrayDouble *DataArrayDouble::computeAbs() const
2786 {
2787   checkAllocated();
2788   DataArrayDouble *newArr(DataArrayDouble::New());
2789   int nbOfTuples(getNumberOfTuples());
2790   int nbOfComp(getNumberOfComponents());
2791   newArr->alloc(nbOfTuples,nbOfComp);
2792   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2793   newArr->copyStringInfoFrom(*this);
2794   return newArr;
2795 }
2796
2797 /*!
2798  * Apply a linear function to a given component of \a this array, so that
2799  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2800  *  \param [in] a - the first coefficient of the function.
2801  *  \param [in] b - the second coefficient of the function.
2802  *  \param [in] compoId - the index of component to modify.
2803  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2804  */
2805 void DataArrayDouble::applyLin(double a, double b, int compoId)
2806 {
2807   checkAllocated();
2808   double *ptr(getPointer()+compoId);
2809   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2810   if(compoId<0 || compoId>=nbOfComp)
2811     {
2812       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2813       throw INTERP_KERNEL::Exception(oss.str().c_str());
2814     }
2815   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2816     *ptr=a*(*ptr)+b;
2817   declareAsNew();
2818 }
2819
2820 /*!
2821  * Apply a linear function to all elements of \a this array, so that
2822  * an element _x_ becomes \f$ a * x + b \f$.
2823  *  \param [in] a - the first coefficient of the function.
2824  *  \param [in] b - the second coefficient of the function.
2825  *  \throw If \a this is not allocated.
2826  */
2827 void DataArrayDouble::applyLin(double a, double b)
2828 {
2829   checkAllocated();
2830   double *ptr=getPointer();
2831   std::size_t nbOfElems=getNbOfElems();
2832   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2833     *ptr=a*(*ptr)+b;
2834   declareAsNew();
2835 }
2836
2837 /*!
2838  * Modify all elements of \a this array, so that
2839  * an element _x_ becomes \f$ numerator / x \f$.
2840  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2841  *           array, all elements processed before detection of the zero element remain
2842  *           modified.
2843  *  \param [in] numerator - the numerator used to modify array elements.
2844  *  \throw If \a this is not allocated.
2845  *  \throw If there is an element equal to 0.0 in \a this array.
2846  */
2847 void DataArrayDouble::applyInv(double numerator)
2848 {
2849   checkAllocated();
2850   double *ptr=getPointer();
2851   std::size_t nbOfElems=getNbOfElems();
2852   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2853     {
2854       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2855         {
2856           *ptr=numerator/(*ptr);
2857         }
2858       else
2859         {
2860           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2861           oss << " !";
2862           throw INTERP_KERNEL::Exception(oss.str().c_str());
2863         }
2864     }
2865   declareAsNew();
2866 }
2867
2868 /*!
2869  * Returns a full copy of \a this array except that sign of all elements is reversed.
2870  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2871  *          same number of tuples and component as \a this array.
2872  *          The caller is to delete this result array using decrRef() as it is no more
2873  *          needed.
2874  *  \throw If \a this is not allocated.
2875  */
2876 DataArrayDouble *DataArrayDouble::negate() const
2877 {
2878   checkAllocated();
2879   DataArrayDouble *newArr=DataArrayDouble::New();
2880   int nbOfTuples=getNumberOfTuples();
2881   int nbOfComp=getNumberOfComponents();
2882   newArr->alloc(nbOfTuples,nbOfComp);
2883   const double *cptr=getConstPointer();
2884   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2885   newArr->copyStringInfoFrom(*this);
2886   return newArr;
2887 }
2888
2889 /*!
2890  * Modify all elements of \a this array, so that
2891  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2892  * all values in \a this have to be >= 0 if val is \b not integer.
2893  *  \param [in] val - the value used to apply pow on all array elements.
2894  *  \throw If \a this is not allocated.
2895  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2896  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2897  *           modified.
2898  */
2899 void DataArrayDouble::applyPow(double val)
2900 {
2901   checkAllocated();
2902   double *ptr=getPointer();
2903   std::size_t nbOfElems=getNbOfElems();
2904   int val2=(int)val;
2905   bool isInt=((double)val2)==val;
2906   if(!isInt)
2907     {
2908       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2909         {
2910           if(*ptr>=0)
2911             *ptr=pow(*ptr,val);
2912           else
2913             {
2914               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2915               throw INTERP_KERNEL::Exception(oss.str().c_str());
2916             }
2917         }
2918     }
2919   else
2920     {
2921       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2922         *ptr=pow(*ptr,val2);
2923     }
2924   declareAsNew();
2925 }
2926
2927 /*!
2928  * Modify all elements of \a this array, so that
2929  * an element _x_ becomes \f$ val ^ x \f$.
2930  *  \param [in] val - the value used to apply pow on all array elements.
2931  *  \throw If \a this is not allocated.
2932  *  \throw If \a val < 0.
2933  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2934  *           array, all elements processed before detection of the zero element remain
2935  *           modified.
2936  */
2937 void DataArrayDouble::applyRPow(double val)
2938 {
2939   checkAllocated();
2940   if(val<0.)
2941     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2942   double *ptr=getPointer();
2943   std::size_t nbOfElems=getNbOfElems();
2944   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2945     *ptr=pow(val,*ptr);
2946   declareAsNew();
2947 }
2948
2949 /*!
2950  * Returns a new DataArrayDouble created from \a this one by applying \a
2951  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2952  * For more info see \ref MEDCouplingArrayApplyFunc
2953  *  \param [in] nbOfComp - number of components in the result array.
2954  *  \param [in] func - the \a FunctionToEvaluate declared as 
2955  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2956  *              where \a pos points to the first component of a tuple of \a this array
2957  *              and \a res points to the first component of a tuple of the result array.
2958  *              Note that length (number of components) of \a pos can differ from
2959  *              that of \a res.
2960  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2961  *          same number of tuples as \a this array.
2962  *          The caller is to delete this result array using decrRef() as it is no more
2963  *          needed.
2964  *  \throw If \a this is not allocated.
2965  *  \throw If \a func returns \a false.
2966  */
2967 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2968 {
2969   checkAllocated();
2970   DataArrayDouble *newArr=DataArrayDouble::New();
2971   int nbOfTuples=getNumberOfTuples();
2972   int oldNbOfComp=getNumberOfComponents();
2973   newArr->alloc(nbOfTuples,nbOfComp);
2974   const double *ptr=getConstPointer();
2975   double *ptrToFill=newArr->getPointer();
2976   for(int i=0;i<nbOfTuples;i++)
2977     {
2978       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2979         {
2980           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2981           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2982           oss << ") : Evaluation of function failed !";
2983           newArr->decrRef();
2984           throw INTERP_KERNEL::Exception(oss.str().c_str());
2985         }
2986     }
2987   return newArr;
2988 }
2989
2990 /*!
2991  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2992  * tuple of \a this array. Textual data is not copied.
2993  * For more info see \ref MEDCouplingArrayApplyFunc1.
2994  *  \param [in] nbOfComp - number of components in the result array.
2995  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2996  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2997  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2998  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2999  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3000  *          same number of tuples as \a this array and \a nbOfComp components.
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 computing \a func fails.
3005  */
3006 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
3007 {
3008   INTERP_KERNEL::ExprParser expr(func);
3009   expr.parse();
3010   std::set<std::string> vars;
3011   expr.getTrueSetOfVars(vars);
3012   std::vector<std::string> varsV(vars.begin(),vars.end());
3013   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
3014 }
3015
3016 /*!
3017  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3018  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
3019  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
3020  *
3021  * For more info see \ref MEDCouplingArrayApplyFunc0.
3022  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3023  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3024  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3025  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3026  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3027  *          same number of tuples and components as \a this array.
3028  *          The caller is to delete this result array using decrRef() as it is no more
3029  *          needed.
3030  *  \sa applyFuncOnThis
3031  *  \throw If \a this is not allocated.
3032  *  \throw If computing \a func fails.
3033  */
3034 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3035 {
3036   int nbOfComp(getNumberOfComponents());
3037   if(nbOfComp<=0)
3038     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3039   checkAllocated();
3040   int nbOfTuples(getNumberOfTuples());
3041   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3042   newArr->alloc(nbOfTuples,nbOfComp);
3043   INTERP_KERNEL::ExprParser expr(func);
3044   expr.parse();
3045   std::set<std::string> vars;
3046   expr.getTrueSetOfVars(vars);
3047   if((int)vars.size()>1)
3048     {
3049       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 : ";
3050       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3051       throw INTERP_KERNEL::Exception(oss.str().c_str());
3052     }
3053   if(vars.empty())
3054     {
3055       expr.prepareFastEvaluator();
3056       newArr->rearrange(1);
3057       newArr->fillWithValue(expr.evaluateDouble());
3058       newArr->rearrange(nbOfComp);
3059       return newArr.retn();
3060     }
3061   std::vector<std::string> vars2(vars.begin(),vars.end());
3062   double buff,*ptrToFill(newArr->getPointer());
3063   const double *ptr(begin());
3064   std::vector<double> stck;
3065   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3066   expr.prepareFastEvaluator();
3067   if(!isSafe)
3068     {
3069       for(int i=0;i<nbOfTuples;i++)
3070         {
3071           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3072             {
3073               buff=*ptr;
3074               expr.evaluateDoubleInternal(stck);
3075               *ptrToFill=stck.back();
3076               stck.pop_back();
3077             }
3078         }
3079     }
3080   else
3081     {
3082       for(int i=0;i<nbOfTuples;i++)
3083         {
3084           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3085             {
3086               buff=*ptr;
3087               try
3088               {
3089                   expr.evaluateDoubleInternalSafe(stck);
3090               }
3091               catch(INTERP_KERNEL::Exception& e)
3092               {
3093                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3094                   oss << buff;
3095                   oss << ") : Evaluation of function failed !" << e.what();
3096                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3097               }
3098               *ptrToFill=stck.back();
3099               stck.pop_back();
3100             }
3101         }
3102     }
3103   return newArr.retn();
3104 }
3105
3106 /*!
3107  * This method is a non const method that modify the array in \a this.
3108  * This method only works on one component array. It means that function \a func must
3109  * contain at most one variable.
3110  * This method is a specialization of applyFunc method with one parameter on one component array.
3111  *
3112  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3113  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3114  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3115  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3116  *
3117  * \sa applyFunc
3118  */
3119 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3120 {
3121   int nbOfComp(getNumberOfComponents());
3122   if(nbOfComp<=0)
3123     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3124   checkAllocated();
3125   int nbOfTuples(getNumberOfTuples());
3126   INTERP_KERNEL::ExprParser expr(func);
3127   expr.parse();
3128   std::set<std::string> vars;
3129   expr.getTrueSetOfVars(vars);
3130   if((int)vars.size()>1)
3131     {
3132       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 : ";
3133       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3134       throw INTERP_KERNEL::Exception(oss.str().c_str());
3135     }
3136   if(vars.empty())
3137     {
3138       expr.prepareFastEvaluator();
3139       std::vector<std::string> compInfo(getInfoOnComponents());
3140       rearrange(1);
3141       fillWithValue(expr.evaluateDouble());
3142       rearrange(nbOfComp);
3143       setInfoOnComponents(compInfo);
3144       return ;
3145     }
3146   std::vector<std::string> vars2(vars.begin(),vars.end());
3147   double buff,*ptrToFill(getPointer());
3148   const double *ptr(begin());
3149   std::vector<double> stck;
3150   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3151   expr.prepareFastEvaluator();
3152   if(!isSafe)
3153     {
3154       for(int i=0;i<nbOfTuples;i++)
3155         {
3156           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3157             {
3158               buff=*ptr;
3159               expr.evaluateDoubleInternal(stck);
3160               *ptrToFill=stck.back();
3161               stck.pop_back();
3162             }
3163         }
3164     }
3165   else
3166     {
3167       for(int i=0;i<nbOfTuples;i++)
3168         {
3169           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3170             {
3171               buff=*ptr;
3172               try
3173               {
3174                   expr.evaluateDoubleInternalSafe(stck);
3175               }
3176               catch(INTERP_KERNEL::Exception& e)
3177               {
3178                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3179                   oss << buff;
3180                   oss << ") : Evaluation of function failed !" << e.what();
3181                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3182               }
3183               *ptrToFill=stck.back();
3184               stck.pop_back();
3185             }
3186         }
3187     }
3188 }
3189
3190 /*!
3191  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3192  * tuple of \a this array. Textual data is not copied.
3193  * For more info see \ref MEDCouplingArrayApplyFunc2.
3194  *  \param [in] nbOfComp - number of components in the result array.
3195  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3196  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3197  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3198  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3199  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3200  *          same number of tuples as \a this array.
3201  *          The caller is to delete this result array using decrRef() as it is no more
3202  *          needed.
3203  *  \throw If \a this is not allocated.
3204  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3205  *  \throw If computing \a func fails.
3206  */
3207 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3208 {
3209   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3210 }
3211
3212 /*!
3213  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3214  * tuple of \a this array. Textual data is not copied.
3215  * For more info see \ref MEDCouplingArrayApplyFunc3.
3216  *  \param [in] nbOfComp - number of components in the result array.
3217  *  \param [in] varsOrder - sequence of vars defining their order.
3218  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3219  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3220  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3221  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3222  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3223  *          same number of tuples as \a this array.
3224  *          The caller is to delete this result array using decrRef() as it is no more
3225  *          needed.
3226  *  \throw If \a this is not allocated.
3227  *  \throw If \a func contains vars not in \a varsOrder.
3228  *  \throw If computing \a func fails.
3229  */
3230 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3231 {
3232   if(nbOfComp<=0)
3233     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3234   std::vector<std::string> varsOrder2(varsOrder);
3235   int oldNbOfComp(getNumberOfComponents());
3236   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3237     varsOrder2.push_back(std::string());
3238   checkAllocated();
3239   int nbOfTuples(getNumberOfTuples());
3240   INTERP_KERNEL::ExprParser expr(func);
3241   expr.parse();
3242   std::set<std::string> vars;
3243   expr.getTrueSetOfVars(vars);
3244   if((int)vars.size()>oldNbOfComp)
3245     {
3246       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3247       oss << vars.size() << " variables : ";
3248       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3249       throw INTERP_KERNEL::Exception(oss.str().c_str());
3250     }
3251   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3252   newArr->alloc(nbOfTuples,nbOfComp);
3253   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3254   double *buffPtr(buff),*ptrToFill;
3255   std::vector<double> stck;
3256   for(int iComp=0;iComp<nbOfComp;iComp++)
3257     {
3258       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3259       expr.prepareFastEvaluator();
3260       const double *ptr(getConstPointer());
3261       ptrToFill=newArr->getPointer()+iComp;
3262       if(!isSafe)
3263         {
3264           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3265             {
3266               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3267               expr.evaluateDoubleInternal(stck);
3268               *ptrToFill=stck.back();
3269               stck.pop_back();
3270             }
3271         }
3272       else
3273         {
3274           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3275             {
3276               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3277               try
3278               {
3279                   expr.evaluateDoubleInternalSafe(stck);
3280                   *ptrToFill=stck.back();
3281                   stck.pop_back();
3282               }
3283               catch(INTERP_KERNEL::Exception& e)
3284               {
3285                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3286                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3287                   oss << ") : Evaluation of function failed !" << e.what();
3288                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3289               }
3290             }
3291         }
3292     }
3293   return newArr.retn();
3294 }
3295
3296 void DataArrayDouble::applyFuncFast32(const std::string& func)
3297 {
3298   checkAllocated();
3299   INTERP_KERNEL::ExprParser expr(func);
3300   expr.parse();
3301   char *funcStr=expr.compileX86();
3302   MYFUNCPTR funcPtr;
3303   *((void **)&funcPtr)=funcStr;//he he...
3304   //
3305   double *ptr=getPointer();
3306   int nbOfComp=getNumberOfComponents();
3307   int nbOfTuples=getNumberOfTuples();
3308   int nbOfElems=nbOfTuples*nbOfComp;
3309   for(int i=0;i<nbOfElems;i++,ptr++)
3310     *ptr=funcPtr(*ptr);
3311   declareAsNew();
3312 }
3313
3314 void DataArrayDouble::applyFuncFast64(const std::string& func)
3315 {
3316   checkAllocated();
3317   INTERP_KERNEL::ExprParser expr(func);
3318   expr.parse();
3319   char *funcStr=expr.compileX86_64();
3320   MYFUNCPTR funcPtr;
3321   *((void **)&funcPtr)=funcStr;//he he...
3322   //
3323   double *ptr=getPointer();
3324   int nbOfComp=getNumberOfComponents();
3325   int nbOfTuples=getNumberOfTuples();
3326   int nbOfElems=nbOfTuples*nbOfComp;
3327   for(int i=0;i<nbOfElems;i++,ptr++)
3328     *ptr=funcPtr(*ptr);
3329   declareAsNew();
3330 }
3331
3332 /*!
3333  * \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.
3334  */
3335 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3336 {
3337   checkAllocated();
3338   if(getNumberOfComponents()!=3)
3339     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3340   int nbTuples(getNumberOfTuples());
3341   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3342   ret->alloc(nbTuples,3);
3343   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3344   return ret;
3345 }
3346
3347 DataArrayDoubleIterator *DataArrayDouble::iterator()
3348 {
3349   return new DataArrayDoubleIterator(this);
3350 }
3351
3352 /*!
3353  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3354  * array whose values are within a given range. Textual data is not copied.
3355  *  \param [in] vmin - a lowest acceptable value (included).
3356  *  \param [in] vmax - a greatest acceptable value (included).
3357  *  \return DataArrayInt * - the new instance of DataArrayInt.
3358  *          The caller is to delete this result array using decrRef() as it is no more
3359  *          needed.
3360  *  \throw If \a this->getNumberOfComponents() != 1.
3361  *
3362  *  \sa DataArrayDouble::findIdsNotInRange
3363  *
3364  *  \if ENABLE_EXAMPLES
3365  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3366  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3367  *  \endif
3368  */
3369 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3370 {
3371   checkAllocated();
3372   if(getNumberOfComponents()!=1)
3373     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3374   const double *cptr(begin());
3375   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3376   int nbOfTuples(getNumberOfTuples());
3377   for(int i=0;i<nbOfTuples;i++,cptr++)
3378     if(*cptr>=vmin && *cptr<=vmax)
3379       ret->pushBackSilent(i);
3380   return ret.retn();
3381 }
3382
3383 /*!
3384  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3385  * array whose values are not within a given range. Textual data is not copied.
3386  *  \param [in] vmin - a lowest not acceptable value (excluded).
3387  *  \param [in] vmax - a greatest not acceptable value (excluded).
3388  *  \return DataArrayInt * - the new instance of DataArrayInt.
3389  *          The caller is to delete this result array using decrRef() as it is no more
3390  *          needed.
3391  *  \throw If \a this->getNumberOfComponents() != 1.
3392  *
3393  *  \sa DataArrayDouble::findIdsInRange
3394  */
3395 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3396 {
3397   checkAllocated();
3398   if(getNumberOfComponents()!=1)
3399     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3400   const double *cptr(begin());
3401   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3402   int nbOfTuples(getNumberOfTuples());
3403   for(int i=0;i<nbOfTuples;i++,cptr++)
3404     if(*cptr<vmin || *cptr>vmax)
3405       ret->pushBackSilent(i);
3406   return ret.retn();
3407 }
3408
3409 /*!
3410  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3411  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3412  * the number of component in the result array is same as that of each of given arrays.
3413  * Info on components is copied from the first of the given arrays. Number of components
3414  * in the given arrays must be  the same.
3415  *  \param [in] a1 - an array to include in the result array.
3416  *  \param [in] a2 - another array to include in the result array.
3417  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3418  *          The caller is to delete this result array using decrRef() as it is no more
3419  *          needed.
3420  *  \throw If both \a a1 and \a a2 are NULL.
3421  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3422  */
3423 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3424 {
3425   std::vector<const DataArrayDouble *> tmp(2);
3426   tmp[0]=a1; tmp[1]=a2;
3427   return Aggregate(tmp);
3428 }
3429
3430 /*!
3431  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3432  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3433  * the number of component in the result array is same as that of each of given arrays.
3434  * Info on components is copied from the first of the given arrays. Number of components
3435  * in the given arrays must be  the same.
3436  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3437  * not the object itself.
3438  *  \param [in] arr - a sequence of arrays to include in the result array.
3439  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3440  *          The caller is to delete this result array using decrRef() as it is no more
3441  *          needed.
3442  *  \throw If all arrays within \a arr are NULL.
3443  *  \throw If getNumberOfComponents() of arrays within \a arr.
3444  */
3445 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3446 {
3447   std::vector<const DataArrayDouble *> a;
3448   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3449     if(*it4)
3450       a.push_back(*it4);
3451   if(a.empty())
3452     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3453   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3454   int nbOfComp=(*it)->getNumberOfComponents();
3455   int nbt=(*it++)->getNumberOfTuples();
3456   for(int i=1;it!=a.end();it++,i++)
3457     {
3458       if((*it)->getNumberOfComponents()!=nbOfComp)
3459         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3460       nbt+=(*it)->getNumberOfTuples();
3461     }
3462   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3463   ret->alloc(nbt,nbOfComp);
3464   double *pt=ret->getPointer();
3465   for(it=a.begin();it!=a.end();it++)
3466     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3467   ret->copyStringInfoFrom(*(a[0]));
3468   return ret.retn();
3469 }
3470
3471 /*!
3472  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3473  * of components in the result array is a sum of the number of components of given arrays
3474  * and (2) the number of tuples in the result array is same as that of each of given
3475  * arrays. In other words the i-th tuple of result array includes all components of
3476  * i-th tuples of all given arrays.
3477  * Number of tuples in the given arrays must be  the same.
3478  *  \param [in] a1 - an array to include in the result array.
3479  *  \param [in] a2 - another array to include in the result array.
3480  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3481  *          The caller is to delete this result array using decrRef() as it is no more
3482  *          needed.
3483  *  \throw If both \a a1 and \a a2 are NULL.
3484  *  \throw If any given array is not allocated.
3485  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3486  */
3487 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3488 {
3489   std::vector<const DataArrayDouble *> arr(2);
3490   arr[0]=a1; arr[1]=a2;
3491   return Meld(arr);
3492 }
3493
3494 /*!
3495  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3496  * of components in the result array is a sum of the number of components of given arrays
3497  * and (2) the number of tuples in the result array is same as that of each of given
3498  * arrays. In other words the i-th tuple of result array includes all components of
3499  * i-th tuples of all given arrays.
3500  * Number of tuples in the given arrays must be  the same.
3501  *  \param [in] arr - a sequence of arrays to include in the result array.
3502  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3503  *          The caller is to delete this result array using decrRef() as it is no more
3504  *          needed.
3505  *  \throw If all arrays within \a arr are NULL.
3506  *  \throw If any given array is not allocated.
3507  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3508  */
3509 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3510 {
3511   std::vector<const DataArrayDouble *> a;
3512   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3513     if(*it4)
3514       a.push_back(*it4);
3515   if(a.empty())
3516     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3517   std::vector<const DataArrayDouble *>::const_iterator it;
3518   for(it=a.begin();it!=a.end();it++)
3519     (*it)->checkAllocated();
3520   it=a.begin();
3521   int nbOfTuples=(*it)->getNumberOfTuples();
3522   std::vector<int> nbc(a.size());
3523   std::vector<const double *> pts(a.size());
3524   nbc[0]=(*it)->getNumberOfComponents();
3525   pts[0]=(*it++)->getConstPointer();
3526   for(int i=1;it!=a.end();it++,i++)
3527     {
3528       if(nbOfTuples!=(*it)->getNumberOfTuples())
3529         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3530       nbc[i]=(*it)->getNumberOfComponents();
3531       pts[i]=(*it)->getConstPointer();
3532     }
3533   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3534   DataArrayDouble *ret=DataArrayDouble::New();
3535   ret->alloc(nbOfTuples,totalNbOfComp);
3536   double *retPtr=ret->getPointer();
3537   for(int i=0;i<nbOfTuples;i++)
3538     for(int j=0;j<(int)a.size();j++)
3539       {
3540         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3541         pts[j]+=nbc[j];
3542       }
3543   int k=0;
3544   for(int i=0;i<(int)a.size();i++)
3545     for(int j=0;j<nbc[i];j++,k++)
3546       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3547   return ret;
3548 }
3549
3550 /*!
3551  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3552  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3553  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3554  * Info on components and name is copied from the first of the given arrays.
3555  * Number of tuples and components in the given arrays must be the same.
3556  *  \param [in] a1 - a given array.
3557  *  \param [in] a2 - another given array.
3558  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3559  *          The caller is to delete this result array using decrRef() as it is no more
3560  *          needed.
3561  *  \throw If either \a a1 or \a a2 is NULL.
3562  *  \throw If any given array is not allocated.
3563  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3564  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3565  */
3566 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3567 {
3568   if(!a1 || !a2)
3569     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3570   a1->checkAllocated();
3571   a2->checkAllocated();
3572   int nbOfComp=a1->getNumberOfComponents();
3573   if(nbOfComp!=a2->getNumberOfComponents())
3574     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3575   int nbOfTuple=a1->getNumberOfTuples();
3576   if(nbOfTuple!=a2->getNumberOfTuples())
3577     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3578   DataArrayDouble *ret=DataArrayDouble::New();
3579   ret->alloc(nbOfTuple,1);
3580   double *retPtr=ret->getPointer();
3581   const double *a1Ptr=a1->getConstPointer();
3582   const double *a2Ptr=a2->getConstPointer();
3583   for(int i=0;i<nbOfTuple;i++)
3584     {
3585       double sum=0.;
3586       for(int j=0;j<nbOfComp;j++)
3587         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3588       retPtr[i]=sum;
3589     }
3590   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3591   ret->setName(a1->getName());
3592   return ret;
3593 }
3594
3595 /*!
3596  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3597  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3598  * product of two vectors defined by the i-th tuples of given arrays.
3599  * Info on components is copied from the first of the given arrays.
3600  * Number of tuples in the given arrays must be the same.
3601  * Number of components in the given arrays must be 3.
3602  *  \param [in] a1 - a given array.
3603  *  \param [in] a2 - another given array.
3604  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3605  *          The caller is to delete this result array using decrRef() as it is no more
3606  *          needed.
3607  *  \throw If either \a a1 or \a a2 is NULL.
3608  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3609  *  \throw If \a a1->getNumberOfComponents() != 3
3610  *  \throw If \a a2->getNumberOfComponents() != 3
3611  */
3612 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3613 {
3614   if(!a1 || !a2)
3615     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3616   int nbOfComp=a1->getNumberOfComponents();
3617   if(nbOfComp!=a2->getNumberOfComponents())
3618     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3619   if(nbOfComp!=3)
3620     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3621   int nbOfTuple=a1->getNumberOfTuples();
3622   if(nbOfTuple!=a2->getNumberOfTuples())
3623     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3624   DataArrayDouble *ret=DataArrayDouble::New();
3625   ret->alloc(nbOfTuple,3);
3626   double *retPtr=ret->getPointer();
3627   const double *a1Ptr=a1->getConstPointer();
3628   const double *a2Ptr=a2->getConstPointer();
3629   for(int i=0;i<nbOfTuple;i++)
3630     {
3631       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3632       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3633       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3634     }
3635   ret->copyStringInfoFrom(*a1);
3636   return ret;
3637 }
3638
3639 /*!
3640  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3641  * Info on components is copied from the first of the given arrays.
3642  * Number of tuples and components in the given arrays must be the same.
3643  *  \param [in] a1 - an array to compare values with another one.
3644  *  \param [in] a2 - another array to compare values with the first one.
3645  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3646  *          The caller is to delete this result array using decrRef() as it is no more
3647  *          needed.
3648  *  \throw If either \a a1 or \a a2 is NULL.
3649  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3650  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3651  */
3652 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3653 {
3654   if(!a1 || !a2)
3655     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3656   int nbOfComp=a1->getNumberOfComponents();
3657   if(nbOfComp!=a2->getNumberOfComponents())
3658     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3659   int nbOfTuple=a1->getNumberOfTuples();
3660   if(nbOfTuple!=a2->getNumberOfTuples())
3661     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3662   DataArrayDouble *ret=DataArrayDouble::New();
3663   ret->alloc(nbOfTuple,nbOfComp);
3664   double *retPtr=ret->getPointer();
3665   const double *a1Ptr=a1->getConstPointer();
3666   const double *a2Ptr=a2->getConstPointer();
3667   int nbElem=nbOfTuple*nbOfComp;
3668   for(int i=0;i<nbElem;i++)
3669     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3670   ret->copyStringInfoFrom(*a1);
3671   return ret;
3672 }
3673
3674 /*!
3675  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3676  * Info on components is copied from the first of the given arrays.
3677  * Number of tuples and components in the given arrays must be the same.
3678  *  \param [in] a1 - an array to compare values with another one.
3679  *  \param [in] a2 - another array to compare values with the first one.
3680  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3681  *          The caller is to delete this result array using decrRef() as it is no more
3682  *          needed.
3683  *  \throw If either \a a1 or \a a2 is NULL.
3684  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3685  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3686  */
3687 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3688 {
3689   if(!a1 || !a2)
3690     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3691   int nbOfComp=a1->getNumberOfComponents();
3692   if(nbOfComp!=a2->getNumberOfComponents())
3693     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3694   int nbOfTuple=a1->getNumberOfTuples();
3695   if(nbOfTuple!=a2->getNumberOfTuples())
3696     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3697   DataArrayDouble *ret=DataArrayDouble::New();
3698   ret->alloc(nbOfTuple,nbOfComp);
3699   double *retPtr=ret->getPointer();
3700   const double *a1Ptr=a1->getConstPointer();
3701   const double *a2Ptr=a2->getConstPointer();
3702   int nbElem=nbOfTuple*nbOfComp;
3703   for(int i=0;i<nbElem;i++)
3704     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3705   ret->copyStringInfoFrom(*a1);
3706   return ret;
3707 }
3708
3709 /*!
3710  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3711  * valid cases.
3712  * 1.  The arrays have same number of tuples and components. Then each value of
3713  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3714  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3715  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3716  *   component. Then
3717  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3718  * 3.  The arrays have same number of components and one array, say _a2_, has one
3719  *   tuple. Then
3720  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3721  *
3722  * Info on components is copied either from the first array (in the first case) or from
3723  * the array with maximal number of elements (getNbOfElems()).
3724  *  \param [in] a1 - an array to sum up.
3725  *  \param [in] a2 - another array to sum up.
3726  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3727  *          The caller is to delete this result array using decrRef() as it is no more
3728  *          needed.
3729  *  \throw If either \a a1 or \a a2 is NULL.
3730  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3731  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3732  *         none of them has number of tuples or components equal to 1.
3733  */
3734 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3735 {
3736   if(!a1 || !a2)
3737     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3738   int nbOfTuple=a1->getNumberOfTuples();
3739   int nbOfTuple2=a2->getNumberOfTuples();
3740   int nbOfComp=a1->getNumberOfComponents();
3741   int nbOfComp2=a2->getNumberOfComponents();
3742   MCAuto<DataArrayDouble> ret=0;
3743   if(nbOfTuple==nbOfTuple2)
3744     {
3745       if(nbOfComp==nbOfComp2)
3746         {
3747           ret=DataArrayDouble::New();
3748           ret->alloc(nbOfTuple,nbOfComp);
3749           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3750           ret->copyStringInfoFrom(*a1);
3751         }
3752       else
3753         {
3754           int nbOfCompMin,nbOfCompMax;
3755           const DataArrayDouble *aMin, *aMax;
3756           if(nbOfComp>nbOfComp2)
3757             {
3758               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3759               aMin=a2; aMax=a1;
3760             }
3761           else
3762             {
3763               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3764               aMin=a1; aMax=a2;
3765             }
3766           if(nbOfCompMin==1)
3767             {
3768               ret=DataArrayDouble::New();
3769               ret->alloc(nbOfTuple,nbOfCompMax);
3770               const double *aMinPtr=aMin->getConstPointer();
3771               const double *aMaxPtr=aMax->getConstPointer();
3772               double *res=ret->getPointer();
3773               for(int i=0;i<nbOfTuple;i++)
3774                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3775               ret->copyStringInfoFrom(*aMax);
3776             }
3777           else
3778             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3779         }
3780     }
3781   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3782     {
3783       if(nbOfComp==nbOfComp2)
3784         {
3785           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3786           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3787           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3788           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3789           ret=DataArrayDouble::New();
3790           ret->alloc(nbOfTupleMax,nbOfComp);
3791           double *res=ret->getPointer();
3792           for(int i=0;i<nbOfTupleMax;i++)
3793             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3794           ret->copyStringInfoFrom(*aMax);
3795         }
3796       else
3797         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3798     }
3799   else
3800     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3801   return ret.retn();
3802 }
3803
3804 /*!
3805  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3806  * valid cases.
3807  * 1.  The arrays have same number of tuples and components. Then each value of
3808  *   \a other array is added to the corresponding value of \a this array, i.e.:
3809  *   _a_ [ i, j ] += _other_ [ i, j ].
3810  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3811  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3812  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3813  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3814  *
3815  *  \param [in] other - an array to add to \a this one.
3816  *  \throw If \a other is NULL.
3817  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3818  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3819  *         \a other has number of both tuples and components not equal to 1.
3820  */
3821 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3822 {
3823   if(!other)
3824     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3825   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3826   checkAllocated();
3827   other->checkAllocated();
3828   int nbOfTuple=getNumberOfTuples();
3829   int nbOfTuple2=other->getNumberOfTuples();
3830   int nbOfComp=getNumberOfComponents();
3831   int nbOfComp2=other->getNumberOfComponents();
3832   if(nbOfTuple==nbOfTuple2)
3833     {
3834       if(nbOfComp==nbOfComp2)
3835         {
3836           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3837         }
3838       else if(nbOfComp2==1)
3839         {
3840           double *ptr=getPointer();
3841           const double *ptrc=other->getConstPointer();
3842           for(int i=0;i<nbOfTuple;i++)
3843             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3844         }
3845       else
3846         throw INTERP_KERNEL::Exception(msg);
3847     }
3848   else if(nbOfTuple2==1)
3849     {
3850       if(nbOfComp2==nbOfComp)
3851         {
3852           double *ptr=getPointer();
3853           const double *ptrc=other->getConstPointer();
3854           for(int i=0;i<nbOfTuple;i++)
3855             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3856         }
3857       else
3858         throw INTERP_KERNEL::Exception(msg);
3859     }
3860   else
3861     throw INTERP_KERNEL::Exception(msg);
3862   declareAsNew();
3863 }
3864
3865 /*!
3866  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3867  * valid cases.
3868  * 1.  The arrays have same number of tuples and components. Then each value of
3869  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3870  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3871  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3872  *   component. Then
3873  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3874  * 3.  The arrays have same number of components and one array, say _a2_, has one
3875  *   tuple. Then
3876  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3877  *
3878  * Info on components is copied either from the first array (in the first case) or from
3879  * the array with maximal number of elements (getNbOfElems()).
3880  *  \param [in] a1 - an array to subtract from.
3881  *  \param [in] a2 - an array to subtract.
3882  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3883  *          The caller is to delete this result array using decrRef() as it is no more
3884  *          needed.
3885  *  \throw If either \a a1 or \a a2 is NULL.
3886  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3887  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3888  *         none of them has number of tuples or components equal to 1.
3889  */
3890 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3891 {
3892   if(!a1 || !a2)
3893     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3894   int nbOfTuple1=a1->getNumberOfTuples();
3895   int nbOfTuple2=a2->getNumberOfTuples();
3896   int nbOfComp1=a1->getNumberOfComponents();
3897   int nbOfComp2=a2->getNumberOfComponents();
3898   if(nbOfTuple2==nbOfTuple1)
3899     {
3900       if(nbOfComp1==nbOfComp2)
3901         {
3902           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3903           ret->alloc(nbOfTuple2,nbOfComp1);
3904           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3905           ret->copyStringInfoFrom(*a1);
3906           return ret.retn();
3907         }
3908       else if(nbOfComp2==1)
3909         {
3910           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3911           ret->alloc(nbOfTuple1,nbOfComp1);
3912           const double *a2Ptr=a2->getConstPointer();
3913           const double *a1Ptr=a1->getConstPointer();
3914           double *res=ret->getPointer();
3915           for(int i=0;i<nbOfTuple1;i++)
3916             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3917           ret->copyStringInfoFrom(*a1);
3918           return ret.retn();
3919         }
3920       else
3921         {
3922           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3923           return 0;
3924         }
3925     }
3926   else if(nbOfTuple2==1)
3927     {
3928       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3929       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3930       ret->alloc(nbOfTuple1,nbOfComp1);
3931       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3932       double *pt=ret->getPointer();
3933       for(int i=0;i<nbOfTuple1;i++)
3934         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3935       ret->copyStringInfoFrom(*a1);
3936       return ret.retn();
3937     }
3938   else
3939     {
3940       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3941       return 0;
3942     }
3943 }
3944
3945 /*!
3946  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3947  * valid cases.
3948  * 1.  The arrays have same number of tuples and components. Then each value of
3949  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3950  *   _a_ [ i, j ] -= _other_ [ i, j ].
3951  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3952  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3953  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3954  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3955  *
3956  *  \param [in] other - an array to subtract from \a this one.
3957  *  \throw If \a other is NULL.
3958  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3959  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3960  *         \a other has number of both tuples and components not equal to 1.
3961  */
3962 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3963 {
3964   if(!other)
3965     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3966   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3967   checkAllocated();
3968   other->checkAllocated();
3969   int nbOfTuple=getNumberOfTuples();
3970   int nbOfTuple2=other->getNumberOfTuples();
3971   int nbOfComp=getNumberOfComponents();
3972   int nbOfComp2=other->getNumberOfComponents();
3973   if(nbOfTuple==nbOfTuple2)
3974     {
3975       if(nbOfComp==nbOfComp2)
3976         {
3977           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3978         }
3979       else if(nbOfComp2==1)
3980         {
3981           double *ptr=getPointer();
3982           const double *ptrc=other->getConstPointer();
3983           for(int i=0;i<nbOfTuple;i++)
3984             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3985         }
3986       else
3987         throw INTERP_KERNEL::Exception(msg);
3988     }
3989   else if(nbOfTuple2==1)
3990     {
3991       if(nbOfComp2==nbOfComp)
3992         {
3993           double *ptr=getPointer();
3994           const double *ptrc=other->getConstPointer();
3995           for(int i=0;i<nbOfTuple;i++)
3996             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3997         }
3998       else
3999         throw INTERP_KERNEL::Exception(msg);
4000     }
4001   else
4002     throw INTERP_KERNEL::Exception(msg);
4003   declareAsNew();
4004 }
4005
4006 /*!
4007  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4008  * valid cases.
4009  * 1.  The arrays have same number of tuples and components. Then each value of
4010  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4011  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4012  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4013  *   component. Then
4014  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4015  * 3.  The arrays have same number of components and one array, say _a2_, has one
4016  *   tuple. Then
4017  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4018  *
4019  * Info on components is copied either from the first array (in the first case) or from
4020  * the array with maximal number of elements (getNbOfElems()).
4021  *  \param [in] a1 - a factor array.
4022  *  \param [in] a2 - another factor array.
4023  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4024  *          The caller is to delete this result array using decrRef() as it is no more
4025  *          needed.
4026  *  \throw If either \a a1 or \a a2 is NULL.
4027  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4028  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4029  *         none of them has number of tuples or components equal to 1.
4030  */
4031 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4032 {
4033   if(!a1 || !a2)
4034     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4035   int nbOfTuple=a1->getNumberOfTuples();
4036   int nbOfTuple2=a2->getNumberOfTuples();
4037   int nbOfComp=a1->getNumberOfComponents();
4038   int nbOfComp2=a2->getNumberOfComponents();
4039   MCAuto<DataArrayDouble> ret=0;
4040   if(nbOfTuple==nbOfTuple2)
4041     {
4042       if(nbOfComp==nbOfComp2)
4043         {
4044           ret=DataArrayDouble::New();
4045           ret->alloc(nbOfTuple,nbOfComp);
4046           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4047           ret->copyStringInfoFrom(*a1);
4048         }
4049       else
4050         {
4051           int nbOfCompMin,nbOfCompMax;
4052           const DataArrayDouble *aMin, *aMax;
4053           if(nbOfComp>nbOfComp2)
4054             {
4055               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4056               aMin=a2; aMax=a1;
4057             }
4058           else
4059             {
4060               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4061               aMin=a1; aMax=a2;
4062             }
4063           if(nbOfCompMin==1)
4064             {
4065               ret=DataArrayDouble::New();
4066               ret->alloc(nbOfTuple,nbOfCompMax);
4067               const double *aMinPtr=aMin->getConstPointer();
4068               const double *aMaxPtr=aMax->getConstPointer();
4069               double *res=ret->getPointer();
4070               for(int i=0;i<nbOfTuple;i++)
4071                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4072               ret->copyStringInfoFrom(*aMax);
4073             }
4074           else
4075             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4076         }
4077     }
4078   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4079     {
4080       if(nbOfComp==nbOfComp2)
4081         {
4082           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4083           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4084           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4085           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4086           ret=DataArrayDouble::New();
4087           ret->alloc(nbOfTupleMax,nbOfComp);
4088           double *res=ret->getPointer();
4089           for(int i=0;i<nbOfTupleMax;i++)
4090             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4091           ret->copyStringInfoFrom(*aMax);
4092         }
4093       else
4094         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4095     }
4096   else
4097     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4098   return ret.retn();
4099 }
4100
4101 /*!
4102  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4103  * valid cases.
4104  * 1.  The arrays have same number of tuples and components. Then each value of
4105  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4106  *   _this_ [ i, j ] *= _other_ [ i, j ].
4107  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4108  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4109  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4110  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4111  *
4112  *  \param [in] other - an array to multiply to \a this one.
4113  *  \throw If \a other is NULL.
4114  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4115  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4116  *         \a other has number of both tuples and components not equal to 1.
4117  */
4118 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4119 {
4120   if(!other)
4121     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4122   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4123   checkAllocated();
4124   other->checkAllocated();
4125   int nbOfTuple=getNumberOfTuples();
4126   int nbOfTuple2=other->getNumberOfTuples();
4127   int nbOfComp=getNumberOfComponents();
4128   int nbOfComp2=other->getNumberOfComponents();
4129   if(nbOfTuple==nbOfTuple2)
4130     {
4131       if(nbOfComp==nbOfComp2)
4132         {
4133           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4134         }
4135       else if(nbOfComp2==1)
4136         {
4137           double *ptr=getPointer();
4138           const double *ptrc=other->getConstPointer();
4139           for(int i=0;i<nbOfTuple;i++)
4140             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4141         }
4142       else
4143         throw INTERP_KERNEL::Exception(msg);
4144     }
4145   else if(nbOfTuple2==1)
4146     {
4147       if(nbOfComp2==nbOfComp)
4148         {
4149           double *ptr=getPointer();
4150           const double *ptrc=other->getConstPointer();
4151           for(int i=0;i<nbOfTuple;i++)
4152             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4153         }
4154       else
4155         throw INTERP_KERNEL::Exception(msg);
4156     }
4157   else
4158     throw INTERP_KERNEL::Exception(msg);
4159   declareAsNew();
4160 }
4161
4162 /*!
4163  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4164  * valid cases.
4165  * 1.  The arrays have same number of tuples and components. Then each value of
4166  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4167  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4168  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4169  *   component. Then
4170  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4171  * 3.  The arrays have same number of components and one array, say _a2_, has one
4172  *   tuple. Then
4173  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4174  *
4175  * Info on components is copied either from the first array (in the first case) or from
4176  * the array with maximal number of elements (getNbOfElems()).
4177  *  \warning No check of division by zero is performed!
4178  *  \param [in] a1 - a numerator array.
4179  *  \param [in] a2 - a denominator array.
4180  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4181  *          The caller is to delete this result array using decrRef() as it is no more
4182  *          needed.
4183  *  \throw If either \a a1 or \a a2 is NULL.
4184  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4185  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4186  *         none of them has number of tuples or components equal to 1.
4187  */
4188 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4189 {
4190   if(!a1 || !a2)
4191     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4192   int nbOfTuple1=a1->getNumberOfTuples();
4193   int nbOfTuple2=a2->getNumberOfTuples();
4194   int nbOfComp1=a1->getNumberOfComponents();
4195   int nbOfComp2=a2->getNumberOfComponents();
4196   if(nbOfTuple2==nbOfTuple1)
4197     {
4198       if(nbOfComp1==nbOfComp2)
4199         {
4200           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4201           ret->alloc(nbOfTuple2,nbOfComp1);
4202           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4203           ret->copyStringInfoFrom(*a1);
4204           return ret.retn();
4205         }
4206       else if(nbOfComp2==1)
4207         {
4208           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4209           ret->alloc(nbOfTuple1,nbOfComp1);
4210           const double *a2Ptr=a2->getConstPointer();
4211           const double *a1Ptr=a1->getConstPointer();
4212           double *res=ret->getPointer();
4213           for(int i=0;i<nbOfTuple1;i++)
4214             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4215           ret->copyStringInfoFrom(*a1);
4216           return ret.retn();
4217         }
4218       else
4219         {
4220           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4221           return 0;
4222         }
4223     }
4224   else if(nbOfTuple2==1)
4225     {
4226       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4227       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4228       ret->alloc(nbOfTuple1,nbOfComp1);
4229       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4230       double *pt=ret->getPointer();
4231       for(int i=0;i<nbOfTuple1;i++)
4232         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4233       ret->copyStringInfoFrom(*a1);
4234       return ret.retn();
4235     }
4236   else
4237     {
4238       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4239       return 0;
4240     }
4241 }
4242
4243 /*!
4244  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4245  * valid cases.
4246  * 1.  The arrays have same number of tuples and components. Then each value of
4247  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4248  *   _a_ [ i, j ] /= _other_ [ i, j ].
4249  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4250  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4251  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4252  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4253  *
4254  *  \warning No check of division by zero is performed!
4255  *  \param [in] other - an array to divide \a this one by.
4256  *  \throw If \a other is NULL.
4257  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4258  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4259  *         \a other has number of both tuples and components not equal to 1.
4260  */
4261 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4262 {
4263   if(!other)
4264     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4265   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4266   checkAllocated();
4267   other->checkAllocated();
4268   int nbOfTuple=getNumberOfTuples();
4269   int nbOfTuple2=other->getNumberOfTuples();
4270   int nbOfComp=getNumberOfComponents();
4271   int nbOfComp2=other->getNumberOfComponents();
4272   if(nbOfTuple==nbOfTuple2)
4273     {
4274       if(nbOfComp==nbOfComp2)
4275         {
4276           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4277         }
4278       else if(nbOfComp2==1)
4279         {
4280           double *ptr=getPointer();
4281           const double *ptrc=other->getConstPointer();
4282           for(int i=0;i<nbOfTuple;i++)
4283             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4284         }
4285       else
4286         throw INTERP_KERNEL::Exception(msg);
4287     }
4288   else if(nbOfTuple2==1)
4289     {
4290       if(nbOfComp2==nbOfComp)
4291         {
4292           double *ptr=getPointer();
4293           const double *ptrc=other->getConstPointer();
4294           for(int i=0;i<nbOfTuple;i++)
4295             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4296         }
4297       else
4298         throw INTERP_KERNEL::Exception(msg);
4299     }
4300   else
4301     throw INTERP_KERNEL::Exception(msg);
4302   declareAsNew();
4303 }
4304
4305 /*!
4306  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4307  * valid cases.
4308  *
4309  *  \param [in] a1 - an array to pow up.
4310  *  \param [in] a2 - another array to sum up.
4311  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4312  *          The caller is to delete this result array using decrRef() as it is no more
4313  *          needed.
4314  *  \throw If either \a a1 or \a a2 is NULL.
4315  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4316  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4317  *  \throw If there is a negative value in \a a1.
4318  */
4319 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4320 {
4321   if(!a1 || !a2)
4322     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4323   int nbOfTuple=a1->getNumberOfTuples();
4324   int nbOfTuple2=a2->getNumberOfTuples();
4325   int nbOfComp=a1->getNumberOfComponents();
4326   int nbOfComp2=a2->getNumberOfComponents();
4327   if(nbOfTuple!=nbOfTuple2)
4328     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4329   if(nbOfComp!=1 || nbOfComp2!=1)
4330     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4331   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4332   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4333   double *ptr=ret->getPointer();
4334   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4335     {
4336       if(*ptr1>=0)
4337         {
4338           *ptr=pow(*ptr1,*ptr2);
4339         }
4340       else
4341         {
4342           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4343           throw INTERP_KERNEL::Exception(oss.str().c_str());
4344         }
4345     }
4346   return ret.retn();
4347 }
4348
4349 /*!
4350  * Apply pow on values of another DataArrayDouble to values of \a this one.
4351  *
4352  *  \param [in] other - an array to pow to \a this one.
4353  *  \throw If \a other is NULL.
4354  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4355  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4356  *  \throw If there is a negative value in \a this.
4357  */
4358 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4359 {
4360   if(!other)
4361     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4362   int nbOfTuple=getNumberOfTuples();
4363   int nbOfTuple2=other->getNumberOfTuples();
4364   int nbOfComp=getNumberOfComponents();
4365   int nbOfComp2=other->getNumberOfComponents();
4366   if(nbOfTuple!=nbOfTuple2)
4367     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4368   if(nbOfComp!=1 || nbOfComp2!=1)
4369     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4370   double *ptr=getPointer();
4371   const double *ptrc=other->begin();
4372   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4373     {
4374       if(*ptr>=0)
4375         *ptr=pow(*ptr,*ptrc);
4376       else
4377         {
4378           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4379           throw INTERP_KERNEL::Exception(oss.str().c_str());
4380         }
4381     }
4382   declareAsNew();
4383 }
4384
4385 /*!
4386  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4387  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4388  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4389  *
4390  * \throw if \a this is not allocated.
4391  * \throw if \a this has not exactly one component.
4392  */
4393 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4394 {
4395   checkAllocated();
4396   if(getNumberOfComponents()!=1)
4397     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4398   int nbt(getNumberOfTuples());
4399   std::vector<bool> ret(nbt);
4400   const double *pt(begin());
4401   for(int i=0;i<nbt;i++)
4402     {
4403       if(fabs(pt[i])<eps)
4404         ret[i]=false;
4405       else if(fabs(pt[i]-1.)<eps)
4406         ret[i]=true;
4407       else
4408         {
4409           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4410           throw INTERP_KERNEL::Exception(oss.str().c_str());
4411         }
4412     }
4413   return ret;
4414 }
4415
4416 /*!
4417  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4418  * Server side.
4419  */
4420 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4421 {
4422   tinyInfo.resize(2);
4423   if(isAllocated())
4424     {
4425       tinyInfo[0]=getNumberOfTuples();
4426       tinyInfo[1]=getNumberOfComponents();
4427     }
4428   else
4429     {
4430       tinyInfo[0]=-1;
4431       tinyInfo[1]=-1;
4432     }
4433 }
4434
4435 /*!
4436  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4437  * Server side.
4438  */
4439 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4440 {
4441   if(isAllocated())
4442     {
4443       int nbOfCompo=getNumberOfComponents();
4444       tinyInfo.resize(nbOfCompo+1);
4445       tinyInfo[0]=getName();
4446       for(int i=0;i<nbOfCompo;i++)
4447         tinyInfo[i+1]=getInfoOnComponent(i);
4448     }
4449   else
4450     {
4451       tinyInfo.resize(1);
4452       tinyInfo[0]=getName();
4453     }
4454 }
4455
4456 /*!
4457  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4458  * This method returns if a feeding is needed.
4459  */
4460 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4461 {
4462   int nbOfTuple=tinyInfoI[0];
4463   int nbOfComp=tinyInfoI[1];
4464   if(nbOfTuple!=-1 || nbOfComp!=-1)
4465     {
4466       alloc(nbOfTuple,nbOfComp);
4467       return true;
4468     }
4469   return false;
4470 }
4471
4472 /*!
4473  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4474  */
4475 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4476 {
4477   setName(tinyInfoS[0]);
4478   if(isAllocated())
4479     {
4480       int nbOfCompo=getNumberOfComponents();
4481       for(int i=0;i<nbOfCompo;i++)
4482         setInfoOnComponent(i,tinyInfoS[i+1]);
4483     }
4484 }
4485
4486 /*!
4487  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4488  * around an axe ( \a center, \a vect) and with angle \a angle.
4489  */
4490 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4491 {
4492   if(!center || !vect)
4493     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4494   double sina(sin(angle));
4495   double cosa(cos(angle));
4496   double vectorNorm[3];
4497   double matrix[9];
4498   double matrixTmp[9];
4499   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4500   if(norm<std::numeric_limits<double>::min())
4501     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4502   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4503   //rotation matrix computation
4504   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;
4505   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4506   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4507   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4508   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4509   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4510   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4511   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4512   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4513   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4514   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4515   //rotation matrix computed.
4516   double tmp[3];
4517   for(int i=0; i<nbNodes; i++)
4518     {
4519       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4520       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4521       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4522       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4523     }
4524 }
4525
4526 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4527 {
4528   double matrix[9],matrix2[9],matrix3[9];
4529   double vect[3],crossVect[3];
4530   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4531   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4532   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4533   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4534   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4535   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4536   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4537   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4538   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4539   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4540   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4541   for(int i=0;i<3;i++)
4542     for(int j=0;j<3;j++)
4543       {
4544         double val(0.);
4545         for(int k=0;k<3;k++)
4546           val+=matrix[3*i+k]*matrix2[3*k+j];
4547         matrix3[3*i+j]=val;
4548       }
4549   //rotation matrix computed.
4550   double tmp[3];
4551   for(int i=0; i<nbNodes; i++)
4552     {
4553       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4554       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4555       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4556       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4557     }
4558 }
4559
4560 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4561 {
4562   double vect[3],crossVect[3];
4563   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4564   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4565   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4566   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4567   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4568   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4569   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4570   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4571 }
4572
4573 /*!
4574  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4575  * around the center point \a center and with angle \a angle.
4576  */
4577 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4578 {
4579   double cosa=cos(angle);
4580   double sina=sin(angle);
4581   double matrix[4];
4582   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4583   double tmp[2];
4584   for(int i=0; i<nbNodes; i++)
4585     {
4586       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4587       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4588       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4589     }
4590 }
4591
4592 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4593 {
4594   if(_da)
4595     {
4596       _da->incrRef();
4597       if(_da->isAllocated())
4598         {
4599           _nb_comp=da->getNumberOfComponents();
4600           _nb_tuple=da->getNumberOfTuples();
4601           _pt=da->getPointer();
4602         }
4603     }
4604 }
4605
4606 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4607 {
4608   if(_da)
4609     _da->decrRef();
4610 }
4611
4612 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4613 {
4614   if(_tuple_id<_nb_tuple)
4615     {
4616       _tuple_id++;
4617       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4618       _pt+=_nb_comp;
4619       return ret;
4620     }
4621   else
4622     return 0;
4623 }
4624
4625 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4626 {
4627 }
4628
4629
4630 std::string DataArrayDoubleTuple::repr() const
4631 {
4632   std::ostringstream oss; oss.precision(17); oss << "(";
4633   for(int i=0;i<_nb_of_compo-1;i++)
4634     oss << _pt[i] << ", ";
4635   oss << _pt[_nb_of_compo-1] << ")";
4636   return oss.str();
4637 }
4638
4639 double DataArrayDoubleTuple::doubleValue() const
4640 {
4641   if(_nb_of_compo==1)
4642     return *_pt;
4643   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4644 }
4645
4646 /*!
4647  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4648  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4649  * 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
4650  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4651  */
4652 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4653 {
4654   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4655     {
4656       DataArrayDouble *ret=DataArrayDouble::New();
4657       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4658       return ret;
4659     }
4660   else
4661     {
4662       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4663       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4664       throw INTERP_KERNEL::Exception(oss.str().c_str());
4665     }
4666 }
4667
4668 /*!
4669  * Returns a new instance of DataArrayInt. The caller is to delete this array
4670  * using decrRef() as it is no more needed. 
4671  */
4672 DataArrayInt *DataArrayInt::New()
4673 {
4674   return new DataArrayInt;
4675 }
4676
4677 /*!
4678  * Returns the only one value in \a this, if and only if number of elements
4679  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4680  *  \return double - the sole value stored in \a this array.
4681  *  \throw If at least one of conditions stated above is not fulfilled.
4682  */
4683 int DataArrayInt::intValue() const
4684 {
4685   if(isAllocated())
4686     {
4687       if(getNbOfElems()==1)
4688         {
4689           return *getConstPointer();
4690         }
4691       else
4692         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4693     }
4694   else
4695     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4696 }
4697
4698 /*!
4699  * Returns an integer value characterizing \a this array, which is useful for a quick
4700  * comparison of many instances of DataArrayInt.
4701  *  \return int - the hash value.
4702  *  \throw If \a this is not allocated.
4703  */
4704 int DataArrayInt::getHashCode() const
4705 {
4706   checkAllocated();
4707   std::size_t nbOfElems=getNbOfElems();
4708   int ret=nbOfElems*65536;
4709   int delta=3;
4710   if(nbOfElems>48)
4711     delta=nbOfElems/8;
4712   int ret0=0;
4713   const int *pt=begin();
4714   for(std::size_t i=0;i<nbOfElems;i+=delta)
4715     ret0+=pt[i] & 0x1FFF;
4716   return ret+ret0;
4717 }
4718
4719 /*!
4720  * Returns a full copy of \a this. For more info on copying data arrays see
4721  * \ref MEDCouplingArrayBasicsCopyDeep.
4722  *  \return DataArrayInt * - a new instance of DataArrayInt.
4723  */
4724 DataArrayInt *DataArrayInt::deepCopy() const
4725 {
4726   return new DataArrayInt(*this);
4727 }
4728
4729 /*!
4730  * Returns either a \a deep or \a shallow copy of this array. For more info see
4731  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4732  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4733  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4734  *          == \a true) or \a this instance (if \a dCpy == \a false).
4735  */
4736 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4737 {
4738   if(dCpy)
4739     return deepCopy();
4740   else
4741     {
4742       incrRef();
4743       return const_cast<DataArrayInt *>(this);
4744     }
4745 }
4746
4747 /*!
4748  * Assign zero to all values in \a this array. To know more on filling arrays see
4749  * \ref MEDCouplingArrayFill.
4750  * \throw If \a this is not allocated.
4751  */
4752 void DataArrayInt::fillWithZero()
4753 {
4754   fillWithValue(0);
4755 }
4756
4757 /*!
4758  * Set all values in \a this array so that the i-th element equals to \a init + i
4759  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4760  *  \param [in] init - value to assign to the first element of array.
4761  *  \throw If \a this->getNumberOfComponents() != 1
4762  *  \throw If \a this is not allocated.
4763  */
4764 void DataArrayInt::iota(int init)
4765 {
4766   checkAllocated();
4767   if(getNumberOfComponents()!=1)
4768     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4769   int *ptr=getPointer();
4770   int ntuples=getNumberOfTuples();
4771   for(int i=0;i<ntuples;i++)
4772     ptr[i]=init+i;
4773   declareAsNew();
4774 }
4775
4776 /*!
4777  * Returns a textual and human readable representation of \a this instance of
4778  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4779  * \return std::string - text describing \a this DataArrayInt.
4780  * 
4781  * \sa reprNotTooLong, reprZip
4782  */
4783 std::string DataArrayInt::repr() const
4784 {
4785   std::ostringstream ret;
4786   reprStream(ret);
4787   return ret.str();
4788 }
4789
4790 std::string DataArrayInt::reprZip() const
4791 {
4792   std::ostringstream ret;
4793   reprZipStream(ret);
4794   return ret.str();
4795 }
4796
4797 /*!
4798  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4799  * printed out to avoid to consume too much space in interpretor.
4800  * \sa repr
4801  */
4802 std::string DataArrayInt::reprNotTooLong() const
4803 {
4804   std::ostringstream ret;
4805   reprNotTooLongStream(ret);
4806   return ret.str();
4807 }
4808
4809 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4810 {
4811   static const char SPACE[4]={' ',' ',' ',' '};
4812   checkAllocated();
4813   std::string idt(indent,' ');
4814   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4815   if(byteArr)
4816     {
4817       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4818       if(std::string(type)=="Int32")
4819         {
4820           const char *data(reinterpret_cast<const char *>(begin()));
4821           std::size_t sz(getNbOfElems()*sizeof(int));
4822           byteArr->insertAtTheEnd(data,data+sz);
4823           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4824         }
4825       else if(std::string(type)=="Int8")
4826         {
4827           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4828           std::copy(begin(),end(),(char *)tmp);
4829           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4830           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4831         }
4832       else if(std::string(type)=="UInt8")
4833         {
4834           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4835           std::copy(begin(),end(),(unsigned char *)tmp);
4836           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4837           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4838         }
4839       else
4840         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4841     }
4842   else
4843     {
4844       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4845       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4846     }
4847   ofs << std::endl << idt << "</DataArray>\n";
4848 }
4849
4850 void DataArrayInt::reprStream(std::ostream& stream) const
4851 {
4852   stream << "Name of int array : \"" << _name << "\"\n";
4853   reprWithoutNameStream(stream);
4854 }
4855
4856 void DataArrayInt::reprZipStream(std::ostream& stream) const
4857 {
4858   stream << "Name of int array : \"" << _name << "\"\n";
4859   reprZipWithoutNameStream(stream);
4860 }
4861
4862 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4863 {
4864   stream << "Name of int array : \"" << _name << "\"\n";
4865   reprNotTooLongWithoutNameStream(stream);
4866 }
4867
4868 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4869 {
4870   DataArray::reprWithoutNameStream(stream);
4871   _mem.repr(getNumberOfComponents(),stream);
4872 }
4873
4874 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4875 {
4876   DataArray::reprWithoutNameStream(stream);
4877   _mem.reprZip(getNumberOfComponents(),stream);
4878 }
4879
4880 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4881 {
4882   DataArray::reprWithoutNameStream(stream);
4883   stream.precision(17);
4884   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4885 }
4886
4887 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4888 {
4889   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4890   const int *data=getConstPointer();
4891   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4892   if(nbTuples*nbComp>=1)
4893     {
4894       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4895       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4896       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4897       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4898     }
4899   else
4900     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4901   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4902 }
4903
4904 /*!
4905  * Method that gives a quick overvien of \a this for python.
4906  */
4907 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4908 {
4909   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4910   stream << "DataArrayInt C++ instance at " << this << ". ";
4911   if(isAllocated())
4912     {
4913       int nbOfCompo=(int)_info_on_compo.size();
4914       if(nbOfCompo>=1)
4915         {
4916           int nbOfTuples=getNumberOfTuples();
4917           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4918           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4919         }
4920       else
4921         stream << "Number of components : 0.";
4922     }
4923   else
4924     stream << "*** No data allocated ****";
4925 }
4926
4927 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4928 {
4929   const int *data=begin();
4930   int nbOfTuples=getNumberOfTuples();
4931   int nbOfCompo=(int)_info_on_compo.size();
4932   std::ostringstream oss2; oss2 << "[";
4933   std::string oss2Str(oss2.str());
4934   bool isFinished=true;
4935   for(int i=0;i<nbOfTuples && isFinished;i++)
4936     {
4937       if(nbOfCompo>1)
4938         {
4939           oss2 << "(";
4940           for(int j=0;j<nbOfCompo;j++,data++)
4941             {
4942               oss2 << *data;
4943               if(j!=nbOfCompo-1) oss2 << ", ";
4944             }
4945           oss2 << ")";
4946         }
4947       else
4948         oss2 << *data++;
4949       if(i!=nbOfTuples-1) oss2 << ", ";
4950       std::string oss3Str(oss2.str());
4951       if(oss3Str.length()<maxNbOfByteInRepr)
4952         oss2Str=oss3Str;
4953       else
4954         isFinished=false;
4955     }
4956   stream << oss2Str;
4957   if(!isFinished)
4958     stream << "... ";
4959   stream << "]";
4960 }
4961
4962 /*!
4963  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4964  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4965  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4966  *         to \a this array.
4967  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4968  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4969  *  \throw If \a this->getNumberOfComponents() != 1
4970  *  \throw If any value of \a this can't be used as a valid index for 
4971  *         [\a indArrBg, \a indArrEnd).
4972  *
4973  *  \sa changeValue
4974  */
4975 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4976 {
4977   checkAllocated();
4978   if(getNumberOfComponents()!=1)
4979     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4980   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4981   for(int i=0;i<nbOfTuples;i++,pt++)
4982     {
4983       if(*pt>=0 && *pt<nbElemsIn)
4984         *pt=indArrBg[*pt];
4985       else
4986         {
4987           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4988           throw INTERP_KERNEL::Exception(oss.str().c_str());
4989         }
4990     }
4991   declareAsNew();
4992 }
4993
4994 /*!
4995  * Computes distribution of values of \a this one-dimensional array between given value
4996  * ranges (casts). This method is typically useful for entity number spliting by types,
4997  * for example. 
4998  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4999  *           check of this is be done. If not, the result is not warranted. 
5000  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5001  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5002  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5003  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5004  *         should be more than every value in \a this array.
5005  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5006  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5007  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5008  *         (same number of tuples and components), the caller is to delete 
5009  *         using decrRef() as it is no more needed.
5010  *         This array contains indices of ranges for every value of \a this array. I.e.
5011  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5012  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5013  *         this in which cast it holds.
5014  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5015  *         array, the caller is to delete using decrRef() as it is no more needed.
5016  *         This array contains ranks of values of \a this array within ranges
5017  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5018  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5019  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5020  *         for each tuple its rank inside its cast. The rank is computed as difference
5021  *         between the value and the lowest value of range.
5022  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5023  *         ranges (casts) to which at least one value of \a this array belongs.
5024  *         Or, in other words, this param contains the casts that \a this contains.
5025  *         The caller is to delete this array using decrRef() as it is no more needed.
5026  *
5027  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5028  *            the output of this method will be : 
5029  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5030  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5031  * - \a castsPresent  : [0,1]
5032  *
5033  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5034  * range #1 and its rank within this range is 2; etc.
5035  *
5036  *  \throw If \a this->getNumberOfComponents() != 1.
5037  *  \throw If \a arrEnd - arrBg < 2.
5038  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5039  */
5040 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5041                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5042 {
5043   checkAllocated();
5044   if(getNumberOfComponents()!=1)
5045     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5046   int nbOfTuples=getNumberOfTuples();
5047   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5048   if(nbOfCast<2)
5049     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5050   nbOfCast--;
5051   const int *work=getConstPointer();
5052   typedef std::reverse_iterator<const int *> rintstart;
5053   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5054   rintstart end2(arrBg);
5055   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5056   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5057   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5058   ret1->alloc(nbOfTuples,1);
5059   ret2->alloc(nbOfTuples,1);
5060   int *ret1Ptr=ret1->getPointer();
5061   int *ret2Ptr=ret2->getPointer();
5062   std::set<std::size_t> castsDetected;
5063   for(int i=0;i<nbOfTuples;i++)
5064     {
5065       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5066       std::size_t pos=std::distance(bg,res);
5067       std::size_t pos2=nbOfCast-pos;
5068       if(pos2<nbOfCast)
5069         {
5070           ret1Ptr[i]=(int)pos2;
5071           ret2Ptr[i]=work[i]-arrBg[pos2];
5072           castsDetected.insert(pos2);
5073         }
5074       else
5075         {
5076           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5077           throw INTERP_KERNEL::Exception(oss.str().c_str());
5078         }
5079     }
5080   ret3->alloc((int)castsDetected.size(),1);
5081   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5082   castArr=ret1.retn();
5083   rankInsideCast=ret2.retn();
5084   castsPresent=ret3.retn();
5085 }
5086
5087 /*!
5088  * 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 ).
5089  * 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 ).
5090  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5091  *
5092  * \param [out] strt - the start of the range (included) if true is returned.
5093  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5094  * \param [out] stteepp - the step of the range if true is returned.
5095  * \return the verdict of the check.
5096  *
5097  * \sa DataArray::GetNumberOfItemGivenBES
5098  */
5099 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5100 {
5101   checkAllocated();
5102   if(getNumberOfComponents()!=1)
5103     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5104   int nbTuples(getNumberOfTuples());
5105   if(nbTuples==0)
5106     { strt=0; sttoopp=0; stteepp=1; return true; }
5107   const int *pt(begin());
5108   strt=*pt; 
5109   if(nbTuples==1)
5110     { sttoopp=strt+1; stteepp=1; return true; }
5111   strt=*pt; sttoopp=pt[nbTuples-1];
5112   if(strt==sttoopp)
5113     return false;
5114   if(sttoopp>strt)
5115     {
5116       sttoopp++;
5117       int a(sttoopp-1-strt),tmp(strt);
5118       if(a%(nbTuples-1)!=0)
5119         return false;
5120       stteepp=a/(nbTuples-1);
5121       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5122         if(pt[i]!=tmp)
5123           return false;
5124       return true;
5125     }
5126   else
5127     {
5128       sttoopp--;
5129       int a(strt-sttoopp-1),tmp(strt);
5130       if(a%(nbTuples-1)!=0)
5131         return false;
5132       stteepp=-(a/(nbTuples-1));
5133       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5134         if(pt[i]!=tmp)
5135           return false;
5136       return true;
5137     }
5138 }
5139
5140 /*!
5141  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5142  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5143  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5144  * new value in place \a indArr[ \a v ] is i.
5145  *  \param [in] indArrBg - the array holding indices within the result array to assign
5146  *         indices of values of \a this array pointing to values of \a indArrBg.
5147  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5148  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5149  *  \return DataArrayInt * - the new instance of DataArrayInt.
5150  *          The caller is to delete this result array using decrRef() as it is no more
5151  *          needed.
5152  *  \throw If \a this->getNumberOfComponents() != 1.
5153  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5154  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5155  */
5156 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5157 {
5158   checkAllocated();
5159   if(getNumberOfComponents()!=1)
5160     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5161   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5162   int nbOfTuples=getNumberOfTuples();
5163   const int *pt=getConstPointer();
5164   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5165   ret->alloc(nbOfTuples,1);
5166   ret->fillWithValue(-1);
5167   int *tmp=ret->getPointer();
5168   for(int i=0;i<nbOfTuples;i++,pt++)
5169     {
5170       if(*pt>=0 && *pt<nbElemsIn)
5171         {
5172           int pos=indArrBg[*pt];
5173           if(pos>=0 && pos<nbOfTuples)
5174             tmp[pos]=i;
5175           else
5176             {
5177               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5178               throw INTERP_KERNEL::Exception(oss.str().c_str());
5179             }
5180         }
5181       else
5182         {
5183           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5184           throw INTERP_KERNEL::Exception(oss.str().c_str());
5185         }
5186     }
5187   return ret.retn();
5188 }
5189
5190 /*!
5191  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5192  * from values of \a this array, which is supposed to contain a renumbering map in 
5193  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5194  * To know how to use the renumbering maps see \ref numbering.
5195  *  \param [in] newNbOfElem - the number of tuples in the result array.
5196  *  \return DataArrayInt * - the new instance of DataArrayInt.
5197  *          The caller is to delete this result array using decrRef() as it is no more
5198  *          needed.
5199  * 
5200  *  \if ENABLE_EXAMPLES
5201  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5202  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5203  *  \endif
5204  */
5205 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5206 {
5207   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5208   ret->alloc(newNbOfElem,1);
5209   int nbOfOldNodes=getNumberOfTuples();
5210   const int *old2New=getConstPointer();
5211   int *pt=ret->getPointer();
5212   for(int i=0;i!=nbOfOldNodes;i++)
5213     {
5214       int newp(old2New[i]);
5215       if(newp!=-1)
5216         {
5217           if(newp>=0 && newp<newNbOfElem)
5218             pt[newp]=i;
5219           else
5220             {
5221               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5222               throw INTERP_KERNEL::Exception(oss.str().c_str());
5223             }
5224         }
5225     }
5226   return ret.retn();
5227 }
5228
5229 /*!
5230  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5231  * 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]
5232  */
5233 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5234 {
5235   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5236   ret->alloc(newNbOfElem,1);
5237   int nbOfOldNodes=getNumberOfTuples();
5238   const int *old2New=getConstPointer();
5239   int *pt=ret->getPointer();
5240   for(int i=nbOfOldNodes-1;i>=0;i--)
5241     {
5242       int newp(old2New[i]);
5243       if(newp!=-1)
5244         {
5245           if(newp>=0 && newp<newNbOfElem)
5246             pt[newp]=i;
5247           else
5248             {
5249               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5250               throw INTERP_KERNEL::Exception(oss.str().c_str());
5251             }
5252         }
5253     }
5254   return ret.retn();
5255 }
5256
5257 /*!
5258  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5259  * from values of \a this array, which is supposed to contain a renumbering map in 
5260  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5261  * To know how to use the renumbering maps see \ref numbering.
5262  *  \param [in] newNbOfElem - the number of tuples in the result array.
5263  *  \return DataArrayInt * - the new instance of DataArrayInt.
5264  *          The caller is to delete this result array using decrRef() as it is no more
5265  *          needed.
5266  * 
5267  *  \if ENABLE_EXAMPLES
5268  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5269  *
5270  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5271  *  \endif
5272  */
5273 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5274 {
5275   checkAllocated();
5276   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5277   ret->alloc(oldNbOfElem,1);
5278   const int *new2Old=getConstPointer();
5279   int *pt=ret->getPointer();
5280   std::fill(pt,pt+oldNbOfElem,-1);
5281   int nbOfNewElems=getNumberOfTuples();
5282   for(int i=0;i<nbOfNewElems;i++)
5283     {
5284       int v(new2Old[i]);
5285       if(v>=0 && v<oldNbOfElem)
5286         pt[v]=i;
5287       else
5288         {
5289           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5290           throw INTERP_KERNEL::Exception(oss.str().c_str());
5291         }
5292     }
5293   return ret.retn();
5294 }
5295
5296 /*!
5297  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5298  * mismatch is given.
5299  * 
5300  * \param [in] other the instance to be compared with \a this
5301  * \param [out] reason In case of inequality returns the reason.
5302  * \sa DataArrayInt::isEqual
5303  */
5304 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5305 {
5306   if(!areInfoEqualsIfNotWhy(other,reason))
5307     return false;
5308   return _mem.isEqual(other._mem,0,reason);
5309 }
5310
5311 /*!
5312  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5313  * \ref MEDCouplingArrayBasicsCompare.
5314  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5315  *  \return bool - \a true if the two arrays are equal, \a false else.
5316  */
5317 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5318 {
5319   std::string tmp;
5320   return isEqualIfNotWhy(other,tmp);
5321 }
5322
5323 /*!
5324  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5325  * \ref MEDCouplingArrayBasicsCompare.
5326  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5327  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5328  */
5329 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5330 {
5331   std::string tmp;
5332   return _mem.isEqual(other._mem,0,tmp);
5333 }
5334
5335 /*!
5336  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5337  * performed on sorted value sequences.
5338  * For more info see\ref MEDCouplingArrayBasicsCompare.
5339  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5340  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5341  */
5342 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5343 {
5344   MCAuto<DataArrayInt> a=deepCopy();
5345   MCAuto<DataArrayInt> b=other.deepCopy();
5346   a->sort();
5347   b->sort();
5348   return a->isEqualWithoutConsideringStr(*b);
5349 }
5350
5351 /*!
5352  * This method compares content of input vector \a v and \a this.
5353  * 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.
5354  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5355  *
5356  * \param [in] v - the vector of 'flags' to be compared with \a this.
5357  *
5358  * \throw If \a this is not sorted ascendingly.
5359  * \throw If \a this has not exactly one component.
5360  * \throw If \a this is not allocated.
5361  */
5362 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5363 {
5364   checkAllocated();
5365   if(getNumberOfComponents()!=1)
5366     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5367   const int *w(begin()),*end2(end());
5368   int refVal=-std::numeric_limits<int>::max();
5369   int i=0;
5370   std::vector<bool>::const_iterator it(v.begin());
5371   for(;it!=v.end();it++,i++)
5372     {
5373       if(*it)
5374         {
5375           if(w!=end2)
5376             {
5377               if(*w++==i)
5378                 {
5379                   if(i>refVal)
5380                     refVal=i;
5381                   else
5382                     {
5383                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5384                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5385                     }
5386                 }
5387               else
5388                 return false;
5389             }
5390           else
5391             return false;
5392         }
5393     }
5394   return w==end2;
5395 }
5396
5397 /*!
5398  * 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
5399  * put True to the corresponding entry in \a vec.
5400  * \a vec is expected to be with the same size than the number of tuples of \a this.
5401  *
5402  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5403  */
5404 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5405 {
5406   checkAllocated();
5407   if(getNumberOfComponents()!=1)
5408     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5409   int nbOfTuples(getNumberOfTuples());
5410   if(nbOfTuples!=(int)vec.size())
5411     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5412   const int *pt(begin());
5413   for(int i=0;i<nbOfTuples;i++)
5414     if(pt[i]==val)
5415       vec[i]=true;
5416 }
5417
5418 /*!
5419  * 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
5420  * put True to the corresponding entry in \a vec.
5421  * \a vec is expected to be with the same size than the number of tuples of \a this.
5422  * 
5423  *  \sa DataArrayInt::switchOnTupleEqualTo.
5424  */
5425 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5426 {
5427   checkAllocated();
5428   if(getNumberOfComponents()!=1)
5429     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5430   int nbOfTuples(getNumberOfTuples());
5431   if(nbOfTuples!=(int)vec.size())
5432     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5433   const int *pt(begin());
5434   for(int i=0;i<nbOfTuples;i++)
5435     if(pt[i]!=val)
5436       vec[i]=true;
5437 }
5438
5439 /*!
5440  * Computes for each tuple the sum of number of components values in the tuple and return it.
5441  * 
5442  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5443  *          same number of tuples as \a this array and one component.
5444  *          The caller is to delete this result array using decrRef() as it is no more
5445  *          needed.
5446  *  \throw If \a this is not allocated.
5447  */
5448 DataArrayInt *DataArrayInt::sumPerTuple() const
5449 {
5450   checkAllocated();
5451   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5452   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5453   ret->alloc(nbOfTuple,1);
5454   const int *src(getConstPointer());
5455   int *dest(ret->getPointer());
5456   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5457     *dest=std::accumulate(src,src+nbOfComp,0);
5458   return ret.retn();
5459 }
5460
5461 /*!
5462  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5463  * If not an exception is thrown.
5464  *  \param [in] increasing - if \a true, the array values should be increasing.
5465  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5466  *         increasing arg.
5467  *  \throw If \a this->getNumberOfComponents() != 1.
5468  *  \throw If \a this is not allocated.
5469  */
5470 void DataArrayInt::checkMonotonic(bool increasing) const
5471 {
5472   if(!isMonotonic(increasing))
5473     {
5474       if (increasing)
5475         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5476       else
5477         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5478     }
5479 }
5480
5481 /*!
5482  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5483  *  \param [in] increasing - if \a true, array values should be increasing.
5484  *  \return bool - \a true if values change in accordance with \a increasing arg.
5485  *  \throw If \a this->getNumberOfComponents() != 1.
5486  *  \throw If \a this is not allocated.
5487  */
5488 bool DataArrayInt::isMonotonic(bool increasing) const
5489 {
5490   checkAllocated();
5491   if(getNumberOfComponents()!=1)
5492     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5493   int nbOfElements=getNumberOfTuples();
5494   const int *ptr=getConstPointer();
5495   if(nbOfElements==0)
5496     return true;
5497   int ref=ptr[0];
5498   if(increasing)
5499     {
5500       for(int i=1;i<nbOfElements;i++)
5501         {
5502           if(ptr[i]>=ref)
5503             ref=ptr[i];
5504           else
5505             return false;
5506         }
5507     }
5508   else
5509     {
5510       for(int i=1;i<nbOfElements;i++)
5511         {
5512           if(ptr[i]<=ref)
5513             ref=ptr[i];
5514           else
5515             return false;
5516         }
5517     }
5518   return true;
5519 }
5520
5521 /*!
5522  * This method check that array consistently INCREASING or DECREASING in value.
5523  */
5524 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5525 {
5526   checkAllocated();
5527   if(getNumberOfComponents()!=1)
5528     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5529   int nbOfElements=getNumberOfTuples();
5530   const int *ptr=getConstPointer();
5531   if(nbOfElements==0)
5532     return true;
5533   int ref=ptr[0];
5534   if(increasing)
5535     {
5536       for(int i=1;i<nbOfElements;i++)
5537         {
5538           if(ptr[i]>ref)
5539             ref=ptr[i];
5540           else
5541             return false;
5542         }
5543     }
5544   else
5545     {
5546       for(int i=1;i<nbOfElements;i++)
5547         {
5548           if(ptr[i]<ref)
5549             ref=ptr[i];
5550           else
5551             return false;
5552         }
5553     }
5554   return true;
5555 }
5556
5557 /*!
5558  * This method check that array consistently INCREASING or DECREASING in value.
5559  */
5560 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5561 {
5562   if(!isStrictlyMonotonic(increasing))
5563     {
5564       if (increasing)
5565         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5566       else
5567         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5568     }
5569 }
5570
5571 /*!
5572  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5573  * one-dimensional arrays that must be of the same length. The result array describes
5574  * correspondence between \a this and \a other arrays, so that 
5575  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5576  * not possible because some element in \a other is not in \a this, an exception is thrown.
5577  *  \param [in] other - an array to compute permutation to.
5578  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5579  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5580  * no more needed.
5581  *  \throw If \a this->getNumberOfComponents() != 1.
5582  *  \throw If \a other->getNumberOfComponents() != 1.
5583  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5584  *  \throw If \a other includes a value which is not in \a this array.
5585  * 
5586  *  \if ENABLE_EXAMPLES
5587  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5588  *
5589  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5590  *  \endif
5591  */
5592 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5593 {
5594   checkAllocated();
5595   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5596     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5597   int nbTuple=getNumberOfTuples();
5598   other.checkAllocated();
5599   if(nbTuple!=other.getNumberOfTuples())
5600     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5601   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5602   ret->alloc(nbTuple,1);
5603   ret->fillWithValue(-1);
5604   const int *pt=getConstPointer();
5605   std::map<int,int> mm;
5606   for(int i=0;i<nbTuple;i++)
5607     mm[pt[i]]=i;
5608   pt=other.getConstPointer();
5609   int *retToFill=ret->getPointer();
5610   for(int i=0;i<nbTuple;i++)
5611     {
5612       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5613       if(it==mm.end())
5614         {
5615           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5616           throw INTERP_KERNEL::Exception(oss.str().c_str());
5617         }
5618       retToFill[i]=(*it).second;
5619     }
5620   return ret.retn();
5621 }
5622
5623 void DataArrayInt::aggregate(const DataArrayInt *other)
5624 {
5625   if(!other)
5626     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5627   if(getNumberOfComponents()!=other->getNumberOfComponents())
5628     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5629   _mem.insertAtTheEnd(other->begin(),other->end());
5630 }
5631
5632 /*!
5633  * Returns a new DataArrayInt holding the same values as \a this array but differently
5634  * arranged in memory. If \a this array holds 2 components of 3 values:
5635  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5636  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5637  *  \warning Do not confuse this method with transpose()!
5638  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5639  *          is to delete using decrRef() as it is no more needed.
5640  *  \throw If \a this is not allocated.
5641  */
5642 DataArrayInt *DataArrayInt::fromNoInterlace() const
5643 {
5644   checkAllocated();
5645   if(_mem.isNull())
5646     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5647   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5648   DataArrayInt *ret=DataArrayInt::New();
5649   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5650   return ret;
5651 }
5652
5653 /*!
5654  * Returns a new DataArrayInt holding the same values as \a this array but differently
5655  * arranged in memory. If \a this array holds 2 components of 3 values:
5656  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5657  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5658  *  \warning Do not confuse this method with transpose()!
5659  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5660  *          is to delete using decrRef() as it is no more needed.
5661  *  \throw If \a this is not allocated.
5662  */
5663 DataArrayInt *DataArrayInt::toNoInterlace() const
5664 {
5665   checkAllocated();
5666   if(_mem.isNull())
5667     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5668   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5669   DataArrayInt *ret=DataArrayInt::New();
5670   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5671   return ret;
5672 }
5673
5674 /*!
5675  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5676  * This map, if applied to \a this array, would make it sorted. For example, if
5677  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5678  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5679  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5680  * This method is useful for renumbering (in MED file for example). For more info
5681  * on renumbering see \ref numbering.
5682  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5683  *          array using decrRef() as it is no more needed.
5684  *  \throw If \a this is not allocated.
5685  *  \throw If \a this->getNumberOfComponents() != 1.
5686  *  \throw If there are equal values in \a this array.
5687  */
5688 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5689 {
5690   checkAllocated();
5691   if(getNumberOfComponents()!=1)
5692     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5693   int nbTuples=getNumberOfTuples();
5694   const int *pt=getConstPointer();
5695   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5696   DataArrayInt *ret=DataArrayInt::New();
5697   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5698   return ret;
5699 }
5700
5701 /*!
5702  * 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
5703  * input array \a ids2.
5704  * \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.
5705  * 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
5706  * inversely.
5707  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5708  *
5709  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5710  *          array using decrRef() as it is no more needed.
5711  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5712  * 
5713  */
5714 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5715 {
5716   if(!ids1 || !ids2)
5717     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5718   if(!ids1->isAllocated() || !ids2->isAllocated())
5719     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5720   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5721     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5722   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5723     {
5724       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 !";
5725       throw INTERP_KERNEL::Exception(oss.str().c_str());
5726     }
5727   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5728   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5729   p1->sort(true); p2->sort(true);
5730   if(!p1->isEqualWithoutConsideringStr(*p2))
5731     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5732   p1=ids1->checkAndPreparePermutation();
5733   p2=ids2->checkAndPreparePermutation();
5734   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5735   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5736   return p2.retn();
5737 }
5738
5739 /*!
5740  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5741  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5742  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5743  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5744  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5745  * The first of out arrays returns indices of elements of \a this array, grouped by their
5746  * place in the set \a B. The second out array is the index of the first one; it shows how
5747  * many elements of \a A are mapped into each element of \a B. <br>
5748  * For more info on
5749  * mapping and its usage in renumbering see \ref numbering. <br>
5750  * \b Example:
5751  * - \a this: [0,3,2,3,2,2,1,2]
5752  * - \a targetNb: 4
5753  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5754  * - \a arrI: [0,1,2,6,8]
5755  *
5756  * This result means: <br>
5757  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5758  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5759  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5760  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5761  * \a arrI[ 2+1 ]]); <br> etc.
5762  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5763  *         than the maximal value of \a A.
5764  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5765  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5766  *         this array using decrRef() as it is no more needed.
5767  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5768  *         elements of \a this. The caller is to delete this array using decrRef() as it
5769  *         is no more needed.
5770  *  \throw If \a this is not allocated.
5771  *  \throw If \a this->getNumberOfComponents() != 1.
5772  *  \throw If any value in \a this is more or equal to \a targetNb.
5773  */
5774 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5775 {
5776   checkAllocated();
5777   if(getNumberOfComponents()!=1)
5778     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5779   int nbOfTuples=getNumberOfTuples();
5780   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5781   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5782   retI->alloc(targetNb+1,1);
5783   const int *input=getConstPointer();
5784   std::vector< std::vector<int> > tmp(targetNb);
5785   for(int i=0;i<nbOfTuples;i++)
5786     {
5787       int tmp2=input[i];
5788       if(tmp2>=0 && tmp2<targetNb)
5789         tmp[tmp2].push_back(i);
5790       else
5791         {
5792           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5793           throw INTERP_KERNEL::Exception(oss.str().c_str());
5794         }
5795     }
5796   int *retIPtr=retI->getPointer();
5797   *retIPtr=0;
5798   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5799     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5800   if(nbOfTuples!=retI->getIJ(targetNb,0))
5801     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5802   ret->alloc(nbOfTuples,1);
5803   int *retPtr=ret->getPointer();
5804   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5805     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5806   arr=ret.retn();
5807   arrI=retI.retn();
5808 }
5809
5810
5811 /*!
5812  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5813  * from a zip representation of a surjective format (returned e.g. by
5814  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5815  * for example). The result array minimizes the permutation. <br>
5816  * For more info on renumbering see \ref numbering. <br>
5817  * \b Example: <br>
5818  * - \a nbOfOldTuples: 10 
5819  * - \a arr          : [0,3, 5,7,9]
5820  * - \a arrIBg       : [0,2,5]
5821  * - \a newNbOfTuples: 7
5822  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5823  *
5824  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5825  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5826  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5827  *         (indices of) equal values. Its every element (except the last one) points to
5828  *         the first element of a group of equal values.
5829  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5830  *          arrIBg is \a arrIEnd[ -1 ].
5831  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5832  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5833  *          array using decrRef() as it is no more needed.
5834  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5835  */
5836 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5837 {
5838   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5839   ret->alloc(nbOfOldTuples,1);
5840   int *pt=ret->getPointer();
5841   std::fill(pt,pt+nbOfOldTuples,-1);
5842   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5843   const int *cIPtr=arrIBg;
5844   for(int i=0;i<nbOfGrps;i++)
5845     pt[arr[cIPtr[i]]]=-(i+2);
5846   int newNb=0;
5847   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5848     {
5849       if(pt[iNode]<0)
5850         {
5851           if(pt[iNode]==-1)
5852             pt[iNode]=newNb++;
5853           else
5854             {
5855               int grpId=-(pt[iNode]+2);
5856               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5857                 {
5858                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5859                     pt[arr[j]]=newNb;
5860                   else
5861                     {
5862                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5863                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5864                     }
5865                 }
5866               newNb++;
5867             }
5868         }
5869     }
5870   newNbOfTuples=newNb;
5871   return ret.retn();
5872 }
5873
5874 /*!
5875  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5876  * which if applied to \a this array would make it sorted ascendingly.
5877  * For more info on renumbering see \ref numbering. <br>
5878  * \b Example: <br>
5879  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5880  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5881  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5882  *
5883  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5884  *          array using decrRef() as it is no more needed.
5885  *  \throw If \a this is not allocated.
5886  *  \throw If \a this->getNumberOfComponents() != 1.
5887  */
5888 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5889 {
5890   checkAllocated();
5891   if(getNumberOfComponents()!=1)
5892     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5893   int nbOfTuples=getNumberOfTuples();
5894   const int *pt=getConstPointer();
5895   std::map<int,int> m;
5896   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5897   ret->alloc(nbOfTuples,1);
5898   int *opt=ret->getPointer();
5899   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5900     {
5901       int val=*pt;
5902       std::map<int,int>::iterator it=m.find(val);
5903       if(it!=m.end())
5904         {
5905           *opt=(*it).second;
5906           (*it).second++;
5907         }
5908       else
5909         {
5910           *opt=0;
5911           m.insert(std::pair<int,int>(val,1));
5912         }
5913     }
5914   int sum=0;
5915   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5916     {
5917       int vt=(*it).second;
5918       (*it).second=sum;
5919       sum+=vt;
5920     }
5921   pt=getConstPointer();
5922   opt=ret->getPointer();
5923   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5924     *opt+=m[*pt];
5925   //
5926   return ret.retn();
5927 }
5928
5929 /*!
5930  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5931  * iota(). This method is particularly useful for DataArrayInt instances that represent
5932  * a renumbering array, to check if there is a real need in renumbering.
5933  * This method checks than \a this can be considered as an identity mapping
5934  * of a set having \a sizeExpected elements into itself.
5935  *
5936  *  \param [in] sizeExpected - The number of elements expected.
5937  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5938  *  \throw If \a this is not allocated.
5939  *  \throw If \a this->getNumberOfComponents() != 1.
5940  */
5941 bool DataArrayInt::isIota(int sizeExpected) const
5942 {
5943   checkAllocated();
5944   if(getNumberOfComponents()!=1)
5945     return false;
5946   int nbOfTuples(getNumberOfTuples());
5947   if(nbOfTuples!=sizeExpected)
5948     return false;
5949   const int *pt=getConstPointer();
5950   for(int i=0;i<nbOfTuples;i++,pt++)
5951     if(*pt!=i)
5952       return false;
5953   return true;
5954 }
5955
5956 /*!
5957  * Checks if all values in \a this array are equal to \a val.
5958  *  \param [in] val - value to check equality of array values to.
5959  *  \return bool - \a true if all values are \a val.
5960  *  \throw If \a this is not allocated.
5961  *  \throw If \a this->getNumberOfComponents() != 1
5962  */
5963 bool DataArrayInt::isUniform(int val) const
5964 {
5965   checkAllocated();
5966   if(getNumberOfComponents()!=1)
5967     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5968   int nbOfTuples=getNumberOfTuples();
5969   const int *w=getConstPointer();
5970   const int *end2=w+nbOfTuples;
5971   for(;w!=end2;w++)
5972     if(*w!=val)
5973       return false;
5974   return true;
5975 }
5976
5977 /*!
5978  * Checks if all values in \a this array are unique.
5979  *  \return bool - \a true if condition above is true
5980  *  \throw If \a this is not allocated.
5981  *  \throw If \a this->getNumberOfComponents() != 1
5982  */
5983 bool DataArrayInt::hasUniqueValues() const
5984 {
5985   checkAllocated();
5986   if(getNumberOfComponents()!=1)
5987     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5988   int nbOfTuples(getNumberOfTuples());
5989   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
5990   if (s.size() != nbOfTuples)
5991     return false;
5992   return true;
5993 }
5994
5995 /*!
5996  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
5997  * array to the new one.
5998  *  \return DataArrayDouble * - the new instance of DataArrayInt.
5999  */
6000 DataArrayDouble *DataArrayInt::convertToDblArr() const
6001 {
6002   checkAllocated();
6003   DataArrayDouble *ret=DataArrayDouble::New();
6004   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6005   std::size_t nbOfVals=getNbOfElems();
6006   const int *src=getConstPointer();
6007   double *dest=ret->getPointer();
6008   std::copy(src,src+nbOfVals,dest);
6009   ret->copyStringInfoFrom(*this);
6010   return ret;
6011 }
6012
6013 /*!
6014  * Appends components of another array to components of \a this one, tuple by tuple.
6015  * So that the number of tuples of \a this array remains the same and the number of 
6016  * components increases.
6017  *  \param [in] other - the DataArrayInt to append to \a this one.
6018  *  \throw If \a this is not allocated.
6019  *  \throw If \a this and \a other arrays have different number of tuples.
6020  *
6021  *  \if ENABLE_EXAMPLES
6022  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6023  *
6024  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6025  *  \endif
6026  */
6027 void DataArrayInt::meldWith(const DataArrayInt *other)
6028 {
6029   if(!other)
6030     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6031   checkAllocated();
6032   other->checkAllocated();
6033   int nbOfTuples=getNumberOfTuples();
6034   if(nbOfTuples!=other->getNumberOfTuples())
6035     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6036   int nbOfComp1=getNumberOfComponents();
6037   int nbOfComp2=other->getNumberOfComponents();
6038   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6039   int *w=newArr;
6040   const int *inp1=getConstPointer();
6041   const int *inp2=other->getConstPointer();
6042   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6043     {
6044       w=std::copy(inp1,inp1+nbOfComp1,w);
6045       w=std::copy(inp2,inp2+nbOfComp2,w);
6046     }
6047   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6048   std::vector<int> compIds(nbOfComp2);
6049   for(int i=0;i<nbOfComp2;i++)
6050     compIds[i]=nbOfComp1+i;
6051   copyPartOfStringInfoFrom2(compIds,*other);
6052 }
6053
6054 /*!
6055  * Copy all components in a specified order from another DataArrayInt.
6056  * The specified components become the first ones in \a this array.
6057  * Both numerical and textual data is copied. The number of tuples in \a this and
6058  * the other array can be different.
6059  *  \param [in] a - the array to copy data from.
6060  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6061  *              to be copied.
6062  *  \throw If \a a is NULL.
6063  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6064  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6065  *
6066  *  \if ENABLE_EXAMPLES
6067  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6068  *  \endif
6069  */
6070 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6071 {
6072   if(!a)
6073     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6074   checkAllocated();
6075   a->checkAllocated();
6076   copyPartOfStringInfoFrom2(compoIds,*a);
6077   std::size_t partOfCompoSz=compoIds.size();
6078   int nbOfCompo=getNumberOfComponents();
6079   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6080   const int *ac=a->getConstPointer();
6081   int *nc=getPointer();
6082   for(int i=0;i<nbOfTuples;i++)
6083     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6084       nc[nbOfCompo*i+compoIds[j]]=*ac;
6085 }
6086
6087 /*!
6088  * Assign pointer to one array to a pointer to another appay. Reference counter of
6089  * \a arrayToSet is incremented / decremented.
6090  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6091  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6092  */
6093 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6094 {
6095   if(newArray!=arrayToSet)
6096     {
6097       if(arrayToSet)
6098         arrayToSet->decrRef();
6099       arrayToSet=newArray;
6100       if(arrayToSet)
6101         arrayToSet->incrRef();
6102     }
6103 }
6104
6105 DataArrayIntIterator *DataArrayInt::iterator()
6106 {
6107   return new DataArrayIntIterator(this);
6108 }
6109
6110 /*!
6111  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6112  * given one. The ids are sorted in the ascending order.
6113  *  \param [in] val - the value to find within \a this.
6114  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6115  *          array using decrRef() as it is no more needed.
6116  *  \throw If \a this is not allocated.
6117  *  \throw If \a this->getNumberOfComponents() != 1.
6118  *  \sa DataArrayInt::findIdsEqualTuple
6119  */
6120 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6121 {
6122   checkAllocated();
6123   if(getNumberOfComponents()!=1)
6124     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6125   const int *cptr(getConstPointer());
6126   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6127   int nbOfTuples=getNumberOfTuples();
6128   for(int i=0;i<nbOfTuples;i++,cptr++)
6129     if(*cptr==val)
6130       ret->pushBackSilent(i);
6131   return ret.retn();
6132 }
6133
6134 /*!
6135  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6136  * equal to a given one. 
6137  *  \param [in] val - the value to ignore within \a this.
6138  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6139  *          array using decrRef() as it is no more needed.
6140  *  \throw If \a this is not allocated.
6141  *  \throw If \a this->getNumberOfComponents() != 1.
6142  */
6143 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6144 {
6145   checkAllocated();
6146   if(getNumberOfComponents()!=1)
6147     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6148   const int *cptr(getConstPointer());
6149   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6150   int nbOfTuples=getNumberOfTuples();
6151   for(int i=0;i<nbOfTuples;i++,cptr++)
6152     if(*cptr!=val)
6153       ret->pushBackSilent(i);
6154   return ret.retn();
6155 }
6156
6157 /*!
6158  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6159  * This method is an extension of  DataArrayInt::findIdsEqual method.
6160  *
6161  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6162  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6163  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6164  *          array using decrRef() as it is no more needed.
6165  *  \throw If \a this is not allocated.
6166  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6167  * \throw If \a this->getNumberOfComponents() is equal to 0.
6168  * \sa DataArrayInt::findIdsEqual
6169  */
6170 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6171 {
6172   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6173   checkAllocated();
6174   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6175     {
6176       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6177       throw INTERP_KERNEL::Exception(oss.str().c_str());
6178     }
6179   if(nbOfCompoExp==0)
6180     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6181   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6182   const int *bg(begin()),*end2(end()),*work(begin());
6183   while(work!=end2)
6184     {
6185       work=std::search(work,end2,tupleBg,tupleEnd);
6186       if(work!=end2)
6187         {
6188           std::size_t pos(std::distance(bg,work));
6189           if(pos%nbOfCompoExp==0)
6190             ret->pushBackSilent(pos/nbOfCompoExp);
6191           work++;
6192         }
6193     }
6194   return ret.retn();
6195 }
6196
6197 /*!
6198  * Assigns \a newValue to all elements holding \a oldValue within \a this
6199  * one-dimensional array.
6200  *  \param [in] oldValue - the value to replace.
6201  *  \param [in] newValue - the value to assign.
6202  *  \return int - number of replacements performed.
6203  *  \throw If \a this is not allocated.
6204  *  \throw If \a this->getNumberOfComponents() != 1.
6205  */
6206 int DataArrayInt::changeValue(int oldValue, int newValue)
6207 {
6208   checkAllocated();
6209   if(getNumberOfComponents()!=1)
6210     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6211   if(oldValue==newValue)
6212     return 0;
6213   int *start(getPointer()),*end2(start+getNbOfElems());
6214   int ret(0);
6215   for(int *val=start;val!=end2;val++)
6216     {
6217       if(*val==oldValue)
6218         {
6219           *val=newValue;
6220           ret++;
6221         }
6222     }
6223   if(ret>0)
6224     declareAsNew();
6225   return ret;
6226 }
6227
6228 /*!
6229  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6230  * one of given values.
6231  *  \param [in] valsBg - an array of values to find within \a this array.
6232  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6233  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6234  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6235  *          array using decrRef() as it is no more needed.
6236  *  \throw If \a this->getNumberOfComponents() != 1.
6237  */
6238 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6239 {
6240   if(getNumberOfComponents()!=1)
6241     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6242   std::set<int> vals2(valsBg,valsEnd);
6243   const int *cptr(getConstPointer());
6244   std::vector<int> res;
6245   int nbOfTuples(getNumberOfTuples());
6246   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6247   for(int i=0;i<nbOfTuples;i++,cptr++)
6248     if(vals2.find(*cptr)!=vals2.end())
6249       ret->pushBackSilent(i);
6250   return ret.retn();
6251 }
6252
6253 /*!
6254  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6255  * equal to any of given values.
6256  *  \param [in] valsBg - an array of values to ignore within \a this array.
6257  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6258  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6259  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6260  *          array using decrRef() as it is no more needed.
6261  *  \throw If \a this->getNumberOfComponents() != 1.
6262  */
6263 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6264 {
6265   if(getNumberOfComponents()!=1)
6266     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6267   std::set<int> vals2(valsBg,valsEnd);
6268   const int *cptr=getConstPointer();
6269   std::vector<int> res;
6270   int nbOfTuples=getNumberOfTuples();
6271   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6272   for(int i=0;i<nbOfTuples;i++,cptr++)
6273     if(vals2.find(*cptr)==vals2.end())
6274       ret->pushBackSilent(i);
6275   return ret.retn();
6276 }
6277
6278 /*!
6279  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6280  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6281  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6282  * If any the tuple id is returned. If not -1 is returned.
6283  * 
6284  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6285  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6286  *
6287  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6288  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6289  */
6290 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6291 {
6292   checkAllocated();
6293   int nbOfCompo=getNumberOfComponents();
6294   if(nbOfCompo==0)
6295     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6296   if(nbOfCompo!=(int)tupl.size())
6297     {
6298       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6299       throw INTERP_KERNEL::Exception(oss.str().c_str());
6300     }
6301   const int *cptr=getConstPointer();
6302   std::size_t nbOfVals=getNbOfElems();
6303   for(const int *work=cptr;work!=cptr+nbOfVals;)
6304     {
6305       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6306       if(work!=cptr+nbOfVals)
6307         {
6308           if(std::distance(cptr,work)%nbOfCompo!=0)
6309             work++;
6310           else
6311             return std::distance(cptr,work)/nbOfCompo;
6312         }
6313     }
6314   return -1;
6315 }
6316
6317 /*!
6318  * This method searches the sequence specified in input parameter \b vals in \b this.
6319  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6320  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6321  * \sa DataArrayInt::findIdFirstEqualTuple
6322  */
6323 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6324 {
6325   checkAllocated();
6326   int nbOfCompo=getNumberOfComponents();
6327   if(nbOfCompo!=1)
6328     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6329   const int *cptr=getConstPointer();
6330   std::size_t nbOfVals=getNbOfElems();
6331   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6332   if(loc!=cptr+nbOfVals)
6333     return std::distance(cptr,loc);
6334   return -1;
6335 }
6336
6337 /*!
6338  * This method expects to be called when number of components of this is equal to one.
6339  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6340  * If not any tuple contains \b value -1 is returned.
6341  * \sa DataArrayInt::presenceOfValue
6342  */
6343 int DataArrayInt::findIdFirstEqual(int value) const
6344 {
6345   checkAllocated();
6346   if(getNumberOfComponents()!=1)
6347     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6348   const int *cptr=getConstPointer();
6349   int nbOfTuples=getNumberOfTuples();
6350   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6351   if(ret!=cptr+nbOfTuples)
6352     return std::distance(cptr,ret);
6353   return -1;
6354 }
6355
6356 /*!
6357  * This method expects to be called when number of components of this is equal to one.
6358  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6359  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6360  * \sa DataArrayInt::presenceOfValue
6361  */
6362 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6363 {
6364   checkAllocated();
6365   if(getNumberOfComponents()!=1)
6366     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6367   std::set<int> vals2(vals.begin(),vals.end());
6368   const int *cptr=getConstPointer();
6369   int nbOfTuples=getNumberOfTuples();
6370   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6371     if(vals2.find(*w)!=vals2.end())
6372       return std::distance(cptr,w);
6373   return -1;
6374 }
6375
6376 /*!
6377  * This method returns the number of values in \a this that are equals to input parameter \a value.
6378  * This method only works for single component array.
6379  *
6380  * \return a value in [ 0, \c this->getNumberOfTuples() )
6381  *
6382  * \throw If \a this is not allocated
6383  *
6384  */
6385 int DataArrayInt::count(int value) const
6386 {
6387   int ret=0;
6388   checkAllocated();
6389   if(getNumberOfComponents()!=1)
6390     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6391   const int *vals=begin();
6392   int nbOfTuples=getNumberOfTuples();
6393   for(int i=0;i<nbOfTuples;i++,vals++)
6394     if(*vals==value)
6395       ret++;
6396   return ret;
6397 }
6398
6399 /*!
6400  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6401  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6402  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6403  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6404  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6405  * \sa DataArrayInt::findIdFirstEqualTuple
6406  */
6407 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6408 {
6409   return findIdFirstEqualTuple(tupl)!=-1;
6410 }
6411
6412
6413 /*!
6414  * Returns \a true if a given value is present within \a this one-dimensional array.
6415  *  \param [in] value - the value to find within \a this array.
6416  *  \return bool - \a true in case if \a value is present within \a this array.
6417  *  \throw If \a this is not allocated.
6418  *  \throw If \a this->getNumberOfComponents() != 1.
6419  *  \sa findIdFirstEqual()
6420  */
6421 bool DataArrayInt::presenceOfValue(int value) const
6422 {
6423   return findIdFirstEqual(value)!=-1;
6424 }
6425
6426 /*!
6427  * This method expects to be called when number of components of this is equal to one.
6428  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6429  * If not any tuple contains one of the values contained in 'vals' false is returned.
6430  * \sa DataArrayInt::findIdFirstEqual
6431  */
6432 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6433 {
6434   return findIdFirstEqual(vals)!=-1;
6435 }
6436
6437 /*!
6438  * Accumulates values of each component of \a this array.
6439  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6440  *         by the caller, that is filled by this method with sum value for each
6441  *         component.
6442  *  \throw If \a this is not allocated.
6443  */
6444 void DataArrayInt::accumulate(int *res) const
6445 {
6446   checkAllocated();
6447   const int *ptr=getConstPointer();
6448   int nbTuple=getNumberOfTuples();
6449   int nbComps=getNumberOfComponents();
6450   std::fill(res,res+nbComps,0);
6451   for(int i=0;i<nbTuple;i++)
6452     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6453 }
6454
6455 int DataArrayInt::accumulate(int compId) const
6456 {
6457   checkAllocated();
6458   const int *ptr=getConstPointer();
6459   int nbTuple=getNumberOfTuples();
6460   int nbComps=getNumberOfComponents();
6461   if(compId<0 || compId>=nbComps)
6462     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6463   int ret=0;
6464   for(int i=0;i<nbTuple;i++)
6465     ret+=ptr[i*nbComps+compId];
6466   return ret;
6467 }
6468
6469 /*!
6470  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6471  * The returned array will have same number of components than \a this and number of tuples equal to
6472  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6473  *
6474  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6475  *
6476  * \param [in] bgOfIndex - begin (included) of the input index array.
6477  * \param [in] endOfIndex - end (excluded) of the input index array.
6478  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6479  * 
6480  * \throw If bgOfIndex or end is NULL.
6481  * \throw If input index array is not ascendingly sorted.
6482  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6483  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6484  */
6485 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6486 {
6487   if(!bgOfIndex || !endOfIndex)
6488     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6489   checkAllocated();
6490   int nbCompo=getNumberOfComponents();
6491   int nbOfTuples=getNumberOfTuples();
6492   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6493   if(sz<1)
6494     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6495   sz--;
6496   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6497   const int *w=bgOfIndex;
6498   if(*w<0 || *w>=nbOfTuples)
6499     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6500   const int *srcPt=begin()+(*w)*nbCompo;
6501   int *tmp=ret->getPointer();
6502   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6503     {
6504       std::fill(tmp,tmp+nbCompo,0);
6505       if(w[1]>=w[0])
6506         {
6507           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6508             {
6509               if(j>=0 && j<nbOfTuples)
6510                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6511               else
6512                 {
6513                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6514                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6515                 }
6516             }
6517         }
6518       else
6519         {
6520           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6521           throw INTERP_KERNEL::Exception(oss.str().c_str());
6522         }
6523     }
6524   ret->copyStringInfoFrom(*this);
6525   return ret.retn();
6526 }
6527
6528 /*!
6529  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6530  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6531  * offsetA2</em> and (2)
6532  * the number of component in the result array is same as that of each of given arrays.
6533  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6534  * Info on components is copied from the first of the given arrays. Number of components
6535  * in the given arrays must be the same.
6536  *  \param [in] a1 - an array to include in the result array.
6537  *  \param [in] a2 - another array to include in the result array.
6538  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6539  *  \return DataArrayInt * - the new instance of DataArrayInt.
6540  *          The caller is to delete this result array using decrRef() as it is no more
6541  *          needed.
6542  *  \throw If either \a a1 or \a a2 is NULL.
6543  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6544  */
6545 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6546 {
6547   if(!a1 || !a2)
6548     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6549   int nbOfComp=a1->getNumberOfComponents();
6550   if(nbOfComp!=a2->getNumberOfComponents())
6551     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6552   int nbOfTuple1=a1->getNumberOfTuples();
6553   int nbOfTuple2=a2->getNumberOfTuples();
6554   DataArrayInt *ret=DataArrayInt::New();
6555   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6556   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6557   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6558   ret->copyStringInfoFrom(*a1);
6559   return ret;
6560 }
6561
6562 /*!
6563  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6564  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6565  * the number of component in the result array is same as that of each of given arrays.
6566  * Info on components is copied from the first of the given arrays. Number of components
6567  * in the given arrays must be  the same.
6568  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6569  * not the object itself.
6570  *  \param [in] arr - a sequence of arrays to include in the result array.
6571  *  \return DataArrayInt * - the new instance of DataArrayInt.
6572  *          The caller is to delete this result array using decrRef() as it is no more
6573  *          needed.
6574  *  \throw If all arrays within \a arr are NULL.
6575  *  \throw If getNumberOfComponents() of arrays within \a arr.
6576  */
6577 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6578 {
6579   std::vector<const DataArrayInt *> a;
6580   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6581     if(*it4)
6582       a.push_back(*it4);
6583   if(a.empty())
6584     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6585   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6586   int nbOfComp=(*it)->getNumberOfComponents();
6587   int nbt=(*it++)->getNumberOfTuples();
6588   for(int i=1;it!=a.end();it++,i++)
6589     {
6590       if((*it)->getNumberOfComponents()!=nbOfComp)
6591         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6592       nbt+=(*it)->getNumberOfTuples();
6593     }
6594   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6595   ret->alloc(nbt,nbOfComp);
6596   int *pt=ret->getPointer();
6597   for(it=a.begin();it!=a.end();it++)
6598     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6599   ret->copyStringInfoFrom(*(a[0]));
6600   return ret.retn();
6601 }
6602
6603 /*!
6604  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6605  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6606  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6607  * 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.
6608  * 
6609  * \return DataArrayInt * - a new object to be managed by the caller.
6610  */
6611 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6612 {
6613   int retSz=1;
6614   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6615     {
6616       if(*it4)
6617         {
6618           (*it4)->checkAllocated();
6619           if((*it4)->getNumberOfComponents()!=1)
6620             {
6621               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6622               throw INTERP_KERNEL::Exception(oss.str().c_str());
6623             }
6624           int nbTupl=(*it4)->getNumberOfTuples();
6625           if(nbTupl<1)
6626             {
6627               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6628               throw INTERP_KERNEL::Exception(oss.str().c_str());
6629             }
6630           if((*it4)->front()!=0)
6631             {
6632               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6633               throw INTERP_KERNEL::Exception(oss.str().c_str());
6634             }
6635           retSz+=nbTupl-1;
6636         }
6637       else
6638         {
6639           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6640           throw INTERP_KERNEL::Exception(oss.str().c_str());
6641         }
6642     }
6643   if(arrs.empty())
6644     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6645   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6646   ret->alloc(retSz,1);
6647   int *pt=ret->getPointer(); *pt++=0;
6648   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6649     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6650   ret->copyStringInfoFrom(*(arrs[0]));
6651   return ret.retn();
6652 }
6653
6654 /*!
6655  * Returns in a single walk in \a this the min value and the max value in \a this.
6656  * \a this is expected to be single component array.
6657  *
6658  * \param [out] minValue - the min value in \a this.
6659  * \param [out] maxValue - the max value in \a this.
6660  *
6661  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6662  */
6663 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6664 {
6665   checkAllocated();
6666   if(getNumberOfComponents()!=1)
6667     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6668   int nbTuples(getNumberOfTuples());
6669   const int *pt(begin());
6670   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6671   for(int i=0;i<nbTuples;i++,pt++)
6672     {
6673       if(*pt<minValue)
6674         minValue=*pt;
6675       if(*pt>maxValue)
6676         maxValue=*pt;
6677     }
6678 }
6679
6680 /*!
6681  * Converts every value of \a this array to its absolute value.
6682  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6683  * should be called instead.
6684  *
6685  * \throw If \a this is not allocated.
6686  * \sa DataArrayInt::computeAbs
6687  */
6688 void DataArrayInt::abs()
6689 {
6690   checkAllocated();
6691   int *ptr(getPointer());
6692   std::size_t nbOfElems(getNbOfElems());
6693   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6694   declareAsNew();
6695 }
6696
6697 /*!
6698  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6699  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6700  *
6701  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6702  *         same number of tuples and component as \a this array.
6703  *         The caller is to delete this result array using decrRef() as it is no more
6704  *         needed.
6705  * \throw If \a this is not allocated.
6706  * \sa DataArrayInt::abs
6707  */
6708 DataArrayInt *DataArrayInt::computeAbs() const
6709 {
6710   checkAllocated();
6711   DataArrayInt *newArr(DataArrayInt::New());
6712   int nbOfTuples(getNumberOfTuples());
6713   int nbOfComp(getNumberOfComponents());
6714   newArr->alloc(nbOfTuples,nbOfComp);
6715   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6716   newArr->copyStringInfoFrom(*this);
6717   return newArr;
6718 }
6719
6720 /*!
6721  * Apply a liner function to a given component of \a this array, so that
6722  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6723  *  \param [in] a - the first coefficient of the function.
6724  *  \param [in] b - the second coefficient of the function.
6725  *  \param [in] compoId - the index of component to modify.
6726  *  \throw If \a this is not allocated.
6727  */
6728 void DataArrayInt::applyLin(int a, int b, int compoId)
6729 {
6730   checkAllocated();
6731   int *ptr=getPointer()+compoId;
6732   int nbOfComp=getNumberOfComponents();
6733   int nbOfTuple=getNumberOfTuples();
6734   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6735     *ptr=a*(*ptr)+b;
6736   declareAsNew();
6737 }
6738
6739 /*!
6740  * Apply a liner function to all elements of \a this array, so that
6741  * an element _x_ becomes \f$ a * x + b \f$.
6742  *  \param [in] a - the first coefficient of the function.
6743  *  \param [in] b - the second coefficient of the function.
6744  *  \throw If \a this is not allocated.
6745  */
6746 void DataArrayInt::applyLin(int a, int b)
6747 {
6748   checkAllocated();
6749   int *ptr=getPointer();
6750   std::size_t nbOfElems=getNbOfElems();
6751   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6752     *ptr=a*(*ptr)+b;
6753   declareAsNew();
6754 }
6755
6756 /*!
6757  * Returns a full copy of \a this array except that sign of all elements is reversed.
6758  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6759  *          same number of tuples and component as \a this array.
6760  *          The caller is to delete this result array using decrRef() as it is no more
6761  *          needed.
6762  *  \throw If \a this is not allocated.
6763  */
6764 DataArrayInt *DataArrayInt::negate() const
6765 {
6766   checkAllocated();
6767   DataArrayInt *newArr=DataArrayInt::New();
6768   int nbOfTuples=getNumberOfTuples();
6769   int nbOfComp=getNumberOfComponents();
6770   newArr->alloc(nbOfTuples,nbOfComp);
6771   const int *cptr=getConstPointer();
6772   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6773   newArr->copyStringInfoFrom(*this);
6774   return newArr;
6775 }
6776
6777 /*!
6778  * Modify all elements of \a this array, so that
6779  * an element _x_ becomes \f$ numerator / x \f$.
6780  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6781  *           array, all elements processed before detection of the zero element remain
6782  *           modified.
6783  *  \param [in] numerator - the numerator used to modify array elements.
6784  *  \throw If \a this is not allocated.
6785  *  \throw If there is an element equal to 0 in \a this array.
6786  */
6787 void DataArrayInt::applyInv(int numerator)
6788 {
6789   checkAllocated();
6790   int *ptr=getPointer();
6791   std::size_t nbOfElems=getNbOfElems();
6792   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6793     {
6794       if(*ptr!=0)
6795         {
6796           *ptr=numerator/(*ptr);
6797         }
6798       else
6799         {
6800           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6801           oss << " !";
6802           throw INTERP_KERNEL::Exception(oss.str().c_str());
6803         }
6804     }
6805   declareAsNew();
6806 }
6807
6808 /*!
6809  * Modify all elements of \a this array, so that
6810  * an element _x_ becomes \f$ x / val \f$.
6811  *  \param [in] val - the denominator used to modify array elements.
6812  *  \throw If \a this is not allocated.
6813  *  \throw If \a val == 0.
6814  */
6815 void DataArrayInt::applyDivideBy(int val)
6816 {
6817   if(val==0)
6818     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6819   checkAllocated();
6820   int *ptr=getPointer();
6821   std::size_t nbOfElems=getNbOfElems();
6822   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6823   declareAsNew();
6824 }
6825
6826 /*!
6827  * Modify all elements of \a this array, so that
6828  * an element _x_ becomes  <em> x % val </em>.
6829  *  \param [in] val - the divisor used to modify array elements.
6830  *  \throw If \a this is not allocated.
6831  *  \throw If \a val <= 0.
6832  */
6833 void DataArrayInt::applyModulus(int val)
6834 {
6835   if(val<=0)
6836     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6837   checkAllocated();
6838   int *ptr=getPointer();
6839   std::size_t nbOfElems=getNbOfElems();
6840   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6841   declareAsNew();
6842 }
6843
6844 /*!
6845  * This method works only on data array with one component.
6846  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6847  * this[*id] in [\b vmin,\b vmax)
6848  * 
6849  * \param [in] vmin begin of range. This value is included in range (included).
6850  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6851  * \return a newly allocated data array that the caller should deal with.
6852  *
6853  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6854  */
6855 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6856 {
6857   checkAllocated();
6858   if(getNumberOfComponents()!=1)
6859     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
6860   const int *cptr(begin());
6861   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6862   int nbOfTuples(getNumberOfTuples());
6863   for(int i=0;i<nbOfTuples;i++,cptr++)
6864     if(*cptr>=vmin && *cptr<vmax)
6865       ret->pushBackSilent(i);
6866   return ret.retn();
6867 }
6868
6869 /*!
6870  * This method works only on data array with one component.
6871  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6872  * this[*id] \b not in [\b vmin,\b vmax)
6873  * 
6874  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6875  * \param [in] vmax end of range. This value is included in range (included).
6876  * \return a newly allocated data array that the caller should deal with.
6877  * 
6878  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6879  */
6880 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6881 {
6882   checkAllocated();
6883   if(getNumberOfComponents()!=1)
6884     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
6885   const int *cptr(getConstPointer());
6886   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6887   int nbOfTuples(getNumberOfTuples());
6888   for(int i=0;i<nbOfTuples;i++,cptr++)
6889     if(*cptr<vmin || *cptr>=vmax)
6890       ret->pushBackSilent(i);
6891   return ret.retn();
6892 }
6893
6894 /*!
6895  * 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.
6896  *
6897  * \return a newly allocated data array that the caller should deal with.
6898  * \sa DataArrayInt::findIdsInRange
6899  */
6900 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6901 {
6902   checkAllocated();
6903   if(getNumberOfComponents()!=1)
6904     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
6905   const int *cptr(getConstPointer());
6906   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6907   int nbOfTuples(getNumberOfTuples());
6908   for(int i=0;i<nbOfTuples;i++,cptr++)
6909     if(*cptr<0)
6910       ret->pushBackSilent(i);
6911   return ret.retn();
6912 }
6913
6914 /*!
6915  * This method works only on data array with one component.
6916  * 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.
6917  * 
6918  * \param [in] vmin begin of range. This value is included in range (included).
6919  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6920  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6921 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6922 {
6923   checkAllocated();
6924   if(getNumberOfComponents()!=1)
6925     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6926   int nbOfTuples=getNumberOfTuples();
6927   bool ret=true;
6928   const int *cptr=getConstPointer();
6929   for(int i=0;i<nbOfTuples;i++,cptr++)
6930     {
6931       if(*cptr>=vmin && *cptr<vmax)
6932         { ret=ret && *cptr==i; }
6933       else
6934         {
6935           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6936           throw INTERP_KERNEL::Exception(oss.str().c_str());
6937         }
6938     }
6939   return ret;
6940 }
6941
6942 /*!
6943  * Modify all elements of \a this array, so that
6944  * an element _x_ becomes <em> val % x </em>.
6945  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6946  *           array, all elements processed before detection of the zero element remain
6947  *           modified.
6948  *  \param [in] val - the divident used to modify array elements.
6949  *  \throw If \a this is not allocated.
6950  *  \throw If there is an element equal to or less than 0 in \a this array.
6951  */
6952 void DataArrayInt::applyRModulus(int val)
6953 {
6954   checkAllocated();
6955   int *ptr=getPointer();
6956   std::size_t nbOfElems=getNbOfElems();
6957   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6958     {
6959       if(*ptr>0)
6960         {
6961           *ptr=val%(*ptr);
6962         }
6963       else
6964         {
6965           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6966           oss << " !";
6967           throw INTERP_KERNEL::Exception(oss.str().c_str());
6968         }
6969     }
6970   declareAsNew();
6971 }
6972
6973 /*!
6974  * Modify all elements of \a this array, so that
6975  * an element _x_ becomes <em> val ^ x </em>.
6976  *  \param [in] val - the value used to apply pow on all array elements.
6977  *  \throw If \a this is not allocated.
6978  *  \throw If \a val < 0.
6979  */
6980 void DataArrayInt::applyPow(int val)
6981 {
6982   checkAllocated();
6983   if(val<0)
6984     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
6985   int *ptr=getPointer();
6986   std::size_t nbOfElems=getNbOfElems();
6987   if(val==0)
6988     {
6989       std::fill(ptr,ptr+nbOfElems,1);
6990       return ;
6991     }
6992   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6993     {
6994       int tmp=1;
6995       for(int j=0;j<val;j++)
6996         tmp*=*ptr;
6997       *ptr=tmp;
6998     }
6999   declareAsNew();
7000 }
7001
7002 /*!
7003  * Modify all elements of \a this array, so that
7004  * an element _x_ becomes \f$ val ^ x \f$.
7005  *  \param [in] val - the value used to apply pow on all array elements.
7006  *  \throw If \a this is not allocated.
7007  *  \throw If there is an element < 0 in \a this array.
7008  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7009  *           array, all elements processed before detection of the zero element remain
7010  *           modified.
7011  */
7012 void DataArrayInt::applyRPow(int val)
7013 {
7014   checkAllocated();
7015   int *ptr=getPointer();
7016   std::size_t nbOfElems=getNbOfElems();
7017   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7018     {
7019       if(*ptr>=0)
7020         {
7021           int tmp=1;
7022           for(int j=0;j<*ptr;j++)
7023             tmp*=val;
7024           *ptr=tmp;
7025         }
7026       else
7027         {
7028           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7029           oss << " !";
7030           throw INTERP_KERNEL::Exception(oss.str().c_str());
7031         }
7032     }
7033   declareAsNew();
7034 }
7035
7036 /*!
7037  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7038  * of components in the result array is a sum of the number of components of given arrays
7039  * and (2) the number of tuples in the result array is same as that of each of given
7040  * arrays. In other words the i-th tuple of result array includes all components of
7041  * i-th tuples of all given arrays.
7042  * Number of tuples in the given arrays must be the same.
7043  *  \param [in] a1 - an array to include in the result array.
7044  *  \param [in] a2 - another array to include in the result array.
7045  *  \return DataArrayInt * - the new instance of DataArrayInt.
7046  *          The caller is to delete this result array using decrRef() as it is no more
7047  *          needed.
7048  *  \throw If both \a a1 and \a a2 are NULL.
7049  *  \throw If any given array is not allocated.
7050  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7051  */
7052 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7053 {
7054   std::vector<const DataArrayInt *> arr(2);
7055   arr[0]=a1; arr[1]=a2;
7056   return Meld(arr);
7057 }
7058
7059 /*!
7060  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7061  * of components in the result array is a sum of the number of components of given arrays
7062  * and (2) the number of tuples in the result array is same as that of each of given
7063  * arrays. In other words the i-th tuple of result array includes all components of
7064  * i-th tuples of all given arrays.
7065  * Number of tuples in the given arrays must be  the same.
7066  *  \param [in] arr - a sequence of arrays to include in the result array.
7067  *  \return DataArrayInt * - the new instance of DataArrayInt.
7068  *          The caller is to delete this result array using decrRef() as it is no more
7069  *          needed.
7070  *  \throw If all arrays within \a arr are NULL.
7071  *  \throw If any given array is not allocated.
7072  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7073  */
7074 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7075 {
7076   std::vector<const DataArrayInt *> a;
7077   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7078     if(*it4)
7079       a.push_back(*it4);
7080   if(a.empty())
7081     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7082   std::vector<const DataArrayInt *>::const_iterator it;
7083   for(it=a.begin();it!=a.end();it++)
7084     (*it)->checkAllocated();
7085   it=a.begin();
7086   int nbOfTuples=(*it)->getNumberOfTuples();
7087   std::vector<int> nbc(a.size());
7088   std::vector<const int *> pts(a.size());
7089   nbc[0]=(*it)->getNumberOfComponents();
7090   pts[0]=(*it++)->getConstPointer();
7091   for(int i=1;it!=a.end();it++,i++)
7092     {
7093       if(nbOfTuples!=(*it)->getNumberOfTuples())
7094         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7095       nbc[i]=(*it)->getNumberOfComponents();
7096       pts[i]=(*it)->getConstPointer();
7097     }
7098   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7099   DataArrayInt *ret=DataArrayInt::New();
7100   ret->alloc(nbOfTuples,totalNbOfComp);
7101   int *retPtr=ret->getPointer();
7102   for(int i=0;i<nbOfTuples;i++)
7103     for(int j=0;j<(int)a.size();j++)
7104       {
7105         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7106         pts[j]+=nbc[j];
7107       }
7108   int k=0;
7109   for(int i=0;i<(int)a.size();i++)
7110     for(int j=0;j<nbc[i];j++,k++)
7111       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7112   return ret;
7113 }
7114
7115 /*!
7116  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7117  * The i-th item of the result array is an ID of a set of elements belonging to a
7118  * unique set of groups, which the i-th element is a part of. This set of elements
7119  * belonging to a unique set of groups is called \a family, so the result array contains
7120  * IDs of families each element belongs to.
7121  *
7122  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7123  * then there are 3 families:
7124  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7125  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7126  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7127  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7128  * stands for the element #3 which is in none of groups.
7129  *
7130  *  \param [in] groups - sequence of groups of element IDs.
7131  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7132  *         in \a groups.
7133  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7134  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7135  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7136  *         delete this array using decrRef() as it is no more needed.
7137  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7138  */
7139 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7140 {
7141   std::vector<const DataArrayInt *> groups2;
7142   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7143     if(*it4)
7144       groups2.push_back(*it4);
7145   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7146   ret->alloc(newNb,1);
7147   int *retPtr=ret->getPointer();
7148   std::fill(retPtr,retPtr+newNb,0);
7149   int fid=1;
7150   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7151     {
7152       const int *ptr=(*iter)->getConstPointer();
7153       std::size_t nbOfElem=(*iter)->getNbOfElems();
7154       int sfid=fid;
7155       for(int j=0;j<sfid;j++)
7156         {
7157           bool found=false;
7158           for(std::size_t i=0;i<nbOfElem;i++)
7159             {
7160               if(ptr[i]>=0 && ptr[i]<newNb)
7161                 {
7162                   if(retPtr[ptr[i]]==j)
7163                     {
7164                       retPtr[ptr[i]]=fid;
7165                       found=true;
7166                     }
7167                 }
7168               else
7169                 {
7170                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7171                   oss << ") !";
7172                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7173                 }
7174             }
7175           if(found)
7176             fid++;
7177         }
7178     }
7179   fidsOfGroups.clear();
7180   fidsOfGroups.resize(groups2.size());
7181   int grId=0;
7182   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7183     {
7184       std::set<int> tmp;
7185       const int *ptr=(*iter)->getConstPointer();
7186       std::size_t nbOfElem=(*iter)->getNbOfElems();
7187       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7188         tmp.insert(retPtr[*p]);
7189       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7190     }
7191   return ret.retn();
7192 }
7193
7194 /*!
7195  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7196  * arrays. The result array does not contain any duplicates and its values
7197  * are sorted in ascending order.
7198  *  \param [in] arr - sequence of DataArrayInt's to unite.
7199  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7200  *         array using decrRef() as it is no more needed.
7201  *  \throw If any \a arr[i] is not allocated.
7202  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7203  */
7204 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7205 {
7206   std::vector<const DataArrayInt *> a;
7207   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7208     if(*it4)
7209       a.push_back(*it4);
7210   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7211     {
7212       (*it)->checkAllocated();
7213       if((*it)->getNumberOfComponents()!=1)
7214         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7215     }
7216   //
7217   std::set<int> r;
7218   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7219     {
7220       const int *pt=(*it)->getConstPointer();
7221       int nbOfTuples=(*it)->getNumberOfTuples();
7222       r.insert(pt,pt+nbOfTuples);
7223     }
7224   DataArrayInt *ret=DataArrayInt::New();
7225   ret->alloc((int)r.size(),1);
7226   std::copy(r.begin(),r.end(),ret->getPointer());
7227   return ret;
7228 }
7229
7230 /*!
7231  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7232  * arrays. The result array does not contain any duplicates and its values
7233  * are sorted in ascending order.
7234  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7235  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7236  *         array using decrRef() as it is no more needed.
7237  *  \throw If any \a arr[i] is not allocated.
7238  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7239  */
7240 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7241 {
7242   std::vector<const DataArrayInt *> a;
7243   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7244     if(*it4)
7245       a.push_back(*it4);
7246   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7247     {
7248       (*it)->checkAllocated();
7249       if((*it)->getNumberOfComponents()!=1)
7250         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7251     }
7252   //
7253   std::set<int> r;
7254   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7255     {
7256       const int *pt=(*it)->getConstPointer();
7257       int nbOfTuples=(*it)->getNumberOfTuples();
7258       std::set<int> s1(pt,pt+nbOfTuples);
7259       if(it!=a.begin())
7260         {
7261           std::set<int> r2;
7262           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7263           r=r2;
7264         }
7265       else
7266         r=s1;
7267     }
7268   DataArrayInt *ret(DataArrayInt::New());
7269   ret->alloc((int)r.size(),1);
7270   std::copy(r.begin(),r.end(),ret->getPointer());
7271   return ret;
7272 }
7273
7274 /// @cond INTERNAL
7275 namespace MEDCouplingImpl
7276 {
7277   class OpSwitchedOn
7278   {
7279   public:
7280     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7281     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7282   private:
7283     int *_pt;
7284     int _cnt;
7285   };
7286
7287   class OpSwitchedOff
7288   {
7289   public:
7290     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7291     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7292   private:
7293     int *_pt;
7294     int _cnt;
7295   };
7296 }
7297 /// @endcond
7298
7299 /*!
7300  * This method returns the list of ids in ascending mode so that v[id]==true.
7301  */
7302 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7303 {
7304   int sz((int)std::count(v.begin(),v.end(),true));
7305   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7306   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7307   return ret.retn();
7308 }
7309
7310 /*!
7311  * This method returns the list of ids in ascending mode so that v[id]==false.
7312  */
7313 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7314 {
7315   int sz((int)std::count(v.begin(),v.end(),false));
7316   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7317   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7318   return ret.retn();
7319 }
7320
7321 /*!
7322  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7323  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7324  *
7325  * \param [in] v the input data structure to be translate into skyline format.
7326  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7327  * \param [out] dataIndex the second element of the skyline format.
7328  */
7329 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7330 {
7331   int sz((int)v.size());
7332   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7333   ret1->alloc(sz+1,1);
7334   int *pt(ret1->getPointer()); *pt=0;
7335   for(int i=0;i<sz;i++,pt++)
7336     pt[1]=pt[0]+(int)v[i].size();
7337   ret0->alloc(ret1->back(),1);
7338   pt=ret0->getPointer();
7339   for(int i=0;i<sz;i++)
7340     pt=std::copy(v[i].begin(),v[i].end(),pt);
7341   data=ret0.retn(); dataIndex=ret1.retn();
7342 }
7343
7344 /*!
7345  * Returns a new DataArrayInt which contains a complement of elements of \a this
7346  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7347  * \a nbOfElement) not present in \a this array.
7348  *  \param [in] nbOfElement - maximal size of the result array.
7349  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7350  *         array using decrRef() as it is no more needed.
7351  *  \throw If \a this is not allocated.
7352  *  \throw If \a this->getNumberOfComponents() != 1.
7353  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7354  *         nbOfElement ).
7355  */
7356 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7357 {
7358   checkAllocated();
7359   if(getNumberOfComponents()!=1)
7360     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7361   std::vector<bool> tmp(nbOfElement);
7362   const int *pt=getConstPointer();
7363   int nbOfTuples=getNumberOfTuples();
7364   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7365     if(*w>=0 && *w<nbOfElement)
7366       tmp[*w]=true;
7367     else
7368       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7369   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7370   DataArrayInt *ret=DataArrayInt::New();
7371   ret->alloc(nbOfRetVal,1);
7372   int j=0;
7373   int *retPtr=ret->getPointer();
7374   for(int i=0;i<nbOfElement;i++)
7375     if(!tmp[i])
7376       retPtr[j++]=i;
7377   return ret;
7378 }
7379
7380 /*!
7381  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7382  * from an \a other one-dimensional array.
7383  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7384  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7385  *         caller is to delete this array using decrRef() as it is no more needed.
7386  *  \throw If \a other is NULL.
7387  *  \throw If \a other is not allocated.
7388  *  \throw If \a other->getNumberOfComponents() != 1.
7389  *  \throw If \a this is not allocated.
7390  *  \throw If \a this->getNumberOfComponents() != 1.
7391  *  \sa DataArrayInt::buildSubstractionOptimized()
7392  */
7393 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7394 {
7395   if(!other)
7396     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7397   checkAllocated();
7398   other->checkAllocated();
7399   if(getNumberOfComponents()!=1)
7400     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7401   if(other->getNumberOfComponents()!=1)
7402     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7403   const int *pt=getConstPointer();
7404   int nbOfTuples=getNumberOfTuples();
7405   std::set<int> s1(pt,pt+nbOfTuples);
7406   pt=other->getConstPointer();
7407   nbOfTuples=other->getNumberOfTuples();
7408   std::set<int> s2(pt,pt+nbOfTuples);
7409   std::vector<int> r;
7410   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7411   DataArrayInt *ret=DataArrayInt::New();
7412   ret->alloc((int)r.size(),1);
7413   std::copy(r.begin(),r.end(),ret->getPointer());
7414   return ret;
7415 }
7416
7417 /*!
7418  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7419  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7420  * 
7421  * \param [in] other an array with one component and expected to be sorted ascendingly.
7422  * \ret list of ids in \a this but not in \a other.
7423  * \sa DataArrayInt::buildSubstraction
7424  */
7425 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7426 {
7427   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7428   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7429   checkAllocated(); other->checkAllocated();
7430   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7431   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7432   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7433   const int *work1(pt1Bg),*work2(pt2Bg);
7434   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7435   for(;work1!=pt1End;work1++)
7436     {
7437       if(work2!=pt2End && *work1==*work2)
7438         work2++;
7439       else
7440         ret->pushBackSilent(*work1);
7441     }
7442   return ret.retn();
7443 }
7444
7445
7446 /*!
7447  * Returns a new DataArrayInt which contains all elements of \a this and a given
7448  * one-dimensional arrays. The result array does not contain any duplicates
7449  * and its values are sorted in ascending order.
7450  *  \param [in] other - an array to unite with \a this one.
7451  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7452  *         array using decrRef() as it is no more needed.
7453  *  \throw If \a this or \a other is not allocated.
7454  *  \throw If \a this->getNumberOfComponents() != 1.
7455  *  \throw If \a other->getNumberOfComponents() != 1.
7456  */
7457 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7458 {
7459   std::vector<const DataArrayInt *>arrs(2);
7460   arrs[0]=this; arrs[1]=other;
7461   return BuildUnion(arrs);
7462 }
7463
7464
7465 /*!
7466  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7467  * one-dimensional arrays. The result array does not contain any duplicates
7468  * and its values are sorted in ascending order.
7469  *  \param [in] other - an array to intersect with \a this one.
7470  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7471  *         array using decrRef() as it is no more needed.
7472  *  \throw If \a this or \a other is not allocated.
7473  *  \throw If \a this->getNumberOfComponents() != 1.
7474  *  \throw If \a other->getNumberOfComponents() != 1.
7475  */
7476 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7477 {
7478   std::vector<const DataArrayInt *>arrs(2);
7479   arrs[0]=this; arrs[1]=other;
7480   return BuildIntersection(arrs);
7481 }
7482
7483 /*!
7484  * This method can be applied on allocated with one component DataArrayInt instance.
7485  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7486  * 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]
7487  * 
7488  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7489  * \throw if \a this is not allocated or if \a this has not exactly one component.
7490  * \sa DataArrayInt::buildUniqueNotSorted
7491  */
7492 DataArrayInt *DataArrayInt::buildUnique() const
7493 {
7494   checkAllocated();
7495   if(getNumberOfComponents()!=1)
7496     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7497   int nbOfTuples=getNumberOfTuples();
7498   MCAuto<DataArrayInt> tmp=deepCopy();
7499   int *data=tmp->getPointer();
7500   int *last=std::unique(data,data+nbOfTuples);
7501   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7502   ret->alloc(std::distance(data,last),1);
7503   std::copy(data,last,ret->getPointer());
7504   return ret.retn();
7505 }
7506
7507 /*!
7508  * This method can be applied on allocated with one component DataArrayInt instance.
7509  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7510  *
7511  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7512  *
7513  * \throw if \a this is not allocated or if \a this has not exactly one component.
7514  *
7515  * \sa DataArrayInt::buildUnique
7516  */
7517 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7518 {
7519   checkAllocated();
7520     if(getNumberOfComponents()!=1)
7521       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7522   int minVal,maxVal;
7523   getMinMaxValues(minVal,maxVal);
7524   std::vector<bool> b(maxVal-minVal+1,false);
7525   const int *ptBg(begin()),*endBg(end());
7526   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7527   for(const int *pt=ptBg;pt!=endBg;pt++)
7528     {
7529       if(!b[*pt-minVal])
7530         {
7531           ret->pushBackSilent(*pt);
7532           b[*pt-minVal]=true;
7533         }
7534     }
7535   ret->copyStringInfoFrom(*this);
7536   return ret.retn();
7537 }
7538
7539 /*!
7540  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7541  * "index" array. Such "index" array is returned for example by 
7542  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7543  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7544  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7545  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7546  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7547  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7548  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7549  *          The caller is to delete this array using decrRef() as it is no more needed. 
7550  *  \throw If \a this is not allocated.
7551  *  \throw If \a this->getNumberOfComponents() != 1.
7552  *  \throw If \a this->getNumberOfTuples() < 2.
7553  *
7554  *  \b Example: <br> 
7555  *         - this contains [1,3,6,7,7,9,15]
7556  *         - result array contains [2,3,1,0,2,6],
7557  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7558  *
7559  * \sa DataArrayInt::computeOffsetsFull
7560  */
7561 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7562 {
7563   checkAllocated();
7564   if(getNumberOfComponents()!=1)
7565     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7566   int nbOfTuples=getNumberOfTuples();
7567   if(nbOfTuples<2)
7568     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7569   const int *ptr=getConstPointer();
7570   DataArrayInt *ret=DataArrayInt::New();
7571   ret->alloc(nbOfTuples-1,1);
7572   int *out=ret->getPointer();
7573   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7574   return ret;
7575 }
7576
7577 /*!
7578  * Modifies \a this one-dimensional array so that value of each element \a x
7579  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7580  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7581  * and components remains the same.<br>
7582  * This method is useful for allToAllV in MPI with contiguous policy. This method
7583  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7584  * this one.
7585  *  \throw If \a this is not allocated.
7586  *  \throw If \a this->getNumberOfComponents() != 1.
7587  *
7588  *  \b Example: <br>
7589  *          - Before \a this contains [3,5,1,2,0,8]
7590  *          - After \a this contains  [0,3,8,9,11,11]<br>
7591  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7592  *          array is retained and thus there is no space to store the last element.
7593  */
7594 void DataArrayInt::computeOffsets()
7595 {
7596   checkAllocated();
7597   if(getNumberOfComponents()!=1)
7598     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7599   int nbOfTuples=getNumberOfTuples();
7600   if(nbOfTuples==0)
7601     return ;
7602   int *work=getPointer();
7603   int tmp=work[0];
7604   work[0]=0;
7605   for(int i=1;i<nbOfTuples;i++)
7606     {
7607       int tmp2=work[i];
7608       work[i]=work[i-1]+tmp;
7609       tmp=tmp2;
7610     }
7611   declareAsNew();
7612 }
7613
7614
7615 /*!
7616  * Modifies \a this one-dimensional array so that value of each element \a x
7617  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7618  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7619  * components remains the same and number of tuples is inceamented by one.<br>
7620  * This method is useful for allToAllV in MPI with contiguous policy. This method
7621  * differs from computeOffsets() in that the number of tuples is changed by this one.
7622  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7623  *  \throw If \a this is not allocated.
7624  *  \throw If \a this->getNumberOfComponents() != 1.
7625  *
7626  *  \b Example: <br>
7627  *          - Before \a this contains [3,5,1,2,0,8]
7628  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7629  * \sa DataArrayInt::deltaShiftIndex
7630  */
7631 void DataArrayInt::computeOffsetsFull()
7632 {
7633   checkAllocated();
7634   if(getNumberOfComponents()!=1)
7635     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7636   int nbOfTuples=getNumberOfTuples();
7637   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7638   const int *work=getConstPointer();
7639   ret[0]=0;
7640   for(int i=0;i<nbOfTuples;i++)
7641     ret[i+1]=work[i]+ret[i];
7642   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7643   declareAsNew();
7644 }
7645
7646 /*!
7647  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7648  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7649  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7650  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7651  * filling completely one of the ranges in \a this.
7652  *
7653  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7654  * \param [out] rangeIdsFetched the range ids fetched
7655  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7656  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7657  *
7658  * \sa DataArrayInt::computeOffsetsFull
7659  *
7660  *  \b Example: <br>
7661  *          - \a this : [0,3,7,9,15,18]
7662  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7663  *          - \a rangeIdsFetched result array: [0,2,4]
7664  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7665  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7666  * <br>
7667  */
7668 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7669 {
7670   if(!listOfIds)
7671     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7672   listOfIds->checkAllocated(); checkAllocated();
7673   if(listOfIds->getNumberOfComponents()!=1)
7674     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7675   if(getNumberOfComponents()!=1)
7676     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7677   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7678   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7679   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7680   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7681   while(tupPtr!=tupEnd && offPtr!=offEnd)
7682     {
7683       if(*tupPtr==*offPtr)
7684         {
7685           int i=offPtr[0];
7686           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7687           if(i==offPtr[1])
7688             {
7689               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7690               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7691               offPtr++;
7692             }
7693         }
7694       else
7695         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7696     }
7697   rangeIdsFetched=ret0.retn();
7698   idsInInputListThatFetch=ret1.retn();
7699 }
7700
7701 /*!
7702  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7703  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7704  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7705  * beginning within the "iota" array. And \a this is a one-dimensional array
7706  * considered as a selector of groups described by \a offsets to include into the result array.
7707  *  \throw If \a offsets is NULL.
7708  *  \throw If \a offsets is not allocated.
7709  *  \throw If \a offsets->getNumberOfComponents() != 1.
7710  *  \throw If \a offsets is not monotonically increasing.
7711  *  \throw If \a this is not allocated.
7712  *  \throw If \a this->getNumberOfComponents() != 1.
7713  *  \throw If any element of \a this is not a valid index for \a offsets array.
7714  *
7715  *  \b Example: <br>
7716  *          - \a this: [0,2,3]
7717  *          - \a offsets: [0,3,6,10,14,20]
7718  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7719  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7720  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7721  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7722  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7723  */
7724 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7725 {
7726   if(!offsets)
7727     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7728   checkAllocated();
7729   if(getNumberOfComponents()!=1)
7730     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7731   offsets->checkAllocated();
7732   if(offsets->getNumberOfComponents()!=1)
7733     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7734   int othNbTuples=offsets->getNumberOfTuples()-1;
7735   int nbOfTuples=getNumberOfTuples();
7736   int retNbOftuples=0;
7737   const int *work=getConstPointer();
7738   const int *offPtr=offsets->getConstPointer();
7739   for(int i=0;i<nbOfTuples;i++)
7740     {
7741       int val=work[i];
7742       if(val>=0 && val<othNbTuples)
7743         {
7744           int delta=offPtr[val+1]-offPtr[val];
7745           if(delta>=0)
7746             retNbOftuples+=delta;
7747           else
7748             {
7749               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7750               throw INTERP_KERNEL::Exception(oss.str().c_str());
7751             }
7752         }
7753       else
7754         {
7755           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7756           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7757           throw INTERP_KERNEL::Exception(oss.str().c_str());
7758         }
7759     }
7760   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7761   ret->alloc(retNbOftuples,1);
7762   int *retPtr=ret->getPointer();
7763   for(int i=0;i<nbOfTuples;i++)
7764     {
7765       int val=work[i];
7766       int start=offPtr[val];
7767       int off=offPtr[val+1]-start;
7768       for(int j=0;j<off;j++,retPtr++)
7769         *retPtr=start+j;
7770     }
7771   return ret.retn();
7772 }
7773
7774 /*!
7775  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7776  * scaled array (monotonically increasing).
7777 from that of \a this and \a
7778  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7779  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7780  * beginning within the "iota" array. And \a this is a one-dimensional array
7781  * considered as a selector of groups described by \a offsets to include into the result array.
7782  *  \throw If \a  is NULL.
7783  *  \throw If \a this is not allocated.
7784  *  \throw If \a this->getNumberOfComponents() != 1.
7785  *  \throw If \a this->getNumberOfTuples() == 0.
7786  *  \throw If \a this is not monotonically increasing.
7787  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7788  *
7789  *  \b Example: <br>
7790  *          - \a bg , \a stop and \a step : (0,5,2)
7791  *          - \a this: [0,3,6,10,14,20]
7792  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7793  */
7794 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7795 {
7796   if(!isAllocated())
7797     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7798   if(getNumberOfComponents()!=1)
7799     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7800   int nbOfTuples(getNumberOfTuples());
7801   if(nbOfTuples==0)
7802     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7803   const int *ids(begin());
7804   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7805   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7806     {
7807       if(pos>=0 && pos<nbOfTuples-1)
7808         {
7809           int delta(ids[pos+1]-ids[pos]);
7810           sz+=delta;
7811           if(delta<0)
7812             {
7813               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7814               throw INTERP_KERNEL::Exception(oss.str().c_str());
7815             }          
7816         }
7817       else
7818         {
7819           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7820           throw INTERP_KERNEL::Exception(oss.str().c_str());
7821         }
7822     }
7823   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7824   int *retPtr(ret->getPointer());
7825   pos=bg;
7826   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7827     {
7828       int delta(ids[pos+1]-ids[pos]);
7829       for(int j=0;j<delta;j++,retPtr++)
7830         *retPtr=pos;
7831     }
7832   return ret.retn();
7833 }
7834
7835 /*!
7836  * 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.
7837  * 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
7838  * in tuple **i** of returned DataArrayInt.
7839  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7840  *
7841  * 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)]
7842  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7843  * 
7844  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7845  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7846  * \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
7847  *        is thrown if no ranges in \a ranges contains value in \a this.
7848  * 
7849  * \sa DataArrayInt::findIdInRangeForEachTuple
7850  */
7851 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7852 {
7853   if(!ranges)
7854     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7855   if(ranges->getNumberOfComponents()!=2)
7856     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7857   checkAllocated();
7858   if(getNumberOfComponents()!=1)
7859     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7860   int nbTuples=getNumberOfTuples();
7861   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7862   int nbOfRanges=ranges->getNumberOfTuples();
7863   const int *rangesPtr=ranges->getConstPointer();
7864   int *retPtr=ret->getPointer();
7865   const int *inPtr=getConstPointer();
7866   for(int i=0;i<nbTuples;i++,retPtr++)
7867     {
7868       int val=inPtr[i];
7869       bool found=false;
7870       for(int j=0;j<nbOfRanges && !found;j++)
7871         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7872           { *retPtr=j; found=true; }
7873       if(found)
7874         continue;
7875       else
7876         {
7877           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7878           throw INTERP_KERNEL::Exception(oss.str().c_str());
7879         }
7880     }
7881   return ret.retn();
7882 }
7883
7884 /*!
7885  * 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.
7886  * 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
7887  * in tuple **i** of returned DataArrayInt.
7888  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7889  *
7890  * 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)]
7891  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7892  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7893  * 
7894  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7895  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7896  * \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
7897  *        is thrown if no ranges in \a ranges contains value in \a this.
7898  * \sa DataArrayInt::findRangeIdForEachTuple
7899  */
7900 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7901 {
7902   if(!ranges)
7903     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7904   if(ranges->getNumberOfComponents()!=2)
7905     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7906   checkAllocated();
7907   if(getNumberOfComponents()!=1)
7908     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7909   int nbTuples=getNumberOfTuples();
7910   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7911   int nbOfRanges=ranges->getNumberOfTuples();
7912   const int *rangesPtr=ranges->getConstPointer();
7913   int *retPtr=ret->getPointer();
7914   const int *inPtr=getConstPointer();
7915   for(int i=0;i<nbTuples;i++,retPtr++)
7916     {
7917       int val=inPtr[i];
7918       bool found=false;
7919       for(int j=0;j<nbOfRanges && !found;j++)
7920         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7921           { *retPtr=val-rangesPtr[2*j]; found=true; }
7922       if(found)
7923         continue;
7924       else
7925         {
7926           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7927           throw INTERP_KERNEL::Exception(oss.str().c_str());
7928         }
7929     }
7930   return ret.retn();
7931 }
7932
7933 /*!
7934  * \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).
7935  * 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).
7936  * 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 !
7937  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7938  * This method does nothing if number of tuples is lower of equal to 1.
7939  *
7940  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7941  *
7942  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
7943  */
7944 void DataArrayInt::sortEachPairToMakeALinkedList()
7945 {
7946   checkAllocated();
7947   if(getNumberOfComponents()!=2)
7948     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7949   int nbOfTuples(getNumberOfTuples());
7950   if(nbOfTuples<=1)
7951     return ;
7952   int *conn(getPointer());
7953   for(int i=1;i<nbOfTuples;i++,conn+=2)
7954     {
7955       if(i>1)
7956         {
7957           if(conn[2]==conn[3])
7958             {
7959               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7960               throw INTERP_KERNEL::Exception(oss.str().c_str());
7961             }
7962           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
7963             std::swap(conn[2],conn[3]);
7964           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
7965           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
7966             {
7967               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
7968               throw INTERP_KERNEL::Exception(oss.str().c_str());
7969             }
7970         }
7971       else
7972         {
7973           if(conn[0]==conn[1] || conn[2]==conn[3])
7974             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
7975           int tmp[4];
7976           std::set<int> s;
7977           s.insert(conn,conn+4);
7978           if(s.size()!=3)
7979             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
7980           if(std::count(conn,conn+4,conn[0])==2)
7981             {
7982               tmp[0]=conn[1];
7983               tmp[1]=conn[0];
7984               tmp[2]=conn[0];
7985               if(conn[2]==conn[0])
7986                 { tmp[3]=conn[3]; }
7987               else
7988                 { tmp[3]=conn[2];}
7989               std::copy(tmp,tmp+4,conn);
7990             }
7991           else
7992             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
7993               if(conn[1]==conn[3])
7994                 std::swap(conn[2],conn[3]);
7995             }
7996         }
7997     }
7998 }
7999
8000 /*!
8001  * 
8002  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8003  *             \a nbTimes  should be at least equal to 1.
8004  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8005  * \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.
8006  */
8007 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8008 {
8009   checkAllocated();
8010   if(getNumberOfComponents()!=1)
8011     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8012   if(nbTimes<1)
8013     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8014   int nbTuples=getNumberOfTuples();
8015   const int *inPtr=getConstPointer();
8016   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8017   int *retPtr=ret->getPointer();
8018   for(int i=0;i<nbTuples;i++,inPtr++)
8019     {
8020       int val=*inPtr;
8021       for(int j=0;j<nbTimes;j++,retPtr++)
8022         *retPtr=val;
8023     }
8024   ret->copyStringInfoFrom(*this);
8025   return ret.retn();
8026 }
8027
8028 /*!
8029  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8030  * But the number of components can be different from one.
8031  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8032  */
8033 DataArrayInt *DataArrayInt::getDifferentValues() const
8034 {
8035   checkAllocated();
8036   std::set<int> ret;
8037   ret.insert(begin(),end());
8038   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8039   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8040   return ret2.retn();
8041 }
8042
8043 /*!
8044  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8045  * them it tells which tuple id have this id.
8046  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8047  * This method returns two arrays having same size.
8048  * 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.
8049  * 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]]
8050  */
8051 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8052 {
8053   checkAllocated();
8054   if(getNumberOfComponents()!=1)
8055     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8056   int id=0;
8057   std::map<int,int> m,m2,m3;
8058   for(const int *w=begin();w!=end();w++)
8059     m[*w]++;
8060   differentIds.resize(m.size());
8061   std::vector<DataArrayInt *> ret(m.size());
8062   std::vector<int *> retPtr(m.size());
8063   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8064     {
8065       m2[(*it).first]=id;
8066       ret[id]=DataArrayInt::New();
8067       ret[id]->alloc((*it).second,1);
8068       retPtr[id]=ret[id]->getPointer();
8069       differentIds[id]=(*it).first;
8070     }
8071   id=0;
8072   for(const int *w=begin();w!=end();w++,id++)
8073     {
8074       retPtr[m2[*w]][m3[*w]++]=id;
8075     }
8076   return ret;
8077 }
8078
8079 /*!
8080  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8081  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8082  *
8083  * \param [in] nbOfSlices - number of slices expected.
8084  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8085  * 
8086  * \sa DataArray::GetSlice
8087  * \throw If \a this is not allocated or not with exactly one component.
8088  * \throw If an element in \a this if < 0.
8089  */
8090 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8091 {
8092   if(!isAllocated() || getNumberOfComponents()!=1)
8093     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8094   if(nbOfSlices<=0)
8095     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8096   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8097   int sumPerSlc(sum/nbOfSlices),pos(0);
8098   const int *w(begin());
8099   std::vector< std::pair<int,int> > ret(nbOfSlices);
8100   for(int i=0;i<nbOfSlices;i++)
8101     {
8102       std::pair<int,int> p(pos,-1);
8103       int locSum(0);
8104       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8105       if(i!=nbOfSlices-1)
8106         p.second=pos;
8107       else
8108         p.second=nbOfTuples;
8109       ret[i]=p;
8110     }
8111   return ret;
8112 }
8113
8114 /*!
8115  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8116  * valid cases.
8117  * 1.  The arrays have same number of tuples and components. Then each value of
8118  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8119  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8120  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8121  *   component. Then
8122  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8123  * 3.  The arrays have same number of components and one array, say _a2_, has one
8124  *   tuple. Then
8125  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8126  *
8127  * Info on components is copied either from the first array (in the first case) or from
8128  * the array with maximal number of elements (getNbOfElems()).
8129  *  \param [in] a1 - an array to sum up.
8130  *  \param [in] a2 - another array to sum up.
8131  *  \return DataArrayInt * - the new instance of DataArrayInt.
8132  *          The caller is to delete this result array using decrRef() as it is no more
8133  *          needed.
8134  *  \throw If either \a a1 or \a a2 is NULL.
8135  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8136  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8137  *         none of them has number of tuples or components equal to 1.
8138  */
8139 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8140 {
8141   if(!a1 || !a2)
8142     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8143   int nbOfTuple=a1->getNumberOfTuples();
8144   int nbOfTuple2=a2->getNumberOfTuples();
8145   int nbOfComp=a1->getNumberOfComponents();
8146   int nbOfComp2=a2->getNumberOfComponents();
8147   MCAuto<DataArrayInt> ret=0;
8148   if(nbOfTuple==nbOfTuple2)
8149     {
8150       if(nbOfComp==nbOfComp2)
8151         {
8152           ret=DataArrayInt::New();
8153           ret->alloc(nbOfTuple,nbOfComp);
8154           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8155           ret->copyStringInfoFrom(*a1);
8156         }
8157       else
8158         {
8159           int nbOfCompMin,nbOfCompMax;
8160           const DataArrayInt *aMin, *aMax;
8161           if(nbOfComp>nbOfComp2)
8162             {
8163               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8164               aMin=a2; aMax=a1;
8165             }
8166           else
8167             {
8168               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8169               aMin=a1; aMax=a2;
8170             }
8171           if(nbOfCompMin==1)
8172             {
8173               ret=DataArrayInt::New();
8174               ret->alloc(nbOfTuple,nbOfCompMax);
8175               const int *aMinPtr=aMin->getConstPointer();
8176               const int *aMaxPtr=aMax->getConstPointer();
8177               int *res=ret->getPointer();
8178               for(int i=0;i<nbOfTuple;i++)
8179                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8180               ret->copyStringInfoFrom(*aMax);
8181             }
8182           else
8183             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8184         }
8185     }
8186   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8187     {
8188       if(nbOfComp==nbOfComp2)
8189         {
8190           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8191           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8192           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8193           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8194           ret=DataArrayInt::New();
8195           ret->alloc(nbOfTupleMax,nbOfComp);
8196           int *res=ret->getPointer();
8197           for(int i=0;i<nbOfTupleMax;i++)
8198             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8199           ret->copyStringInfoFrom(*aMax);
8200         }
8201       else
8202         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8203     }
8204   else
8205     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8206   return ret.retn();
8207 }
8208
8209 /*!
8210  * Adds values of another DataArrayInt to values of \a this one. There are 3
8211  * valid cases.
8212  * 1.  The arrays have same number of tuples and components. Then each value of
8213  *   \a other array is added to the corresponding value of \a this array, i.e.:
8214  *   _a_ [ i, j ] += _other_ [ i, j ].
8215  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8216  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8217  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8218  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8219  *
8220  *  \param [in] other - an array to add to \a this one.
8221  *  \throw If \a other is NULL.
8222  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8223  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8224  *         \a other has number of both tuples and components not equal to 1.
8225  */
8226 void DataArrayInt::addEqual(const DataArrayInt *other)
8227 {
8228   if(!other)
8229     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8230   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8231   checkAllocated(); other->checkAllocated();
8232   int nbOfTuple=getNumberOfTuples();
8233   int nbOfTuple2=other->getNumberOfTuples();
8234   int nbOfComp=getNumberOfComponents();
8235   int nbOfComp2=other->getNumberOfComponents();
8236   if(nbOfTuple==nbOfTuple2)
8237     {
8238       if(nbOfComp==nbOfComp2)
8239         {
8240           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8241         }
8242       else if(nbOfComp2==1)
8243         {
8244           int *ptr=getPointer();
8245           const int *ptrc=other->getConstPointer();
8246           for(int i=0;i<nbOfTuple;i++)
8247             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8248         }
8249       else
8250         throw INTERP_KERNEL::Exception(msg);
8251     }
8252   else if(nbOfTuple2==1)
8253     {
8254       if(nbOfComp2==nbOfComp)
8255         {
8256           int *ptr=getPointer();
8257           const int *ptrc=other->getConstPointer();
8258           for(int i=0;i<nbOfTuple;i++)
8259             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8260         }
8261       else
8262         throw INTERP_KERNEL::Exception(msg);
8263     }
8264   else
8265     throw INTERP_KERNEL::Exception(msg);
8266   declareAsNew();
8267 }
8268
8269 /*!
8270  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8271  * valid cases.
8272  * 1.  The arrays have same number of tuples and components. Then each value of
8273  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8274  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8275  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8276  *   component. Then
8277  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8278  * 3.  The arrays have same number of components and one array, say _a2_, has one
8279  *   tuple. Then
8280  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8281  *
8282  * Info on components is copied either from the first array (in the first case) or from
8283  * the array with maximal number of elements (getNbOfElems()).
8284  *  \param [in] a1 - an array to subtract from.
8285  *  \param [in] a2 - an array to subtract.
8286  *  \return DataArrayInt * - the new instance of DataArrayInt.
8287  *          The caller is to delete this result array using decrRef() as it is no more
8288  *          needed.
8289  *  \throw If either \a a1 or \a a2 is NULL.
8290  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8291  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8292  *         none of them has number of tuples or components equal to 1.
8293  */
8294 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8295 {
8296   if(!a1 || !a2)
8297     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8298   int nbOfTuple1=a1->getNumberOfTuples();
8299   int nbOfTuple2=a2->getNumberOfTuples();
8300   int nbOfComp1=a1->getNumberOfComponents();
8301   int nbOfComp2=a2->getNumberOfComponents();
8302   if(nbOfTuple2==nbOfTuple1)
8303     {
8304       if(nbOfComp1==nbOfComp2)
8305         {
8306           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8307           ret->alloc(nbOfTuple2,nbOfComp1);
8308           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8309           ret->copyStringInfoFrom(*a1);
8310           return ret.retn();
8311         }
8312       else if(nbOfComp2==1)
8313         {
8314           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8315           ret->alloc(nbOfTuple1,nbOfComp1);
8316           const int *a2Ptr=a2->getConstPointer();
8317           const int *a1Ptr=a1->getConstPointer();
8318           int *res=ret->getPointer();
8319           for(int i=0;i<nbOfTuple1;i++)
8320             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8321           ret->copyStringInfoFrom(*a1);
8322           return ret.retn();
8323         }
8324       else
8325         {
8326           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8327           return 0;
8328         }
8329     }
8330   else if(nbOfTuple2==1)
8331     {
8332       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8333       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8334       ret->alloc(nbOfTuple1,nbOfComp1);
8335       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8336       int *pt=ret->getPointer();
8337       for(int i=0;i<nbOfTuple1;i++)
8338         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8339       ret->copyStringInfoFrom(*a1);
8340       return ret.retn();
8341     }
8342   else
8343     {
8344       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8345       return 0;
8346     }
8347 }
8348
8349 /*!
8350  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8351  * valid cases.
8352  * 1.  The arrays have same number of tuples and components. Then each value of
8353  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8354  *   _a_ [ i, j ] -= _other_ [ i, j ].
8355  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8356  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8357  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8358  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8359  *
8360  *  \param [in] other - an array to subtract from \a this one.
8361  *  \throw If \a other is NULL.
8362  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8363  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8364  *         \a other has number of both tuples and components not equal to 1.
8365  */
8366 void DataArrayInt::substractEqual(const DataArrayInt *other)
8367 {
8368   if(!other)
8369     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8370   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8371   checkAllocated(); other->checkAllocated();
8372   int nbOfTuple=getNumberOfTuples();
8373   int nbOfTuple2=other->getNumberOfTuples();
8374   int nbOfComp=getNumberOfComponents();
8375   int nbOfComp2=other->getNumberOfComponents();
8376   if(nbOfTuple==nbOfTuple2)
8377     {
8378       if(nbOfComp==nbOfComp2)
8379         {
8380           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8381         }
8382       else if(nbOfComp2==1)
8383         {
8384           int *ptr=getPointer();
8385           const int *ptrc=other->getConstPointer();
8386           for(int i=0;i<nbOfTuple;i++)
8387             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8388         }
8389       else
8390         throw INTERP_KERNEL::Exception(msg);
8391     }
8392   else if(nbOfTuple2==1)
8393     {
8394       int *ptr=getPointer();
8395       const int *ptrc=other->getConstPointer();
8396       for(int i=0;i<nbOfTuple;i++)
8397         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8398     }
8399   else
8400     throw INTERP_KERNEL::Exception(msg);
8401   declareAsNew();
8402 }
8403
8404 /*!
8405  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8406  * valid cases.
8407  * 1.  The arrays have same number of tuples and components. Then each value of
8408  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8409  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8410  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8411  *   component. Then
8412  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8413  * 3.  The arrays have same number of components and one array, say _a2_, has one
8414  *   tuple. Then
8415  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8416  *
8417  * Info on components is copied either from the first array (in the first case) or from
8418  * the array with maximal number of elements (getNbOfElems()).
8419  *  \param [in] a1 - a factor array.
8420  *  \param [in] a2 - another factor array.
8421  *  \return DataArrayInt * - the new instance of DataArrayInt.
8422  *          The caller is to delete this result array using decrRef() as it is no more
8423  *          needed.
8424  *  \throw If either \a a1 or \a a2 is NULL.
8425  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8426  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8427  *         none of them has number of tuples or components equal to 1.
8428  */
8429 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8430 {
8431   if(!a1 || !a2)
8432     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8433   int nbOfTuple=a1->getNumberOfTuples();
8434   int nbOfTuple2=a2->getNumberOfTuples();
8435   int nbOfComp=a1->getNumberOfComponents();
8436   int nbOfComp2=a2->getNumberOfComponents();
8437   MCAuto<DataArrayInt> ret=0;
8438   if(nbOfTuple==nbOfTuple2)
8439     {
8440       if(nbOfComp==nbOfComp2)
8441         {
8442           ret=DataArrayInt::New();
8443           ret->alloc(nbOfTuple,nbOfComp);
8444           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8445           ret->copyStringInfoFrom(*a1);
8446         }
8447       else
8448         {
8449           int nbOfCompMin,nbOfCompMax;
8450           const DataArrayInt *aMin, *aMax;
8451           if(nbOfComp>nbOfComp2)
8452             {
8453               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8454               aMin=a2; aMax=a1;
8455             }
8456           else
8457             {
8458               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8459               aMin=a1; aMax=a2;
8460             }
8461           if(nbOfCompMin==1)
8462             {
8463               ret=DataArrayInt::New();
8464               ret->alloc(nbOfTuple,nbOfCompMax);
8465               const int *aMinPtr=aMin->getConstPointer();
8466               const int *aMaxPtr=aMax->getConstPointer();
8467               int *res=ret->getPointer();
8468               for(int i=0;i<nbOfTuple;i++)
8469                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8470               ret->copyStringInfoFrom(*aMax);
8471             }
8472           else
8473             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8474         }
8475     }
8476   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8477     {
8478       if(nbOfComp==nbOfComp2)
8479         {
8480           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8481           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8482           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8483           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8484           ret=DataArrayInt::New();
8485           ret->alloc(nbOfTupleMax,nbOfComp);
8486           int *res=ret->getPointer();
8487           for(int i=0;i<nbOfTupleMax;i++)
8488             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8489           ret->copyStringInfoFrom(*aMax);
8490         }
8491       else
8492         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8493     }
8494   else
8495     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8496   return ret.retn();
8497 }
8498
8499
8500 /*!
8501  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8502  * valid cases.
8503  * 1.  The arrays have same number of tuples and components. Then each value of
8504  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8505  *   _a_ [ i, j ] *= _other_ [ i, j ].
8506  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8507  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8508  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8509  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8510  *
8511  *  \param [in] other - an array to multiply to \a this one.
8512  *  \throw If \a other is NULL.
8513  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8514  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8515  *         \a other has number of both tuples and components not equal to 1.
8516  */
8517 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8518 {
8519   if(!other)
8520     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8521   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8522   checkAllocated(); other->checkAllocated();
8523   int nbOfTuple=getNumberOfTuples();
8524   int nbOfTuple2=other->getNumberOfTuples();
8525   int nbOfComp=getNumberOfComponents();
8526   int nbOfComp2=other->getNumberOfComponents();
8527   if(nbOfTuple==nbOfTuple2)
8528     {
8529       if(nbOfComp==nbOfComp2)
8530         {
8531           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8532         }
8533       else if(nbOfComp2==1)
8534         {
8535           int *ptr=getPointer();
8536           const int *ptrc=other->getConstPointer();
8537           for(int i=0;i<nbOfTuple;i++)
8538             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8539         }
8540       else
8541         throw INTERP_KERNEL::Exception(msg);
8542     }
8543   else if(nbOfTuple2==1)
8544     {
8545       if(nbOfComp2==nbOfComp)
8546         {
8547           int *ptr=getPointer();
8548           const int *ptrc=other->getConstPointer();
8549           for(int i=0;i<nbOfTuple;i++)
8550             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8551         }
8552       else
8553         throw INTERP_KERNEL::Exception(msg);
8554     }
8555   else
8556     throw INTERP_KERNEL::Exception(msg);
8557   declareAsNew();
8558 }
8559
8560
8561 /*!
8562  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8563  * valid cases.
8564  * 1.  The arrays have same number of tuples and components. Then each value of
8565  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8566  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8567  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8568  *   component. Then
8569  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8570  * 3.  The arrays have same number of components and one array, say _a2_, has one
8571  *   tuple. Then
8572  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8573  *
8574  * Info on components is copied either from the first array (in the first case) or from
8575  * the array with maximal number of elements (getNbOfElems()).
8576  *  \warning No check of division by zero is performed!
8577  *  \param [in] a1 - a numerator array.
8578  *  \param [in] a2 - a denominator array.
8579  *  \return DataArrayInt * - the new instance of DataArrayInt.
8580  *          The caller is to delete this result array using decrRef() as it is no more
8581  *          needed.
8582  *  \throw If either \a a1 or \a a2 is NULL.
8583  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8584  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8585  *         none of them has number of tuples or components equal to 1.
8586  */
8587 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8588 {
8589   if(!a1 || !a2)
8590     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8591   int nbOfTuple1=a1->getNumberOfTuples();
8592   int nbOfTuple2=a2->getNumberOfTuples();
8593   int nbOfComp1=a1->getNumberOfComponents();
8594   int nbOfComp2=a2->getNumberOfComponents();
8595   if(nbOfTuple2==nbOfTuple1)
8596     {
8597       if(nbOfComp1==nbOfComp2)
8598         {
8599           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8600           ret->alloc(nbOfTuple2,nbOfComp1);
8601           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8602           ret->copyStringInfoFrom(*a1);
8603           return ret.retn();
8604         }
8605       else if(nbOfComp2==1)
8606         {
8607           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8608           ret->alloc(nbOfTuple1,nbOfComp1);
8609           const int *a2Ptr=a2->getConstPointer();
8610           const int *a1Ptr=a1->getConstPointer();
8611           int *res=ret->getPointer();
8612           for(int i=0;i<nbOfTuple1;i++)
8613             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8614           ret->copyStringInfoFrom(*a1);
8615           return ret.retn();
8616         }
8617       else
8618         {
8619           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8620           return 0;
8621         }
8622     }
8623   else if(nbOfTuple2==1)
8624     {
8625       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8626       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8627       ret->alloc(nbOfTuple1,nbOfComp1);
8628       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8629       int *pt=ret->getPointer();
8630       for(int i=0;i<nbOfTuple1;i++)
8631         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8632       ret->copyStringInfoFrom(*a1);
8633       return ret.retn();
8634     }
8635   else
8636     {
8637       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8638       return 0;
8639     }
8640 }
8641
8642 /*!
8643  * Divide values of \a this array by values of another DataArrayInt. There are 3
8644  * valid cases.
8645  * 1.  The arrays have same number of tuples and components. Then each value of
8646  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8647  *   _a_ [ i, j ] /= _other_ [ i, j ].
8648  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8649  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8650  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8651  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8652  *
8653  *  \warning No check of division by zero is performed!
8654  *  \param [in] other - an array to divide \a this one by.
8655  *  \throw If \a other is NULL.
8656  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8657  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8658  *         \a other has number of both tuples and components not equal to 1.
8659  */
8660 void DataArrayInt::divideEqual(const DataArrayInt *other)
8661 {
8662   if(!other)
8663     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8664   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8665   checkAllocated(); other->checkAllocated();
8666   int nbOfTuple=getNumberOfTuples();
8667   int nbOfTuple2=other->getNumberOfTuples();
8668   int nbOfComp=getNumberOfComponents();
8669   int nbOfComp2=other->getNumberOfComponents();
8670   if(nbOfTuple==nbOfTuple2)
8671     {
8672       if(nbOfComp==nbOfComp2)
8673         {
8674           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8675         }
8676       else if(nbOfComp2==1)
8677         {
8678           int *ptr=getPointer();
8679           const int *ptrc=other->getConstPointer();
8680           for(int i=0;i<nbOfTuple;i++)
8681             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8682         }
8683       else
8684         throw INTERP_KERNEL::Exception(msg);
8685     }
8686   else if(nbOfTuple2==1)
8687     {
8688       if(nbOfComp2==nbOfComp)
8689         {
8690           int *ptr=getPointer();
8691           const int *ptrc=other->getConstPointer();
8692           for(int i=0;i<nbOfTuple;i++)
8693             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8694         }
8695       else
8696         throw INTERP_KERNEL::Exception(msg);
8697     }
8698   else
8699     throw INTERP_KERNEL::Exception(msg);
8700   declareAsNew();
8701 }
8702
8703
8704 /*!
8705  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8706  * valid cases.
8707  * 1.  The arrays have same number of tuples and components. Then each value of
8708  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8709  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8710  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8711  *   component. Then
8712  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8713  * 3.  The arrays have same number of components and one array, say _a2_, has one
8714  *   tuple. Then
8715  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8716  *
8717  * Info on components is copied either from the first array (in the first case) or from
8718  * the array with maximal number of elements (getNbOfElems()).
8719  *  \warning No check of division by zero is performed!
8720  *  \param [in] a1 - a dividend array.
8721  *  \param [in] a2 - a divisor array.
8722  *  \return DataArrayInt * - the new instance of DataArrayInt.
8723  *          The caller is to delete this result array using decrRef() as it is no more
8724  *          needed.
8725  *  \throw If either \a a1 or \a a2 is NULL.
8726  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8727  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8728  *         none of them has number of tuples or components equal to 1.
8729  */
8730 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8731 {
8732   if(!a1 || !a2)
8733     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8734   int nbOfTuple1=a1->getNumberOfTuples();
8735   int nbOfTuple2=a2->getNumberOfTuples();
8736   int nbOfComp1=a1->getNumberOfComponents();
8737   int nbOfComp2=a2->getNumberOfComponents();
8738   if(nbOfTuple2==nbOfTuple1)
8739     {
8740       if(nbOfComp1==nbOfComp2)
8741         {
8742           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8743           ret->alloc(nbOfTuple2,nbOfComp1);
8744           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8745           ret->copyStringInfoFrom(*a1);
8746           return ret.retn();
8747         }
8748       else if(nbOfComp2==1)
8749         {
8750           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8751           ret->alloc(nbOfTuple1,nbOfComp1);
8752           const int *a2Ptr=a2->getConstPointer();
8753           const int *a1Ptr=a1->getConstPointer();
8754           int *res=ret->getPointer();
8755           for(int i=0;i<nbOfTuple1;i++)
8756             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8757           ret->copyStringInfoFrom(*a1);
8758           return ret.retn();
8759         }
8760       else
8761         {
8762           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8763           return 0;
8764         }
8765     }
8766   else if(nbOfTuple2==1)
8767     {
8768       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8769       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8770       ret->alloc(nbOfTuple1,nbOfComp1);
8771       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8772       int *pt=ret->getPointer();
8773       for(int i=0;i<nbOfTuple1;i++)
8774         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8775       ret->copyStringInfoFrom(*a1);
8776       return ret.retn();
8777     }
8778   else
8779     {
8780       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8781       return 0;
8782     }
8783 }
8784
8785 /*!
8786  * Modify \a this array so that each value becomes a modulus of division of this value by
8787  * a value of another DataArrayInt. There are 3 valid cases.
8788  * 1.  The arrays have same number of tuples and components. Then each value of
8789  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8790  *   _a_ [ i, j ] %= _other_ [ i, j ].
8791  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8792  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8793  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8794  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8795  *
8796  *  \warning No check of division by zero is performed!
8797  *  \param [in] other - a divisor array.
8798  *  \throw If \a other is NULL.
8799  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8800  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8801  *         \a other has number of both tuples and components not equal to 1.
8802  */
8803 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8804 {
8805   if(!other)
8806     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8807   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8808   checkAllocated(); other->checkAllocated();
8809   int nbOfTuple=getNumberOfTuples();
8810   int nbOfTuple2=other->getNumberOfTuples();
8811   int nbOfComp=getNumberOfComponents();
8812   int nbOfComp2=other->getNumberOfComponents();
8813   if(nbOfTuple==nbOfTuple2)
8814     {
8815       if(nbOfComp==nbOfComp2)
8816         {
8817           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8818         }
8819       else if(nbOfComp2==1)
8820         {
8821           if(nbOfComp2==nbOfComp)
8822             {
8823               int *ptr=getPointer();
8824               const int *ptrc=other->getConstPointer();
8825               for(int i=0;i<nbOfTuple;i++)
8826                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8827             }
8828           else
8829             throw INTERP_KERNEL::Exception(msg);
8830         }
8831       else
8832         throw INTERP_KERNEL::Exception(msg);
8833     }
8834   else if(nbOfTuple2==1)
8835     {
8836       int *ptr=getPointer();
8837       const int *ptrc=other->getConstPointer();
8838       for(int i=0;i<nbOfTuple;i++)
8839         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8840     }
8841   else
8842     throw INTERP_KERNEL::Exception(msg);
8843   declareAsNew();
8844 }
8845
8846 /*!
8847  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8848  * valid cases.
8849  *
8850  *  \param [in] a1 - an array to pow up.
8851  *  \param [in] a2 - another array to sum up.
8852  *  \return DataArrayInt * - the new instance of DataArrayInt.
8853  *          The caller is to delete this result array using decrRef() as it is no more
8854  *          needed.
8855  *  \throw If either \a a1 or \a a2 is NULL.
8856  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8857  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8858  *  \throw If there is a negative value in \a a2.
8859  */
8860 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8861 {
8862   if(!a1 || !a2)
8863     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8864   int nbOfTuple=a1->getNumberOfTuples();
8865   int nbOfTuple2=a2->getNumberOfTuples();
8866   int nbOfComp=a1->getNumberOfComponents();
8867   int nbOfComp2=a2->getNumberOfComponents();
8868   if(nbOfTuple!=nbOfTuple2)
8869     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8870   if(nbOfComp!=1 || nbOfComp2!=1)
8871     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8872   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8873   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8874   int *ptr=ret->getPointer();
8875   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8876     {
8877       if(*ptr2>=0)
8878         {
8879           int tmp=1;
8880           for(int j=0;j<*ptr2;j++)
8881             tmp*=*ptr1;
8882           *ptr=tmp;
8883         }
8884       else
8885         {
8886           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8887           throw INTERP_KERNEL::Exception(oss.str().c_str());
8888         }
8889     }
8890   return ret.retn();
8891 }
8892
8893 /*!
8894  * Apply pow on values of another DataArrayInt to values of \a this one.
8895  *
8896  *  \param [in] other - an array to pow to \a this one.
8897  *  \throw If \a other is NULL.
8898  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8899  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8900  *  \throw If there is a negative value in \a other.
8901  */
8902 void DataArrayInt::powEqual(const DataArrayInt *other)
8903 {
8904   if(!other)
8905     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8906   int nbOfTuple=getNumberOfTuples();
8907   int nbOfTuple2=other->getNumberOfTuples();
8908   int nbOfComp=getNumberOfComponents();
8909   int nbOfComp2=other->getNumberOfComponents();
8910   if(nbOfTuple!=nbOfTuple2)
8911     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8912   if(nbOfComp!=1 || nbOfComp2!=1)
8913     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8914   int *ptr=getPointer();
8915   const int *ptrc=other->begin();
8916   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8917     {
8918       if(*ptrc>=0)
8919         {
8920           int tmp=1;
8921           for(int j=0;j<*ptrc;j++)
8922             tmp*=*ptr;
8923           *ptr=tmp;
8924         }
8925       else
8926         {
8927           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8928           throw INTERP_KERNEL::Exception(oss.str().c_str());
8929         }
8930     }
8931   declareAsNew();
8932 }
8933
8934 /*!
8935  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8936  * This map, if applied to \a start array, would make it sorted. For example, if
8937  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8938  * [5,6,0,3,2,7,1,4].
8939  *  \param [in] start - pointer to the first element of the array for which the
8940  *         permutation map is computed.
8941  *  \param [in] end - pointer specifying the end of the array \a start, so that
8942  *         the last value of \a start is \a end[ -1 ].
8943  *  \return int * - the result permutation array that the caller is to delete as it is no
8944  *         more needed.
8945  *  \throw If there are equal values in the input array.
8946  */
8947 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
8948 {
8949   std::size_t sz=std::distance(start,end);
8950   int *ret=(int *)malloc(sz*sizeof(int));
8951   int *work=new int[sz];
8952   std::copy(start,end,work);
8953   std::sort(work,work+sz);
8954   if(std::unique(work,work+sz)!=work+sz)
8955     {
8956       delete [] work;
8957       free(ret);
8958       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
8959     }
8960   std::map<int,int> m;
8961   for(int *workPt=work;workPt!=work+sz;workPt++)
8962     m[*workPt]=(int)std::distance(work,workPt);
8963   int *iter2=ret;
8964   for(const int *iter=start;iter!=end;iter++,iter2++)
8965     *iter2=m[*iter];
8966   delete [] work;
8967   return ret;
8968 }
8969
8970 /*!
8971  * Returns a new DataArrayInt containing an arithmetic progression
8972  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
8973  * function.
8974  *  \param [in] begin - the start value of the result sequence.
8975  *  \param [in] end - limiting value, so that every value of the result array is less than
8976  *              \a end.
8977  *  \param [in] step - specifies the increment or decrement.
8978  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8979  *          array using decrRef() as it is no more needed.
8980  *  \throw If \a step == 0.
8981  *  \throw If \a end < \a begin && \a step > 0.
8982  *  \throw If \a end > \a begin && \a step < 0.
8983  */
8984 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
8985 {
8986   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
8987   MCAuto<DataArrayInt> ret=DataArrayInt::New();
8988   ret->alloc(nbOfTuples,1);
8989   int *ptr=ret->getPointer();
8990   if(step>0)
8991     {
8992       for(int i=begin;i<end;i+=step,ptr++)
8993         *ptr=i;
8994     }
8995   else
8996     {
8997       for(int i=begin;i>end;i+=step,ptr++)
8998         *ptr=i;
8999     }
9000   return ret.retn();
9001 }
9002
9003 /*!
9004  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9005  * Server side.
9006  */
9007 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9008 {
9009   tinyInfo.resize(2);
9010   if(isAllocated())
9011     {
9012       tinyInfo[0]=getNumberOfTuples();
9013       tinyInfo[1]=getNumberOfComponents();
9014     }
9015   else
9016     {
9017       tinyInfo[0]=-1;
9018       tinyInfo[1]=-1;
9019     }
9020 }
9021
9022 /*!
9023  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9024  * Server side.
9025  */
9026 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9027 {
9028   if(isAllocated())
9029     {
9030       int nbOfCompo=getNumberOfComponents();
9031       tinyInfo.resize(nbOfCompo+1);
9032       tinyInfo[0]=getName();
9033       for(int i=0;i<nbOfCompo;i++)
9034         tinyInfo[i+1]=getInfoOnComponent(i);
9035     }
9036   else
9037     {
9038       tinyInfo.resize(1);
9039       tinyInfo[0]=getName();
9040     }
9041 }
9042
9043 /*!
9044  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9045  * This method returns if a feeding is needed.
9046  */
9047 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9048 {
9049   int nbOfTuple=tinyInfoI[0];
9050   int nbOfComp=tinyInfoI[1];
9051   if(nbOfTuple!=-1 || nbOfComp!=-1)
9052     {
9053       alloc(nbOfTuple,nbOfComp);
9054       return true;
9055     }
9056   return false;
9057 }
9058
9059 /*!
9060  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9061  * This method returns if a feeding is needed.
9062  */
9063 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9064 {
9065   setName(tinyInfoS[0]);
9066   if(isAllocated())
9067     {
9068       int nbOfCompo=tinyInfoI[1];
9069       for(int i=0;i<nbOfCompo;i++)
9070         setInfoOnComponent(i,tinyInfoS[i+1]);
9071     }
9072 }
9073
9074 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9075 {
9076   if(_da)
9077     {
9078       _da->incrRef();
9079       if(_da->isAllocated())
9080         {
9081           _nb_comp=da->getNumberOfComponents();
9082           _nb_tuple=da->getNumberOfTuples();
9083           _pt=da->getPointer();
9084         }
9085     }
9086 }
9087
9088 DataArrayIntIterator::~DataArrayIntIterator()
9089 {
9090   if(_da)
9091     _da->decrRef();
9092 }
9093
9094 DataArrayIntTuple *DataArrayIntIterator::nextt()
9095 {
9096   if(_tuple_id<_nb_tuple)
9097     {
9098       _tuple_id++;
9099       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9100       _pt+=_nb_comp;
9101       return ret;
9102     }
9103   else
9104     return 0;
9105 }
9106
9107 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9108 {
9109 }
9110
9111 std::string DataArrayIntTuple::repr() const
9112 {
9113   std::ostringstream oss; oss << "(";
9114   for(int i=0;i<_nb_of_compo-1;i++)
9115     oss << _pt[i] << ", ";
9116   oss << _pt[_nb_of_compo-1] << ")";
9117   return oss.str();
9118 }
9119
9120 int DataArrayIntTuple::intValue() const
9121 {
9122   if(_nb_of_compo==1)
9123     return *_pt;
9124   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9125 }
9126
9127 /*!
9128  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9129  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9130  * 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
9131  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9132  */
9133 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9134 {
9135   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9136     {
9137       DataArrayInt *ret=DataArrayInt::New();
9138       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9139       return ret;
9140     }
9141   else
9142     {
9143       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9144       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9145       throw INTERP_KERNEL::Exception(oss.str().c_str());
9146     }
9147 }