Salome HOME
DataArrayInt.indicesOfSubPart useful method
[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 /*!
5624  * Elements of \a partOfThis are expected to be included in \a this.
5625  * The returned array \a ret is so that this[ret]==partOfThis
5626  *
5627  * For example, if \a this array contents are [9,10,0,6,4,11,3,8] and if \a partOfThis contains [6,0,11,8]
5628  * the return array will contain [3,2,5,7].
5629  *
5630  * \a this is expected to be a 1 compo allocated array.
5631  * \param [in] partOfThis - A 1 compo allocated array
5632  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5633  * \throw if two same element is present twice in \a this
5634  * \throw if an element in \a partOfThis is \b NOT in \a this.
5635  */
5636 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5637 {
5638   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5639     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5640   checkAllocated(); partOfThis.checkAllocated();
5641   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5642   const int *thisPt(begin()),*pt(partOfThis.begin());
5643   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5644   ret->alloc(nbTuples,1);
5645   int *retPt(ret->getPointer());
5646   std::map<int,int> m;
5647   for(int i=0;i<thisNbTuples;i++,thisPt++)
5648     m[*thisPt]=i;
5649   if(m.size()!=thisNbTuples)
5650     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5651   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5652     {
5653       std::map<int,int>::const_iterator it(m.find(*pt));
5654       if(it!=m.end())
5655         *retPt=(*it).second;
5656       else
5657         {
5658           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5659           throw INTERP_KERNEL::Exception(oss.str());
5660         }
5661     }
5662   return ret.retn();
5663 }
5664
5665 void DataArrayInt::aggregate(const DataArrayInt *other)
5666 {
5667   if(!other)
5668     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5669   if(getNumberOfComponents()!=other->getNumberOfComponents())
5670     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5671   _mem.insertAtTheEnd(other->begin(),other->end());
5672 }
5673
5674 /*!
5675  * Returns a new DataArrayInt holding the same values as \a this array but differently
5676  * arranged in memory. If \a this array holds 2 components of 3 values:
5677  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5678  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5679  *  \warning Do not confuse this method with transpose()!
5680  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5681  *          is to delete using decrRef() as it is no more needed.
5682  *  \throw If \a this is not allocated.
5683  */
5684 DataArrayInt *DataArrayInt::fromNoInterlace() const
5685 {
5686   checkAllocated();
5687   if(_mem.isNull())
5688     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5689   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5690   DataArrayInt *ret=DataArrayInt::New();
5691   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5692   return ret;
5693 }
5694
5695 /*!
5696  * Returns a new DataArrayInt holding the same values as \a this array but differently
5697  * arranged in memory. If \a this array holds 2 components of 3 values:
5698  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5699  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5700  *  \warning Do not confuse this method with transpose()!
5701  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5702  *          is to delete using decrRef() as it is no more needed.
5703  *  \throw If \a this is not allocated.
5704  */
5705 DataArrayInt *DataArrayInt::toNoInterlace() const
5706 {
5707   checkAllocated();
5708   if(_mem.isNull())
5709     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5710   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5711   DataArrayInt *ret=DataArrayInt::New();
5712   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5713   return ret;
5714 }
5715
5716 /*!
5717  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5718  * This map, if applied to \a this array, would make it sorted. For example, if
5719  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5720  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5721  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5722  * This method is useful for renumbering (in MED file for example). For more info
5723  * on renumbering see \ref numbering.
5724  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5725  *          array using decrRef() as it is no more needed.
5726  *  \throw If \a this is not allocated.
5727  *  \throw If \a this->getNumberOfComponents() != 1.
5728  *  \throw If there are equal values in \a this array.
5729  */
5730 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5731 {
5732   checkAllocated();
5733   if(getNumberOfComponents()!=1)
5734     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5735   int nbTuples=getNumberOfTuples();
5736   const int *pt=getConstPointer();
5737   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5738   DataArrayInt *ret=DataArrayInt::New();
5739   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5740   return ret;
5741 }
5742
5743 /*!
5744  * 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
5745  * input array \a ids2.
5746  * \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.
5747  * 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
5748  * inversely.
5749  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5750  *
5751  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5752  *          array using decrRef() as it is no more needed.
5753  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5754  * 
5755  */
5756 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5757 {
5758   if(!ids1 || !ids2)
5759     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5760   if(!ids1->isAllocated() || !ids2->isAllocated())
5761     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5762   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5763     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5764   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5765     {
5766       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 !";
5767       throw INTERP_KERNEL::Exception(oss.str().c_str());
5768     }
5769   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5770   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5771   p1->sort(true); p2->sort(true);
5772   if(!p1->isEqualWithoutConsideringStr(*p2))
5773     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5774   p1=ids1->checkAndPreparePermutation();
5775   p2=ids2->checkAndPreparePermutation();
5776   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5777   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5778   return p2.retn();
5779 }
5780
5781 /*!
5782  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5783  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5784  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5785  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5786  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5787  * The first of out arrays returns indices of elements of \a this array, grouped by their
5788  * place in the set \a B. The second out array is the index of the first one; it shows how
5789  * many elements of \a A are mapped into each element of \a B. <br>
5790  * For more info on
5791  * mapping and its usage in renumbering see \ref numbering. <br>
5792  * \b Example:
5793  * - \a this: [0,3,2,3,2,2,1,2]
5794  * - \a targetNb: 4
5795  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5796  * - \a arrI: [0,1,2,6,8]
5797  *
5798  * This result means: <br>
5799  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5800  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5801  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5802  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5803  * \a arrI[ 2+1 ]]); <br> etc.
5804  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5805  *         than the maximal value of \a A.
5806  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5807  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5808  *         this array using decrRef() as it is no more needed.
5809  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5810  *         elements of \a this. The caller is to delete this array using decrRef() as it
5811  *         is no more needed.
5812  *  \throw If \a this is not allocated.
5813  *  \throw If \a this->getNumberOfComponents() != 1.
5814  *  \throw If any value in \a this is more or equal to \a targetNb.
5815  */
5816 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5817 {
5818   checkAllocated();
5819   if(getNumberOfComponents()!=1)
5820     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5821   int nbOfTuples=getNumberOfTuples();
5822   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5823   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5824   retI->alloc(targetNb+1,1);
5825   const int *input=getConstPointer();
5826   std::vector< std::vector<int> > tmp(targetNb);
5827   for(int i=0;i<nbOfTuples;i++)
5828     {
5829       int tmp2=input[i];
5830       if(tmp2>=0 && tmp2<targetNb)
5831         tmp[tmp2].push_back(i);
5832       else
5833         {
5834           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5835           throw INTERP_KERNEL::Exception(oss.str().c_str());
5836         }
5837     }
5838   int *retIPtr=retI->getPointer();
5839   *retIPtr=0;
5840   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5841     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5842   if(nbOfTuples!=retI->getIJ(targetNb,0))
5843     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5844   ret->alloc(nbOfTuples,1);
5845   int *retPtr=ret->getPointer();
5846   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5847     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5848   arr=ret.retn();
5849   arrI=retI.retn();
5850 }
5851
5852
5853 /*!
5854  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5855  * from a zip representation of a surjective format (returned e.g. by
5856  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5857  * for example). The result array minimizes the permutation. <br>
5858  * For more info on renumbering see \ref numbering. <br>
5859  * \b Example: <br>
5860  * - \a nbOfOldTuples: 10 
5861  * - \a arr          : [0,3, 5,7,9]
5862  * - \a arrIBg       : [0,2,5]
5863  * - \a newNbOfTuples: 7
5864  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5865  *
5866  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5867  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5868  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5869  *         (indices of) equal values. Its every element (except the last one) points to
5870  *         the first element of a group of equal values.
5871  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5872  *          arrIBg is \a arrIEnd[ -1 ].
5873  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5874  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5875  *          array using decrRef() as it is no more needed.
5876  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5877  */
5878 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5879 {
5880   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5881   ret->alloc(nbOfOldTuples,1);
5882   int *pt=ret->getPointer();
5883   std::fill(pt,pt+nbOfOldTuples,-1);
5884   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5885   const int *cIPtr=arrIBg;
5886   for(int i=0;i<nbOfGrps;i++)
5887     pt[arr[cIPtr[i]]]=-(i+2);
5888   int newNb=0;
5889   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5890     {
5891       if(pt[iNode]<0)
5892         {
5893           if(pt[iNode]==-1)
5894             pt[iNode]=newNb++;
5895           else
5896             {
5897               int grpId=-(pt[iNode]+2);
5898               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5899                 {
5900                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5901                     pt[arr[j]]=newNb;
5902                   else
5903                     {
5904                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5905                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5906                     }
5907                 }
5908               newNb++;
5909             }
5910         }
5911     }
5912   newNbOfTuples=newNb;
5913   return ret.retn();
5914 }
5915
5916 /*!
5917  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5918  * which if applied to \a this array would make it sorted ascendingly.
5919  * For more info on renumbering see \ref numbering. <br>
5920  * \b Example: <br>
5921  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5922  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5923  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5924  *
5925  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5926  *          array using decrRef() as it is no more needed.
5927  *  \throw If \a this is not allocated.
5928  *  \throw If \a this->getNumberOfComponents() != 1.
5929  */
5930 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5931 {
5932   checkAllocated();
5933   if(getNumberOfComponents()!=1)
5934     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5935   int nbOfTuples=getNumberOfTuples();
5936   const int *pt=getConstPointer();
5937   std::map<int,int> m;
5938   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5939   ret->alloc(nbOfTuples,1);
5940   int *opt=ret->getPointer();
5941   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5942     {
5943       int val=*pt;
5944       std::map<int,int>::iterator it=m.find(val);
5945       if(it!=m.end())
5946         {
5947           *opt=(*it).second;
5948           (*it).second++;
5949         }
5950       else
5951         {
5952           *opt=0;
5953           m.insert(std::pair<int,int>(val,1));
5954         }
5955     }
5956   int sum=0;
5957   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5958     {
5959       int vt=(*it).second;
5960       (*it).second=sum;
5961       sum+=vt;
5962     }
5963   pt=getConstPointer();
5964   opt=ret->getPointer();
5965   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5966     *opt+=m[*pt];
5967   //
5968   return ret.retn();
5969 }
5970
5971 /*!
5972  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5973  * iota(). This method is particularly useful for DataArrayInt instances that represent
5974  * a renumbering array, to check if there is a real need in renumbering.
5975  * This method checks than \a this can be considered as an identity mapping
5976  * of a set having \a sizeExpected elements into itself.
5977  *
5978  *  \param [in] sizeExpected - The number of elements expected.
5979  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5980  *  \throw If \a this is not allocated.
5981  *  \throw If \a this->getNumberOfComponents() != 1.
5982  */
5983 bool DataArrayInt::isIota(int sizeExpected) const
5984 {
5985   checkAllocated();
5986   if(getNumberOfComponents()!=1)
5987     return false;
5988   int nbOfTuples(getNumberOfTuples());
5989   if(nbOfTuples!=sizeExpected)
5990     return false;
5991   const int *pt=getConstPointer();
5992   for(int i=0;i<nbOfTuples;i++,pt++)
5993     if(*pt!=i)
5994       return false;
5995   return true;
5996 }
5997
5998 /*!
5999  * Checks if all values in \a this array are equal to \a val.
6000  *  \param [in] val - value to check equality of array values to.
6001  *  \return bool - \a true if all values are \a val.
6002  *  \throw If \a this is not allocated.
6003  *  \throw If \a this->getNumberOfComponents() != 1
6004  */
6005 bool DataArrayInt::isUniform(int val) const
6006 {
6007   checkAllocated();
6008   if(getNumberOfComponents()!=1)
6009     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6010   int nbOfTuples=getNumberOfTuples();
6011   const int *w=getConstPointer();
6012   const int *end2=w+nbOfTuples;
6013   for(;w!=end2;w++)
6014     if(*w!=val)
6015       return false;
6016   return true;
6017 }
6018
6019 /*!
6020  * Checks if all values in \a this array are unique.
6021  *  \return bool - \a true if condition above is true
6022  *  \throw If \a this is not allocated.
6023  *  \throw If \a this->getNumberOfComponents() != 1
6024  */
6025 bool DataArrayInt::hasUniqueValues() const
6026 {
6027   checkAllocated();
6028   if(getNumberOfComponents()!=1)
6029     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6030   int nbOfTuples(getNumberOfTuples());
6031   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
6032   if (s.size() != nbOfTuples)
6033     return false;
6034   return true;
6035 }
6036
6037 /*!
6038  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6039  * array to the new one.
6040  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6041  */
6042 DataArrayDouble *DataArrayInt::convertToDblArr() const
6043 {
6044   checkAllocated();
6045   DataArrayDouble *ret=DataArrayDouble::New();
6046   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6047   std::size_t nbOfVals=getNbOfElems();
6048   const int *src=getConstPointer();
6049   double *dest=ret->getPointer();
6050   std::copy(src,src+nbOfVals,dest);
6051   ret->copyStringInfoFrom(*this);
6052   return ret;
6053 }
6054
6055 /*!
6056  * Appends components of another array to components of \a this one, tuple by tuple.
6057  * So that the number of tuples of \a this array remains the same and the number of 
6058  * components increases.
6059  *  \param [in] other - the DataArrayInt to append to \a this one.
6060  *  \throw If \a this is not allocated.
6061  *  \throw If \a this and \a other arrays have different number of tuples.
6062  *
6063  *  \if ENABLE_EXAMPLES
6064  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6065  *
6066  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6067  *  \endif
6068  */
6069 void DataArrayInt::meldWith(const DataArrayInt *other)
6070 {
6071   if(!other)
6072     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6073   checkAllocated();
6074   other->checkAllocated();
6075   int nbOfTuples=getNumberOfTuples();
6076   if(nbOfTuples!=other->getNumberOfTuples())
6077     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6078   int nbOfComp1=getNumberOfComponents();
6079   int nbOfComp2=other->getNumberOfComponents();
6080   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6081   int *w=newArr;
6082   const int *inp1=getConstPointer();
6083   const int *inp2=other->getConstPointer();
6084   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6085     {
6086       w=std::copy(inp1,inp1+nbOfComp1,w);
6087       w=std::copy(inp2,inp2+nbOfComp2,w);
6088     }
6089   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6090   std::vector<int> compIds(nbOfComp2);
6091   for(int i=0;i<nbOfComp2;i++)
6092     compIds[i]=nbOfComp1+i;
6093   copyPartOfStringInfoFrom2(compIds,*other);
6094 }
6095
6096 /*!
6097  * Copy all components in a specified order from another DataArrayInt.
6098  * The specified components become the first ones in \a this array.
6099  * Both numerical and textual data is copied. The number of tuples in \a this and
6100  * the other array can be different.
6101  *  \param [in] a - the array to copy data from.
6102  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6103  *              to be copied.
6104  *  \throw If \a a is NULL.
6105  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6106  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6107  *
6108  *  \if ENABLE_EXAMPLES
6109  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6110  *  \endif
6111  */
6112 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6113 {
6114   if(!a)
6115     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6116   checkAllocated();
6117   a->checkAllocated();
6118   copyPartOfStringInfoFrom2(compoIds,*a);
6119   std::size_t partOfCompoSz=compoIds.size();
6120   int nbOfCompo=getNumberOfComponents();
6121   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6122   const int *ac=a->getConstPointer();
6123   int *nc=getPointer();
6124   for(int i=0;i<nbOfTuples;i++)
6125     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6126       nc[nbOfCompo*i+compoIds[j]]=*ac;
6127 }
6128
6129 /*!
6130  * Assign pointer to one array to a pointer to another appay. Reference counter of
6131  * \a arrayToSet is incremented / decremented.
6132  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6133  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6134  */
6135 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6136 {
6137   if(newArray!=arrayToSet)
6138     {
6139       if(arrayToSet)
6140         arrayToSet->decrRef();
6141       arrayToSet=newArray;
6142       if(arrayToSet)
6143         arrayToSet->incrRef();
6144     }
6145 }
6146
6147 DataArrayIntIterator *DataArrayInt::iterator()
6148 {
6149   return new DataArrayIntIterator(this);
6150 }
6151
6152 /*!
6153  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6154  * given one. The ids are sorted in the ascending order.
6155  *  \param [in] val - the value to find within \a this.
6156  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6157  *          array using decrRef() as it is no more needed.
6158  *  \throw If \a this is not allocated.
6159  *  \throw If \a this->getNumberOfComponents() != 1.
6160  *  \sa DataArrayInt::findIdsEqualTuple
6161  */
6162 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6163 {
6164   checkAllocated();
6165   if(getNumberOfComponents()!=1)
6166     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6167   const int *cptr(getConstPointer());
6168   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6169   int nbOfTuples=getNumberOfTuples();
6170   for(int i=0;i<nbOfTuples;i++,cptr++)
6171     if(*cptr==val)
6172       ret->pushBackSilent(i);
6173   return ret.retn();
6174 }
6175
6176 /*!
6177  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6178  * equal to a given one. 
6179  *  \param [in] val - the value to ignore within \a this.
6180  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6181  *          array using decrRef() as it is no more needed.
6182  *  \throw If \a this is not allocated.
6183  *  \throw If \a this->getNumberOfComponents() != 1.
6184  */
6185 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6186 {
6187   checkAllocated();
6188   if(getNumberOfComponents()!=1)
6189     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6190   const int *cptr(getConstPointer());
6191   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6192   int nbOfTuples=getNumberOfTuples();
6193   for(int i=0;i<nbOfTuples;i++,cptr++)
6194     if(*cptr!=val)
6195       ret->pushBackSilent(i);
6196   return ret.retn();
6197 }
6198
6199 /*!
6200  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6201  * This method is an extension of  DataArrayInt::findIdsEqual method.
6202  *
6203  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6204  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6205  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6206  *          array using decrRef() as it is no more needed.
6207  *  \throw If \a this is not allocated.
6208  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6209  * \throw If \a this->getNumberOfComponents() is equal to 0.
6210  * \sa DataArrayInt::findIdsEqual
6211  */
6212 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6213 {
6214   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6215   checkAllocated();
6216   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6217     {
6218       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6219       throw INTERP_KERNEL::Exception(oss.str().c_str());
6220     }
6221   if(nbOfCompoExp==0)
6222     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6223   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6224   const int *bg(begin()),*end2(end()),*work(begin());
6225   while(work!=end2)
6226     {
6227       work=std::search(work,end2,tupleBg,tupleEnd);
6228       if(work!=end2)
6229         {
6230           std::size_t pos(std::distance(bg,work));
6231           if(pos%nbOfCompoExp==0)
6232             ret->pushBackSilent(pos/nbOfCompoExp);
6233           work++;
6234         }
6235     }
6236   return ret.retn();
6237 }
6238
6239 /*!
6240  * Assigns \a newValue to all elements holding \a oldValue within \a this
6241  * one-dimensional array.
6242  *  \param [in] oldValue - the value to replace.
6243  *  \param [in] newValue - the value to assign.
6244  *  \return int - number of replacements performed.
6245  *  \throw If \a this is not allocated.
6246  *  \throw If \a this->getNumberOfComponents() != 1.
6247  */
6248 int DataArrayInt::changeValue(int oldValue, int newValue)
6249 {
6250   checkAllocated();
6251   if(getNumberOfComponents()!=1)
6252     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6253   if(oldValue==newValue)
6254     return 0;
6255   int *start(getPointer()),*end2(start+getNbOfElems());
6256   int ret(0);
6257   for(int *val=start;val!=end2;val++)
6258     {
6259       if(*val==oldValue)
6260         {
6261           *val=newValue;
6262           ret++;
6263         }
6264     }
6265   if(ret>0)
6266     declareAsNew();
6267   return ret;
6268 }
6269
6270 /*!
6271  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6272  * one of given values.
6273  *  \param [in] valsBg - an array of values to find within \a this array.
6274  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6275  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6276  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6277  *          array using decrRef() as it is no more needed.
6278  *  \throw If \a this->getNumberOfComponents() != 1.
6279  */
6280 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6281 {
6282   if(getNumberOfComponents()!=1)
6283     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6284   std::set<int> vals2(valsBg,valsEnd);
6285   const int *cptr(getConstPointer());
6286   std::vector<int> res;
6287   int nbOfTuples(getNumberOfTuples());
6288   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6289   for(int i=0;i<nbOfTuples;i++,cptr++)
6290     if(vals2.find(*cptr)!=vals2.end())
6291       ret->pushBackSilent(i);
6292   return ret.retn();
6293 }
6294
6295 /*!
6296  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6297  * equal to any of given values.
6298  *  \param [in] valsBg - an array of values to ignore within \a this array.
6299  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6300  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6301  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6302  *          array using decrRef() as it is no more needed.
6303  *  \throw If \a this->getNumberOfComponents() != 1.
6304  */
6305 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6306 {
6307   if(getNumberOfComponents()!=1)
6308     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6309   std::set<int> vals2(valsBg,valsEnd);
6310   const int *cptr=getConstPointer();
6311   std::vector<int> res;
6312   int nbOfTuples=getNumberOfTuples();
6313   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6314   for(int i=0;i<nbOfTuples;i++,cptr++)
6315     if(vals2.find(*cptr)==vals2.end())
6316       ret->pushBackSilent(i);
6317   return ret.retn();
6318 }
6319
6320 /*!
6321  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6322  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6323  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6324  * If any the tuple id is returned. If not -1 is returned.
6325  * 
6326  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6327  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6328  *
6329  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6330  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6331  */
6332 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6333 {
6334   checkAllocated();
6335   int nbOfCompo=getNumberOfComponents();
6336   if(nbOfCompo==0)
6337     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6338   if(nbOfCompo!=(int)tupl.size())
6339     {
6340       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6341       throw INTERP_KERNEL::Exception(oss.str().c_str());
6342     }
6343   const int *cptr=getConstPointer();
6344   std::size_t nbOfVals=getNbOfElems();
6345   for(const int *work=cptr;work!=cptr+nbOfVals;)
6346     {
6347       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6348       if(work!=cptr+nbOfVals)
6349         {
6350           if(std::distance(cptr,work)%nbOfCompo!=0)
6351             work++;
6352           else
6353             return std::distance(cptr,work)/nbOfCompo;
6354         }
6355     }
6356   return -1;
6357 }
6358
6359 /*!
6360  * This method searches the sequence specified in input parameter \b vals in \b this.
6361  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6362  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6363  * \sa DataArrayInt::findIdFirstEqualTuple
6364  */
6365 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6366 {
6367   checkAllocated();
6368   int nbOfCompo=getNumberOfComponents();
6369   if(nbOfCompo!=1)
6370     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6371   const int *cptr=getConstPointer();
6372   std::size_t nbOfVals=getNbOfElems();
6373   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6374   if(loc!=cptr+nbOfVals)
6375     return std::distance(cptr,loc);
6376   return -1;
6377 }
6378
6379 /*!
6380  * This method expects to be called when number of components of this is equal to one.
6381  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6382  * If not any tuple contains \b value -1 is returned.
6383  * \sa DataArrayInt::presenceOfValue
6384  */
6385 int DataArrayInt::findIdFirstEqual(int value) const
6386 {
6387   checkAllocated();
6388   if(getNumberOfComponents()!=1)
6389     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6390   const int *cptr=getConstPointer();
6391   int nbOfTuples=getNumberOfTuples();
6392   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6393   if(ret!=cptr+nbOfTuples)
6394     return std::distance(cptr,ret);
6395   return -1;
6396 }
6397
6398 /*!
6399  * This method expects to be called when number of components of this is equal to one.
6400  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6401  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6402  * \sa DataArrayInt::presenceOfValue
6403  */
6404 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6405 {
6406   checkAllocated();
6407   if(getNumberOfComponents()!=1)
6408     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6409   std::set<int> vals2(vals.begin(),vals.end());
6410   const int *cptr=getConstPointer();
6411   int nbOfTuples=getNumberOfTuples();
6412   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6413     if(vals2.find(*w)!=vals2.end())
6414       return std::distance(cptr,w);
6415   return -1;
6416 }
6417
6418 /*!
6419  * This method returns the number of values in \a this that are equals to input parameter \a value.
6420  * This method only works for single component array.
6421  *
6422  * \return a value in [ 0, \c this->getNumberOfTuples() )
6423  *
6424  * \throw If \a this is not allocated
6425  *
6426  */
6427 int DataArrayInt::count(int value) const
6428 {
6429   int ret=0;
6430   checkAllocated();
6431   if(getNumberOfComponents()!=1)
6432     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6433   const int *vals=begin();
6434   int nbOfTuples=getNumberOfTuples();
6435   for(int i=0;i<nbOfTuples;i++,vals++)
6436     if(*vals==value)
6437       ret++;
6438   return ret;
6439 }
6440
6441 /*!
6442  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6443  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6444  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6445  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6446  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6447  * \sa DataArrayInt::findIdFirstEqualTuple
6448  */
6449 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6450 {
6451   return findIdFirstEqualTuple(tupl)!=-1;
6452 }
6453
6454
6455 /*!
6456  * Returns \a true if a given value is present within \a this one-dimensional array.
6457  *  \param [in] value - the value to find within \a this array.
6458  *  \return bool - \a true in case if \a value is present within \a this array.
6459  *  \throw If \a this is not allocated.
6460  *  \throw If \a this->getNumberOfComponents() != 1.
6461  *  \sa findIdFirstEqual()
6462  */
6463 bool DataArrayInt::presenceOfValue(int value) const
6464 {
6465   return findIdFirstEqual(value)!=-1;
6466 }
6467
6468 /*!
6469  * This method expects to be called when number of components of this is equal to one.
6470  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6471  * If not any tuple contains one of the values contained in 'vals' false is returned.
6472  * \sa DataArrayInt::findIdFirstEqual
6473  */
6474 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6475 {
6476   return findIdFirstEqual(vals)!=-1;
6477 }
6478
6479 /*!
6480  * Accumulates values of each component of \a this array.
6481  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6482  *         by the caller, that is filled by this method with sum value for each
6483  *         component.
6484  *  \throw If \a this is not allocated.
6485  */
6486 void DataArrayInt::accumulate(int *res) const
6487 {
6488   checkAllocated();
6489   const int *ptr=getConstPointer();
6490   int nbTuple=getNumberOfTuples();
6491   int nbComps=getNumberOfComponents();
6492   std::fill(res,res+nbComps,0);
6493   for(int i=0;i<nbTuple;i++)
6494     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6495 }
6496
6497 int DataArrayInt::accumulate(int compId) const
6498 {
6499   checkAllocated();
6500   const int *ptr=getConstPointer();
6501   int nbTuple=getNumberOfTuples();
6502   int nbComps=getNumberOfComponents();
6503   if(compId<0 || compId>=nbComps)
6504     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6505   int ret=0;
6506   for(int i=0;i<nbTuple;i++)
6507     ret+=ptr[i*nbComps+compId];
6508   return ret;
6509 }
6510
6511 /*!
6512  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6513  * The returned array will have same number of components than \a this and number of tuples equal to
6514  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6515  *
6516  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6517  *
6518  * \param [in] bgOfIndex - begin (included) of the input index array.
6519  * \param [in] endOfIndex - end (excluded) of the input index array.
6520  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6521  * 
6522  * \throw If bgOfIndex or end is NULL.
6523  * \throw If input index array is not ascendingly sorted.
6524  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6525  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6526  */
6527 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6528 {
6529   if(!bgOfIndex || !endOfIndex)
6530     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6531   checkAllocated();
6532   int nbCompo=getNumberOfComponents();
6533   int nbOfTuples=getNumberOfTuples();
6534   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6535   if(sz<1)
6536     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6537   sz--;
6538   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6539   const int *w=bgOfIndex;
6540   if(*w<0 || *w>=nbOfTuples)
6541     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6542   const int *srcPt=begin()+(*w)*nbCompo;
6543   int *tmp=ret->getPointer();
6544   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6545     {
6546       std::fill(tmp,tmp+nbCompo,0);
6547       if(w[1]>=w[0])
6548         {
6549           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6550             {
6551               if(j>=0 && j<nbOfTuples)
6552                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6553               else
6554                 {
6555                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6556                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6557                 }
6558             }
6559         }
6560       else
6561         {
6562           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6563           throw INTERP_KERNEL::Exception(oss.str().c_str());
6564         }
6565     }
6566   ret->copyStringInfoFrom(*this);
6567   return ret.retn();
6568 }
6569
6570 /*!
6571  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6572  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6573  * offsetA2</em> and (2)
6574  * the number of component in the result array is same as that of each of given arrays.
6575  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6576  * Info on components is copied from the first of the given arrays. Number of components
6577  * in the given arrays must be the same.
6578  *  \param [in] a1 - an array to include in the result array.
6579  *  \param [in] a2 - another array to include in the result array.
6580  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6581  *  \return DataArrayInt * - the new instance of DataArrayInt.
6582  *          The caller is to delete this result array using decrRef() as it is no more
6583  *          needed.
6584  *  \throw If either \a a1 or \a a2 is NULL.
6585  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6586  */
6587 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6588 {
6589   if(!a1 || !a2)
6590     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6591   int nbOfComp=a1->getNumberOfComponents();
6592   if(nbOfComp!=a2->getNumberOfComponents())
6593     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6594   int nbOfTuple1=a1->getNumberOfTuples();
6595   int nbOfTuple2=a2->getNumberOfTuples();
6596   DataArrayInt *ret=DataArrayInt::New();
6597   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6598   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6599   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6600   ret->copyStringInfoFrom(*a1);
6601   return ret;
6602 }
6603
6604 /*!
6605  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6606  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6607  * the number of component in the result array is same as that of each of given arrays.
6608  * Info on components is copied from the first of the given arrays. Number of components
6609  * in the given arrays must be  the same.
6610  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6611  * not the object itself.
6612  *  \param [in] arr - a sequence of arrays to include in the result array.
6613  *  \return DataArrayInt * - the new instance of DataArrayInt.
6614  *          The caller is to delete this result array using decrRef() as it is no more
6615  *          needed.
6616  *  \throw If all arrays within \a arr are NULL.
6617  *  \throw If getNumberOfComponents() of arrays within \a arr.
6618  */
6619 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6620 {
6621   std::vector<const DataArrayInt *> a;
6622   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6623     if(*it4)
6624       a.push_back(*it4);
6625   if(a.empty())
6626     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6627   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6628   int nbOfComp=(*it)->getNumberOfComponents();
6629   int nbt=(*it++)->getNumberOfTuples();
6630   for(int i=1;it!=a.end();it++,i++)
6631     {
6632       if((*it)->getNumberOfComponents()!=nbOfComp)
6633         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6634       nbt+=(*it)->getNumberOfTuples();
6635     }
6636   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6637   ret->alloc(nbt,nbOfComp);
6638   int *pt=ret->getPointer();
6639   for(it=a.begin();it!=a.end();it++)
6640     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6641   ret->copyStringInfoFrom(*(a[0]));
6642   return ret.retn();
6643 }
6644
6645 /*!
6646  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6647  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6648  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6649  * 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.
6650  * 
6651  * \return DataArrayInt * - a new object to be managed by the caller.
6652  */
6653 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6654 {
6655   int retSz=1;
6656   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6657     {
6658       if(*it4)
6659         {
6660           (*it4)->checkAllocated();
6661           if((*it4)->getNumberOfComponents()!=1)
6662             {
6663               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6664               throw INTERP_KERNEL::Exception(oss.str().c_str());
6665             }
6666           int nbTupl=(*it4)->getNumberOfTuples();
6667           if(nbTupl<1)
6668             {
6669               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6670               throw INTERP_KERNEL::Exception(oss.str().c_str());
6671             }
6672           if((*it4)->front()!=0)
6673             {
6674               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6675               throw INTERP_KERNEL::Exception(oss.str().c_str());
6676             }
6677           retSz+=nbTupl-1;
6678         }
6679       else
6680         {
6681           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6682           throw INTERP_KERNEL::Exception(oss.str().c_str());
6683         }
6684     }
6685   if(arrs.empty())
6686     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6687   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6688   ret->alloc(retSz,1);
6689   int *pt=ret->getPointer(); *pt++=0;
6690   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6691     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6692   ret->copyStringInfoFrom(*(arrs[0]));
6693   return ret.retn();
6694 }
6695
6696 /*!
6697  * Returns in a single walk in \a this the min value and the max value in \a this.
6698  * \a this is expected to be single component array.
6699  *
6700  * \param [out] minValue - the min value in \a this.
6701  * \param [out] maxValue - the max value in \a this.
6702  *
6703  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6704  */
6705 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6706 {
6707   checkAllocated();
6708   if(getNumberOfComponents()!=1)
6709     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6710   int nbTuples(getNumberOfTuples());
6711   const int *pt(begin());
6712   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6713   for(int i=0;i<nbTuples;i++,pt++)
6714     {
6715       if(*pt<minValue)
6716         minValue=*pt;
6717       if(*pt>maxValue)
6718         maxValue=*pt;
6719     }
6720 }
6721
6722 /*!
6723  * Converts every value of \a this array to its absolute value.
6724  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6725  * should be called instead.
6726  *
6727  * \throw If \a this is not allocated.
6728  * \sa DataArrayInt::computeAbs
6729  */
6730 void DataArrayInt::abs()
6731 {
6732   checkAllocated();
6733   int *ptr(getPointer());
6734   std::size_t nbOfElems(getNbOfElems());
6735   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6736   declareAsNew();
6737 }
6738
6739 /*!
6740  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6741  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6742  *
6743  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6744  *         same number of tuples and component as \a this array.
6745  *         The caller is to delete this result array using decrRef() as it is no more
6746  *         needed.
6747  * \throw If \a this is not allocated.
6748  * \sa DataArrayInt::abs
6749  */
6750 DataArrayInt *DataArrayInt::computeAbs() const
6751 {
6752   checkAllocated();
6753   DataArrayInt *newArr(DataArrayInt::New());
6754   int nbOfTuples(getNumberOfTuples());
6755   int nbOfComp(getNumberOfComponents());
6756   newArr->alloc(nbOfTuples,nbOfComp);
6757   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6758   newArr->copyStringInfoFrom(*this);
6759   return newArr;
6760 }
6761
6762 /*!
6763  * Apply a liner function to a given component of \a this array, so that
6764  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6765  *  \param [in] a - the first coefficient of the function.
6766  *  \param [in] b - the second coefficient of the function.
6767  *  \param [in] compoId - the index of component to modify.
6768  *  \throw If \a this is not allocated.
6769  */
6770 void DataArrayInt::applyLin(int a, int b, int compoId)
6771 {
6772   checkAllocated();
6773   int *ptr=getPointer()+compoId;
6774   int nbOfComp=getNumberOfComponents();
6775   int nbOfTuple=getNumberOfTuples();
6776   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6777     *ptr=a*(*ptr)+b;
6778   declareAsNew();
6779 }
6780
6781 /*!
6782  * Apply a liner function to all elements of \a this array, so that
6783  * an element _x_ becomes \f$ a * x + b \f$.
6784  *  \param [in] a - the first coefficient of the function.
6785  *  \param [in] b - the second coefficient of the function.
6786  *  \throw If \a this is not allocated.
6787  */
6788 void DataArrayInt::applyLin(int a, int b)
6789 {
6790   checkAllocated();
6791   int *ptr=getPointer();
6792   std::size_t nbOfElems=getNbOfElems();
6793   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6794     *ptr=a*(*ptr)+b;
6795   declareAsNew();
6796 }
6797
6798 /*!
6799  * Returns a full copy of \a this array except that sign of all elements is reversed.
6800  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6801  *          same number of tuples and component as \a this array.
6802  *          The caller is to delete this result array using decrRef() as it is no more
6803  *          needed.
6804  *  \throw If \a this is not allocated.
6805  */
6806 DataArrayInt *DataArrayInt::negate() const
6807 {
6808   checkAllocated();
6809   DataArrayInt *newArr=DataArrayInt::New();
6810   int nbOfTuples=getNumberOfTuples();
6811   int nbOfComp=getNumberOfComponents();
6812   newArr->alloc(nbOfTuples,nbOfComp);
6813   const int *cptr=getConstPointer();
6814   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6815   newArr->copyStringInfoFrom(*this);
6816   return newArr;
6817 }
6818
6819 /*!
6820  * Modify all elements of \a this array, so that
6821  * an element _x_ becomes \f$ numerator / x \f$.
6822  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6823  *           array, all elements processed before detection of the zero element remain
6824  *           modified.
6825  *  \param [in] numerator - the numerator used to modify array elements.
6826  *  \throw If \a this is not allocated.
6827  *  \throw If there is an element equal to 0 in \a this array.
6828  */
6829 void DataArrayInt::applyInv(int numerator)
6830 {
6831   checkAllocated();
6832   int *ptr=getPointer();
6833   std::size_t nbOfElems=getNbOfElems();
6834   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6835     {
6836       if(*ptr!=0)
6837         {
6838           *ptr=numerator/(*ptr);
6839         }
6840       else
6841         {
6842           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6843           oss << " !";
6844           throw INTERP_KERNEL::Exception(oss.str().c_str());
6845         }
6846     }
6847   declareAsNew();
6848 }
6849
6850 /*!
6851  * Modify all elements of \a this array, so that
6852  * an element _x_ becomes \f$ x / val \f$.
6853  *  \param [in] val - the denominator used to modify array elements.
6854  *  \throw If \a this is not allocated.
6855  *  \throw If \a val == 0.
6856  */
6857 void DataArrayInt::applyDivideBy(int val)
6858 {
6859   if(val==0)
6860     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6861   checkAllocated();
6862   int *ptr=getPointer();
6863   std::size_t nbOfElems=getNbOfElems();
6864   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6865   declareAsNew();
6866 }
6867
6868 /*!
6869  * Modify all elements of \a this array, so that
6870  * an element _x_ becomes  <em> x % val </em>.
6871  *  \param [in] val - the divisor used to modify array elements.
6872  *  \throw If \a this is not allocated.
6873  *  \throw If \a val <= 0.
6874  */
6875 void DataArrayInt::applyModulus(int val)
6876 {
6877   if(val<=0)
6878     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6879   checkAllocated();
6880   int *ptr=getPointer();
6881   std::size_t nbOfElems=getNbOfElems();
6882   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6883   declareAsNew();
6884 }
6885
6886 /*!
6887  * This method works only on data array with one component.
6888  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6889  * this[*id] in [\b vmin,\b vmax)
6890  * 
6891  * \param [in] vmin begin of range. This value is included in range (included).
6892  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6893  * \return a newly allocated data array that the caller should deal with.
6894  *
6895  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6896  */
6897 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6898 {
6899   checkAllocated();
6900   if(getNumberOfComponents()!=1)
6901     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
6902   const int *cptr(begin());
6903   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6904   int nbOfTuples(getNumberOfTuples());
6905   for(int i=0;i<nbOfTuples;i++,cptr++)
6906     if(*cptr>=vmin && *cptr<vmax)
6907       ret->pushBackSilent(i);
6908   return ret.retn();
6909 }
6910
6911 /*!
6912  * This method works only on data array with one component.
6913  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6914  * this[*id] \b not in [\b vmin,\b vmax)
6915  * 
6916  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6917  * \param [in] vmax end of range. This value is included in range (included).
6918  * \return a newly allocated data array that the caller should deal with.
6919  * 
6920  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6921  */
6922 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6923 {
6924   checkAllocated();
6925   if(getNumberOfComponents()!=1)
6926     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
6927   const int *cptr(getConstPointer());
6928   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6929   int nbOfTuples(getNumberOfTuples());
6930   for(int i=0;i<nbOfTuples;i++,cptr++)
6931     if(*cptr<vmin || *cptr>=vmax)
6932       ret->pushBackSilent(i);
6933   return ret.retn();
6934 }
6935
6936 /*!
6937  * 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.
6938  *
6939  * \return a newly allocated data array that the caller should deal with.
6940  * \sa DataArrayInt::findIdsInRange
6941  */
6942 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6943 {
6944   checkAllocated();
6945   if(getNumberOfComponents()!=1)
6946     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
6947   const int *cptr(getConstPointer());
6948   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6949   int nbOfTuples(getNumberOfTuples());
6950   for(int i=0;i<nbOfTuples;i++,cptr++)
6951     if(*cptr<0)
6952       ret->pushBackSilent(i);
6953   return ret.retn();
6954 }
6955
6956 /*!
6957  * This method works only on data array with one component.
6958  * 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.
6959  * 
6960  * \param [in] vmin begin of range. This value is included in range (included).
6961  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6962  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6963 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6964 {
6965   checkAllocated();
6966   if(getNumberOfComponents()!=1)
6967     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6968   int nbOfTuples=getNumberOfTuples();
6969   bool ret=true;
6970   const int *cptr=getConstPointer();
6971   for(int i=0;i<nbOfTuples;i++,cptr++)
6972     {
6973       if(*cptr>=vmin && *cptr<vmax)
6974         { ret=ret && *cptr==i; }
6975       else
6976         {
6977           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6978           throw INTERP_KERNEL::Exception(oss.str().c_str());
6979         }
6980     }
6981   return ret;
6982 }
6983
6984 /*!
6985  * Modify all elements of \a this array, so that
6986  * an element _x_ becomes <em> val % x </em>.
6987  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6988  *           array, all elements processed before detection of the zero element remain
6989  *           modified.
6990  *  \param [in] val - the divident used to modify array elements.
6991  *  \throw If \a this is not allocated.
6992  *  \throw If there is an element equal to or less than 0 in \a this array.
6993  */
6994 void DataArrayInt::applyRModulus(int val)
6995 {
6996   checkAllocated();
6997   int *ptr=getPointer();
6998   std::size_t nbOfElems=getNbOfElems();
6999   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7000     {
7001       if(*ptr>0)
7002         {
7003           *ptr=val%(*ptr);
7004         }
7005       else
7006         {
7007           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7008           oss << " !";
7009           throw INTERP_KERNEL::Exception(oss.str().c_str());
7010         }
7011     }
7012   declareAsNew();
7013 }
7014
7015 /*!
7016  * Modify all elements of \a this array, so that
7017  * an element _x_ becomes <em> val ^ x </em>.
7018  *  \param [in] val - the value used to apply pow on all array elements.
7019  *  \throw If \a this is not allocated.
7020  *  \throw If \a val < 0.
7021  */
7022 void DataArrayInt::applyPow(int val)
7023 {
7024   checkAllocated();
7025   if(val<0)
7026     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7027   int *ptr=getPointer();
7028   std::size_t nbOfElems=getNbOfElems();
7029   if(val==0)
7030     {
7031       std::fill(ptr,ptr+nbOfElems,1);
7032       return ;
7033     }
7034   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7035     {
7036       int tmp=1;
7037       for(int j=0;j<val;j++)
7038         tmp*=*ptr;
7039       *ptr=tmp;
7040     }
7041   declareAsNew();
7042 }
7043
7044 /*!
7045  * Modify all elements of \a this array, so that
7046  * an element _x_ becomes \f$ val ^ x \f$.
7047  *  \param [in] val - the value used to apply pow on all array elements.
7048  *  \throw If \a this is not allocated.
7049  *  \throw If there is an element < 0 in \a this array.
7050  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7051  *           array, all elements processed before detection of the zero element remain
7052  *           modified.
7053  */
7054 void DataArrayInt::applyRPow(int val)
7055 {
7056   checkAllocated();
7057   int *ptr=getPointer();
7058   std::size_t nbOfElems=getNbOfElems();
7059   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7060     {
7061       if(*ptr>=0)
7062         {
7063           int tmp=1;
7064           for(int j=0;j<*ptr;j++)
7065             tmp*=val;
7066           *ptr=tmp;
7067         }
7068       else
7069         {
7070           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7071           oss << " !";
7072           throw INTERP_KERNEL::Exception(oss.str().c_str());
7073         }
7074     }
7075   declareAsNew();
7076 }
7077
7078 /*!
7079  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7080  * of components in the result array is a sum of the number of components of given arrays
7081  * and (2) the number of tuples in the result array is same as that of each of given
7082  * arrays. In other words the i-th tuple of result array includes all components of
7083  * i-th tuples of all given arrays.
7084  * Number of tuples in the given arrays must be the same.
7085  *  \param [in] a1 - an array to include in the result array.
7086  *  \param [in] a2 - another array to include in the result array.
7087  *  \return DataArrayInt * - the new instance of DataArrayInt.
7088  *          The caller is to delete this result array using decrRef() as it is no more
7089  *          needed.
7090  *  \throw If both \a a1 and \a a2 are NULL.
7091  *  \throw If any given array is not allocated.
7092  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7093  */
7094 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7095 {
7096   std::vector<const DataArrayInt *> arr(2);
7097   arr[0]=a1; arr[1]=a2;
7098   return Meld(arr);
7099 }
7100
7101 /*!
7102  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7103  * of components in the result array is a sum of the number of components of given arrays
7104  * and (2) the number of tuples in the result array is same as that of each of given
7105  * arrays. In other words the i-th tuple of result array includes all components of
7106  * i-th tuples of all given arrays.
7107  * Number of tuples in the given arrays must be  the same.
7108  *  \param [in] arr - a sequence of arrays to include in the result array.
7109  *  \return DataArrayInt * - the new instance of DataArrayInt.
7110  *          The caller is to delete this result array using decrRef() as it is no more
7111  *          needed.
7112  *  \throw If all arrays within \a arr are NULL.
7113  *  \throw If any given array is not allocated.
7114  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7115  */
7116 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7117 {
7118   std::vector<const DataArrayInt *> a;
7119   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7120     if(*it4)
7121       a.push_back(*it4);
7122   if(a.empty())
7123     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7124   std::vector<const DataArrayInt *>::const_iterator it;
7125   for(it=a.begin();it!=a.end();it++)
7126     (*it)->checkAllocated();
7127   it=a.begin();
7128   int nbOfTuples=(*it)->getNumberOfTuples();
7129   std::vector<int> nbc(a.size());
7130   std::vector<const int *> pts(a.size());
7131   nbc[0]=(*it)->getNumberOfComponents();
7132   pts[0]=(*it++)->getConstPointer();
7133   for(int i=1;it!=a.end();it++,i++)
7134     {
7135       if(nbOfTuples!=(*it)->getNumberOfTuples())
7136         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7137       nbc[i]=(*it)->getNumberOfComponents();
7138       pts[i]=(*it)->getConstPointer();
7139     }
7140   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7141   DataArrayInt *ret=DataArrayInt::New();
7142   ret->alloc(nbOfTuples,totalNbOfComp);
7143   int *retPtr=ret->getPointer();
7144   for(int i=0;i<nbOfTuples;i++)
7145     for(int j=0;j<(int)a.size();j++)
7146       {
7147         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7148         pts[j]+=nbc[j];
7149       }
7150   int k=0;
7151   for(int i=0;i<(int)a.size();i++)
7152     for(int j=0;j<nbc[i];j++,k++)
7153       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7154   return ret;
7155 }
7156
7157 /*!
7158  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7159  * The i-th item of the result array is an ID of a set of elements belonging to a
7160  * unique set of groups, which the i-th element is a part of. This set of elements
7161  * belonging to a unique set of groups is called \a family, so the result array contains
7162  * IDs of families each element belongs to.
7163  *
7164  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7165  * then there are 3 families:
7166  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7167  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7168  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7169  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7170  * stands for the element #3 which is in none of groups.
7171  *
7172  *  \param [in] groups - sequence of groups of element IDs.
7173  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7174  *         in \a groups.
7175  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7176  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7177  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7178  *         delete this array using decrRef() as it is no more needed.
7179  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7180  */
7181 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7182 {
7183   std::vector<const DataArrayInt *> groups2;
7184   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7185     if(*it4)
7186       groups2.push_back(*it4);
7187   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7188   ret->alloc(newNb,1);
7189   int *retPtr=ret->getPointer();
7190   std::fill(retPtr,retPtr+newNb,0);
7191   int fid=1;
7192   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7193     {
7194       const int *ptr=(*iter)->getConstPointer();
7195       std::size_t nbOfElem=(*iter)->getNbOfElems();
7196       int sfid=fid;
7197       for(int j=0;j<sfid;j++)
7198         {
7199           bool found=false;
7200           for(std::size_t i=0;i<nbOfElem;i++)
7201             {
7202               if(ptr[i]>=0 && ptr[i]<newNb)
7203                 {
7204                   if(retPtr[ptr[i]]==j)
7205                     {
7206                       retPtr[ptr[i]]=fid;
7207                       found=true;
7208                     }
7209                 }
7210               else
7211                 {
7212                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7213                   oss << ") !";
7214                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7215                 }
7216             }
7217           if(found)
7218             fid++;
7219         }
7220     }
7221   fidsOfGroups.clear();
7222   fidsOfGroups.resize(groups2.size());
7223   int grId=0;
7224   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7225     {
7226       std::set<int> tmp;
7227       const int *ptr=(*iter)->getConstPointer();
7228       std::size_t nbOfElem=(*iter)->getNbOfElems();
7229       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7230         tmp.insert(retPtr[*p]);
7231       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7232     }
7233   return ret.retn();
7234 }
7235
7236 /*!
7237  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7238  * arrays. The result array does not contain any duplicates and its values
7239  * are sorted in ascending order.
7240  *  \param [in] arr - sequence of DataArrayInt's to unite.
7241  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7242  *         array using decrRef() as it is no more needed.
7243  *  \throw If any \a arr[i] is not allocated.
7244  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7245  */
7246 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7247 {
7248   std::vector<const DataArrayInt *> a;
7249   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7250     if(*it4)
7251       a.push_back(*it4);
7252   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7253     {
7254       (*it)->checkAllocated();
7255       if((*it)->getNumberOfComponents()!=1)
7256         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7257     }
7258   //
7259   std::set<int> r;
7260   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7261     {
7262       const int *pt=(*it)->getConstPointer();
7263       int nbOfTuples=(*it)->getNumberOfTuples();
7264       r.insert(pt,pt+nbOfTuples);
7265     }
7266   DataArrayInt *ret=DataArrayInt::New();
7267   ret->alloc((int)r.size(),1);
7268   std::copy(r.begin(),r.end(),ret->getPointer());
7269   return ret;
7270 }
7271
7272 /*!
7273  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7274  * arrays. The result array does not contain any duplicates and its values
7275  * are sorted in ascending order.
7276  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7277  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7278  *         array using decrRef() as it is no more needed.
7279  *  \throw If any \a arr[i] is not allocated.
7280  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7281  */
7282 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7283 {
7284   std::vector<const DataArrayInt *> a;
7285   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7286     if(*it4)
7287       a.push_back(*it4);
7288   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7289     {
7290       (*it)->checkAllocated();
7291       if((*it)->getNumberOfComponents()!=1)
7292         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7293     }
7294   //
7295   std::set<int> r;
7296   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7297     {
7298       const int *pt=(*it)->getConstPointer();
7299       int nbOfTuples=(*it)->getNumberOfTuples();
7300       std::set<int> s1(pt,pt+nbOfTuples);
7301       if(it!=a.begin())
7302         {
7303           std::set<int> r2;
7304           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7305           r=r2;
7306         }
7307       else
7308         r=s1;
7309     }
7310   DataArrayInt *ret(DataArrayInt::New());
7311   ret->alloc((int)r.size(),1);
7312   std::copy(r.begin(),r.end(),ret->getPointer());
7313   return ret;
7314 }
7315
7316 /// @cond INTERNAL
7317 namespace MEDCouplingImpl
7318 {
7319   class OpSwitchedOn
7320   {
7321   public:
7322     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7323     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7324   private:
7325     int *_pt;
7326     int _cnt;
7327   };
7328
7329   class OpSwitchedOff
7330   {
7331   public:
7332     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7333     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7334   private:
7335     int *_pt;
7336     int _cnt;
7337   };
7338 }
7339 /// @endcond
7340
7341 /*!
7342  * This method returns the list of ids in ascending mode so that v[id]==true.
7343  */
7344 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7345 {
7346   int sz((int)std::count(v.begin(),v.end(),true));
7347   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7348   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7349   return ret.retn();
7350 }
7351
7352 /*!
7353  * This method returns the list of ids in ascending mode so that v[id]==false.
7354  */
7355 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7356 {
7357   int sz((int)std::count(v.begin(),v.end(),false));
7358   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7359   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7360   return ret.retn();
7361 }
7362
7363 /*!
7364  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7365  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7366  *
7367  * \param [in] v the input data structure to be translate into skyline format.
7368  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7369  * \param [out] dataIndex the second element of the skyline format.
7370  */
7371 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7372 {
7373   int sz((int)v.size());
7374   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7375   ret1->alloc(sz+1,1);
7376   int *pt(ret1->getPointer()); *pt=0;
7377   for(int i=0;i<sz;i++,pt++)
7378     pt[1]=pt[0]+(int)v[i].size();
7379   ret0->alloc(ret1->back(),1);
7380   pt=ret0->getPointer();
7381   for(int i=0;i<sz;i++)
7382     pt=std::copy(v[i].begin(),v[i].end(),pt);
7383   data=ret0.retn(); dataIndex=ret1.retn();
7384 }
7385
7386 /*!
7387  * Returns a new DataArrayInt which contains a complement of elements of \a this
7388  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7389  * \a nbOfElement) not present in \a this array.
7390  *  \param [in] nbOfElement - maximal size of the result array.
7391  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7392  *         array using decrRef() as it is no more needed.
7393  *  \throw If \a this is not allocated.
7394  *  \throw If \a this->getNumberOfComponents() != 1.
7395  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7396  *         nbOfElement ).
7397  */
7398 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7399 {
7400   checkAllocated();
7401   if(getNumberOfComponents()!=1)
7402     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7403   std::vector<bool> tmp(nbOfElement);
7404   const int *pt=getConstPointer();
7405   int nbOfTuples=getNumberOfTuples();
7406   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7407     if(*w>=0 && *w<nbOfElement)
7408       tmp[*w]=true;
7409     else
7410       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7411   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7412   DataArrayInt *ret=DataArrayInt::New();
7413   ret->alloc(nbOfRetVal,1);
7414   int j=0;
7415   int *retPtr=ret->getPointer();
7416   for(int i=0;i<nbOfElement;i++)
7417     if(!tmp[i])
7418       retPtr[j++]=i;
7419   return ret;
7420 }
7421
7422 /*!
7423  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7424  * from an \a other one-dimensional array.
7425  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7426  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7427  *         caller is to delete this array using decrRef() as it is no more needed.
7428  *  \throw If \a other is NULL.
7429  *  \throw If \a other is not allocated.
7430  *  \throw If \a other->getNumberOfComponents() != 1.
7431  *  \throw If \a this is not allocated.
7432  *  \throw If \a this->getNumberOfComponents() != 1.
7433  *  \sa DataArrayInt::buildSubstractionOptimized()
7434  */
7435 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7436 {
7437   if(!other)
7438     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7439   checkAllocated();
7440   other->checkAllocated();
7441   if(getNumberOfComponents()!=1)
7442     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7443   if(other->getNumberOfComponents()!=1)
7444     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7445   const int *pt=getConstPointer();
7446   int nbOfTuples=getNumberOfTuples();
7447   std::set<int> s1(pt,pt+nbOfTuples);
7448   pt=other->getConstPointer();
7449   nbOfTuples=other->getNumberOfTuples();
7450   std::set<int> s2(pt,pt+nbOfTuples);
7451   std::vector<int> r;
7452   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7453   DataArrayInt *ret=DataArrayInt::New();
7454   ret->alloc((int)r.size(),1);
7455   std::copy(r.begin(),r.end(),ret->getPointer());
7456   return ret;
7457 }
7458
7459 /*!
7460  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7461  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7462  * 
7463  * \param [in] other an array with one component and expected to be sorted ascendingly.
7464  * \ret list of ids in \a this but not in \a other.
7465  * \sa DataArrayInt::buildSubstraction
7466  */
7467 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7468 {
7469   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7470   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7471   checkAllocated(); other->checkAllocated();
7472   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7473   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7474   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7475   const int *work1(pt1Bg),*work2(pt2Bg);
7476   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7477   for(;work1!=pt1End;work1++)
7478     {
7479       if(work2!=pt2End && *work1==*work2)
7480         work2++;
7481       else
7482         ret->pushBackSilent(*work1);
7483     }
7484   return ret.retn();
7485 }
7486
7487
7488 /*!
7489  * Returns a new DataArrayInt which contains all elements of \a this and a given
7490  * one-dimensional arrays. The result array does not contain any duplicates
7491  * and its values are sorted in ascending order.
7492  *  \param [in] other - an array to unite with \a this one.
7493  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7494  *         array using decrRef() as it is no more needed.
7495  *  \throw If \a this or \a other is not allocated.
7496  *  \throw If \a this->getNumberOfComponents() != 1.
7497  *  \throw If \a other->getNumberOfComponents() != 1.
7498  */
7499 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7500 {
7501   std::vector<const DataArrayInt *>arrs(2);
7502   arrs[0]=this; arrs[1]=other;
7503   return BuildUnion(arrs);
7504 }
7505
7506
7507 /*!
7508  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7509  * one-dimensional arrays. The result array does not contain any duplicates
7510  * and its values are sorted in ascending order.
7511  *  \param [in] other - an array to intersect with \a this one.
7512  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7513  *         array using decrRef() as it is no more needed.
7514  *  \throw If \a this or \a other is not allocated.
7515  *  \throw If \a this->getNumberOfComponents() != 1.
7516  *  \throw If \a other->getNumberOfComponents() != 1.
7517  */
7518 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7519 {
7520   std::vector<const DataArrayInt *>arrs(2);
7521   arrs[0]=this; arrs[1]=other;
7522   return BuildIntersection(arrs);
7523 }
7524
7525 /*!
7526  * This method can be applied on allocated with one component DataArrayInt instance.
7527  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7528  * 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]
7529  * 
7530  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7531  * \throw if \a this is not allocated or if \a this has not exactly one component.
7532  * \sa DataArrayInt::buildUniqueNotSorted
7533  */
7534 DataArrayInt *DataArrayInt::buildUnique() const
7535 {
7536   checkAllocated();
7537   if(getNumberOfComponents()!=1)
7538     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7539   int nbOfTuples=getNumberOfTuples();
7540   MCAuto<DataArrayInt> tmp=deepCopy();
7541   int *data=tmp->getPointer();
7542   int *last=std::unique(data,data+nbOfTuples);
7543   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7544   ret->alloc(std::distance(data,last),1);
7545   std::copy(data,last,ret->getPointer());
7546   return ret.retn();
7547 }
7548
7549 /*!
7550  * This method can be applied on allocated with one component DataArrayInt instance.
7551  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7552  *
7553  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7554  *
7555  * \throw if \a this is not allocated or if \a this has not exactly one component.
7556  *
7557  * \sa DataArrayInt::buildUnique
7558  */
7559 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7560 {
7561   checkAllocated();
7562     if(getNumberOfComponents()!=1)
7563       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7564   int minVal,maxVal;
7565   getMinMaxValues(minVal,maxVal);
7566   std::vector<bool> b(maxVal-minVal+1,false);
7567   const int *ptBg(begin()),*endBg(end());
7568   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7569   for(const int *pt=ptBg;pt!=endBg;pt++)
7570     {
7571       if(!b[*pt-minVal])
7572         {
7573           ret->pushBackSilent(*pt);
7574           b[*pt-minVal]=true;
7575         }
7576     }
7577   ret->copyStringInfoFrom(*this);
7578   return ret.retn();
7579 }
7580
7581 /*!
7582  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7583  * "index" array. Such "index" array is returned for example by 
7584  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7585  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7586  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7587  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7588  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7589  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7590  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7591  *          The caller is to delete this array using decrRef() as it is no more needed. 
7592  *  \throw If \a this is not allocated.
7593  *  \throw If \a this->getNumberOfComponents() != 1.
7594  *  \throw If \a this->getNumberOfTuples() < 2.
7595  *
7596  *  \b Example: <br> 
7597  *         - this contains [1,3,6,7,7,9,15]
7598  *         - result array contains [2,3,1,0,2,6],
7599  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7600  *
7601  * \sa DataArrayInt::computeOffsetsFull
7602  */
7603 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7604 {
7605   checkAllocated();
7606   if(getNumberOfComponents()!=1)
7607     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7608   int nbOfTuples=getNumberOfTuples();
7609   if(nbOfTuples<2)
7610     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7611   const int *ptr=getConstPointer();
7612   DataArrayInt *ret=DataArrayInt::New();
7613   ret->alloc(nbOfTuples-1,1);
7614   int *out=ret->getPointer();
7615   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7616   return ret;
7617 }
7618
7619 /*!
7620  * Modifies \a this one-dimensional array so that value of each element \a x
7621  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7622  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7623  * and components remains the same.<br>
7624  * This method is useful for allToAllV in MPI with contiguous policy. This method
7625  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7626  * this one.
7627  *  \throw If \a this is not allocated.
7628  *  \throw If \a this->getNumberOfComponents() != 1.
7629  *
7630  *  \b Example: <br>
7631  *          - Before \a this contains [3,5,1,2,0,8]
7632  *          - After \a this contains  [0,3,8,9,11,11]<br>
7633  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7634  *          array is retained and thus there is no space to store the last element.
7635  */
7636 void DataArrayInt::computeOffsets()
7637 {
7638   checkAllocated();
7639   if(getNumberOfComponents()!=1)
7640     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7641   int nbOfTuples=getNumberOfTuples();
7642   if(nbOfTuples==0)
7643     return ;
7644   int *work=getPointer();
7645   int tmp=work[0];
7646   work[0]=0;
7647   for(int i=1;i<nbOfTuples;i++)
7648     {
7649       int tmp2=work[i];
7650       work[i]=work[i-1]+tmp;
7651       tmp=tmp2;
7652     }
7653   declareAsNew();
7654 }
7655
7656
7657 /*!
7658  * Modifies \a this one-dimensional array so that value of each element \a x
7659  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7660  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7661  * components remains the same and number of tuples is inceamented by one.<br>
7662  * This method is useful for allToAllV in MPI with contiguous policy. This method
7663  * differs from computeOffsets() in that the number of tuples is changed by this one.
7664  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7665  *  \throw If \a this is not allocated.
7666  *  \throw If \a this->getNumberOfComponents() != 1.
7667  *
7668  *  \b Example: <br>
7669  *          - Before \a this contains [3,5,1,2,0,8]
7670  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7671  * \sa DataArrayInt::deltaShiftIndex
7672  */
7673 void DataArrayInt::computeOffsetsFull()
7674 {
7675   checkAllocated();
7676   if(getNumberOfComponents()!=1)
7677     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7678   int nbOfTuples=getNumberOfTuples();
7679   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7680   const int *work=getConstPointer();
7681   ret[0]=0;
7682   for(int i=0;i<nbOfTuples;i++)
7683     ret[i+1]=work[i]+ret[i];
7684   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7685   declareAsNew();
7686 }
7687
7688 /*!
7689  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7690  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7691  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7692  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7693  * filling completely one of the ranges in \a this.
7694  *
7695  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7696  * \param [out] rangeIdsFetched the range ids fetched
7697  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7698  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7699  *
7700  * \sa DataArrayInt::computeOffsetsFull
7701  *
7702  *  \b Example: <br>
7703  *          - \a this : [0,3,7,9,15,18]
7704  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7705  *          - \a rangeIdsFetched result array: [0,2,4]
7706  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7707  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7708  * <br>
7709  */
7710 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7711 {
7712   if(!listOfIds)
7713     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7714   listOfIds->checkAllocated(); checkAllocated();
7715   if(listOfIds->getNumberOfComponents()!=1)
7716     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7717   if(getNumberOfComponents()!=1)
7718     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7719   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7720   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7721   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7722   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7723   while(tupPtr!=tupEnd && offPtr!=offEnd)
7724     {
7725       if(*tupPtr==*offPtr)
7726         {
7727           int i=offPtr[0];
7728           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7729           if(i==offPtr[1])
7730             {
7731               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7732               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7733               offPtr++;
7734             }
7735         }
7736       else
7737         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7738     }
7739   rangeIdsFetched=ret0.retn();
7740   idsInInputListThatFetch=ret1.retn();
7741 }
7742
7743 /*!
7744  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7745  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7746  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7747  * beginning within the "iota" array. And \a this is a one-dimensional array
7748  * considered as a selector of groups described by \a offsets to include into the result array.
7749  *  \throw If \a offsets is NULL.
7750  *  \throw If \a offsets is not allocated.
7751  *  \throw If \a offsets->getNumberOfComponents() != 1.
7752  *  \throw If \a offsets is not monotonically increasing.
7753  *  \throw If \a this is not allocated.
7754  *  \throw If \a this->getNumberOfComponents() != 1.
7755  *  \throw If any element of \a this is not a valid index for \a offsets array.
7756  *
7757  *  \b Example: <br>
7758  *          - \a this: [0,2,3]
7759  *          - \a offsets: [0,3,6,10,14,20]
7760  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7761  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7762  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7763  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7764  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7765  */
7766 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7767 {
7768   if(!offsets)
7769     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7770   checkAllocated();
7771   if(getNumberOfComponents()!=1)
7772     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7773   offsets->checkAllocated();
7774   if(offsets->getNumberOfComponents()!=1)
7775     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7776   int othNbTuples=offsets->getNumberOfTuples()-1;
7777   int nbOfTuples=getNumberOfTuples();
7778   int retNbOftuples=0;
7779   const int *work=getConstPointer();
7780   const int *offPtr=offsets->getConstPointer();
7781   for(int i=0;i<nbOfTuples;i++)
7782     {
7783       int val=work[i];
7784       if(val>=0 && val<othNbTuples)
7785         {
7786           int delta=offPtr[val+1]-offPtr[val];
7787           if(delta>=0)
7788             retNbOftuples+=delta;
7789           else
7790             {
7791               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7792               throw INTERP_KERNEL::Exception(oss.str().c_str());
7793             }
7794         }
7795       else
7796         {
7797           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7798           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7799           throw INTERP_KERNEL::Exception(oss.str().c_str());
7800         }
7801     }
7802   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7803   ret->alloc(retNbOftuples,1);
7804   int *retPtr=ret->getPointer();
7805   for(int i=0;i<nbOfTuples;i++)
7806     {
7807       int val=work[i];
7808       int start=offPtr[val];
7809       int off=offPtr[val+1]-start;
7810       for(int j=0;j<off;j++,retPtr++)
7811         *retPtr=start+j;
7812     }
7813   return ret.retn();
7814 }
7815
7816 /*!
7817  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7818  * scaled array (monotonically increasing).
7819 from that of \a this and \a
7820  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7821  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7822  * beginning within the "iota" array. And \a this is a one-dimensional array
7823  * considered as a selector of groups described by \a offsets to include into the result array.
7824  *  \throw If \a  is NULL.
7825  *  \throw If \a this is not allocated.
7826  *  \throw If \a this->getNumberOfComponents() != 1.
7827  *  \throw If \a this->getNumberOfTuples() == 0.
7828  *  \throw If \a this is not monotonically increasing.
7829  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7830  *
7831  *  \b Example: <br>
7832  *          - \a bg , \a stop and \a step : (0,5,2)
7833  *          - \a this: [0,3,6,10,14,20]
7834  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7835  */
7836 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7837 {
7838   if(!isAllocated())
7839     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7840   if(getNumberOfComponents()!=1)
7841     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7842   int nbOfTuples(getNumberOfTuples());
7843   if(nbOfTuples==0)
7844     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7845   const int *ids(begin());
7846   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7847   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7848     {
7849       if(pos>=0 && pos<nbOfTuples-1)
7850         {
7851           int delta(ids[pos+1]-ids[pos]);
7852           sz+=delta;
7853           if(delta<0)
7854             {
7855               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7856               throw INTERP_KERNEL::Exception(oss.str().c_str());
7857             }          
7858         }
7859       else
7860         {
7861           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7862           throw INTERP_KERNEL::Exception(oss.str().c_str());
7863         }
7864     }
7865   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7866   int *retPtr(ret->getPointer());
7867   pos=bg;
7868   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7869     {
7870       int delta(ids[pos+1]-ids[pos]);
7871       for(int j=0;j<delta;j++,retPtr++)
7872         *retPtr=pos;
7873     }
7874   return ret.retn();
7875 }
7876
7877 /*!
7878  * 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.
7879  * 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
7880  * in tuple **i** of returned DataArrayInt.
7881  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7882  *
7883  * 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)]
7884  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7885  * 
7886  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7887  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7888  * \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
7889  *        is thrown if no ranges in \a ranges contains value in \a this.
7890  * 
7891  * \sa DataArrayInt::findIdInRangeForEachTuple
7892  */
7893 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7894 {
7895   if(!ranges)
7896     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7897   if(ranges->getNumberOfComponents()!=2)
7898     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7899   checkAllocated();
7900   if(getNumberOfComponents()!=1)
7901     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7902   int nbTuples=getNumberOfTuples();
7903   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7904   int nbOfRanges=ranges->getNumberOfTuples();
7905   const int *rangesPtr=ranges->getConstPointer();
7906   int *retPtr=ret->getPointer();
7907   const int *inPtr=getConstPointer();
7908   for(int i=0;i<nbTuples;i++,retPtr++)
7909     {
7910       int val=inPtr[i];
7911       bool found=false;
7912       for(int j=0;j<nbOfRanges && !found;j++)
7913         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7914           { *retPtr=j; found=true; }
7915       if(found)
7916         continue;
7917       else
7918         {
7919           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7920           throw INTERP_KERNEL::Exception(oss.str().c_str());
7921         }
7922     }
7923   return ret.retn();
7924 }
7925
7926 /*!
7927  * 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.
7928  * 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
7929  * in tuple **i** of returned DataArrayInt.
7930  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7931  *
7932  * 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)]
7933  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7934  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7935  * 
7936  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7937  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7938  * \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
7939  *        is thrown if no ranges in \a ranges contains value in \a this.
7940  * \sa DataArrayInt::findRangeIdForEachTuple
7941  */
7942 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7943 {
7944   if(!ranges)
7945     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7946   if(ranges->getNumberOfComponents()!=2)
7947     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7948   checkAllocated();
7949   if(getNumberOfComponents()!=1)
7950     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7951   int nbTuples=getNumberOfTuples();
7952   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7953   int nbOfRanges=ranges->getNumberOfTuples();
7954   const int *rangesPtr=ranges->getConstPointer();
7955   int *retPtr=ret->getPointer();
7956   const int *inPtr=getConstPointer();
7957   for(int i=0;i<nbTuples;i++,retPtr++)
7958     {
7959       int val=inPtr[i];
7960       bool found=false;
7961       for(int j=0;j<nbOfRanges && !found;j++)
7962         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7963           { *retPtr=val-rangesPtr[2*j]; found=true; }
7964       if(found)
7965         continue;
7966       else
7967         {
7968           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7969           throw INTERP_KERNEL::Exception(oss.str().c_str());
7970         }
7971     }
7972   return ret.retn();
7973 }
7974
7975 /*!
7976  * \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).
7977  * 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).
7978  * 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 !
7979  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7980  * This method does nothing if number of tuples is lower of equal to 1.
7981  *
7982  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7983  *
7984  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
7985  */
7986 void DataArrayInt::sortEachPairToMakeALinkedList()
7987 {
7988   checkAllocated();
7989   if(getNumberOfComponents()!=2)
7990     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7991   int nbOfTuples(getNumberOfTuples());
7992   if(nbOfTuples<=1)
7993     return ;
7994   int *conn(getPointer());
7995   for(int i=1;i<nbOfTuples;i++,conn+=2)
7996     {
7997       if(i>1)
7998         {
7999           if(conn[2]==conn[3])
8000             {
8001               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
8002               throw INTERP_KERNEL::Exception(oss.str().c_str());
8003             }
8004           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8005             std::swap(conn[2],conn[3]);
8006           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8007           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8008             {
8009               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8010               throw INTERP_KERNEL::Exception(oss.str().c_str());
8011             }
8012         }
8013       else
8014         {
8015           if(conn[0]==conn[1] || conn[2]==conn[3])
8016             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8017           int tmp[4];
8018           std::set<int> s;
8019           s.insert(conn,conn+4);
8020           if(s.size()!=3)
8021             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8022           if(std::count(conn,conn+4,conn[0])==2)
8023             {
8024               tmp[0]=conn[1];
8025               tmp[1]=conn[0];
8026               tmp[2]=conn[0];
8027               if(conn[2]==conn[0])
8028                 { tmp[3]=conn[3]; }
8029               else
8030                 { tmp[3]=conn[2];}
8031               std::copy(tmp,tmp+4,conn);
8032             }
8033           else
8034             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8035               if(conn[1]==conn[3])
8036                 std::swap(conn[2],conn[3]);
8037             }
8038         }
8039     }
8040 }
8041
8042 /*!
8043  * 
8044  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8045  *             \a nbTimes  should be at least equal to 1.
8046  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8047  * \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.
8048  */
8049 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8050 {
8051   checkAllocated();
8052   if(getNumberOfComponents()!=1)
8053     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8054   if(nbTimes<1)
8055     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8056   int nbTuples=getNumberOfTuples();
8057   const int *inPtr=getConstPointer();
8058   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8059   int *retPtr=ret->getPointer();
8060   for(int i=0;i<nbTuples;i++,inPtr++)
8061     {
8062       int val=*inPtr;
8063       for(int j=0;j<nbTimes;j++,retPtr++)
8064         *retPtr=val;
8065     }
8066   ret->copyStringInfoFrom(*this);
8067   return ret.retn();
8068 }
8069
8070 /*!
8071  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8072  * But the number of components can be different from one.
8073  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8074  */
8075 DataArrayInt *DataArrayInt::getDifferentValues() const
8076 {
8077   checkAllocated();
8078   std::set<int> ret;
8079   ret.insert(begin(),end());
8080   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8081   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8082   return ret2.retn();
8083 }
8084
8085 /*!
8086  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8087  * them it tells which tuple id have this id.
8088  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8089  * This method returns two arrays having same size.
8090  * 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.
8091  * 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]]
8092  */
8093 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8094 {
8095   checkAllocated();
8096   if(getNumberOfComponents()!=1)
8097     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8098   int id=0;
8099   std::map<int,int> m,m2,m3;
8100   for(const int *w=begin();w!=end();w++)
8101     m[*w]++;
8102   differentIds.resize(m.size());
8103   std::vector<DataArrayInt *> ret(m.size());
8104   std::vector<int *> retPtr(m.size());
8105   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8106     {
8107       m2[(*it).first]=id;
8108       ret[id]=DataArrayInt::New();
8109       ret[id]->alloc((*it).second,1);
8110       retPtr[id]=ret[id]->getPointer();
8111       differentIds[id]=(*it).first;
8112     }
8113   id=0;
8114   for(const int *w=begin();w!=end();w++,id++)
8115     {
8116       retPtr[m2[*w]][m3[*w]++]=id;
8117     }
8118   return ret;
8119 }
8120
8121 /*!
8122  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8123  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8124  *
8125  * \param [in] nbOfSlices - number of slices expected.
8126  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8127  * 
8128  * \sa DataArray::GetSlice
8129  * \throw If \a this is not allocated or not with exactly one component.
8130  * \throw If an element in \a this if < 0.
8131  */
8132 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8133 {
8134   if(!isAllocated() || getNumberOfComponents()!=1)
8135     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8136   if(nbOfSlices<=0)
8137     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8138   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8139   int sumPerSlc(sum/nbOfSlices),pos(0);
8140   const int *w(begin());
8141   std::vector< std::pair<int,int> > ret(nbOfSlices);
8142   for(int i=0;i<nbOfSlices;i++)
8143     {
8144       std::pair<int,int> p(pos,-1);
8145       int locSum(0);
8146       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8147       if(i!=nbOfSlices-1)
8148         p.second=pos;
8149       else
8150         p.second=nbOfTuples;
8151       ret[i]=p;
8152     }
8153   return ret;
8154 }
8155
8156 /*!
8157  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8158  * valid cases.
8159  * 1.  The arrays have same number of tuples and components. Then each value of
8160  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8161  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8162  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8163  *   component. Then
8164  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8165  * 3.  The arrays have same number of components and one array, say _a2_, has one
8166  *   tuple. Then
8167  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8168  *
8169  * Info on components is copied either from the first array (in the first case) or from
8170  * the array with maximal number of elements (getNbOfElems()).
8171  *  \param [in] a1 - an array to sum up.
8172  *  \param [in] a2 - another array to sum up.
8173  *  \return DataArrayInt * - the new instance of DataArrayInt.
8174  *          The caller is to delete this result array using decrRef() as it is no more
8175  *          needed.
8176  *  \throw If either \a a1 or \a a2 is NULL.
8177  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8178  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8179  *         none of them has number of tuples or components equal to 1.
8180  */
8181 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8182 {
8183   if(!a1 || !a2)
8184     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8185   int nbOfTuple=a1->getNumberOfTuples();
8186   int nbOfTuple2=a2->getNumberOfTuples();
8187   int nbOfComp=a1->getNumberOfComponents();
8188   int nbOfComp2=a2->getNumberOfComponents();
8189   MCAuto<DataArrayInt> ret=0;
8190   if(nbOfTuple==nbOfTuple2)
8191     {
8192       if(nbOfComp==nbOfComp2)
8193         {
8194           ret=DataArrayInt::New();
8195           ret->alloc(nbOfTuple,nbOfComp);
8196           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8197           ret->copyStringInfoFrom(*a1);
8198         }
8199       else
8200         {
8201           int nbOfCompMin,nbOfCompMax;
8202           const DataArrayInt *aMin, *aMax;
8203           if(nbOfComp>nbOfComp2)
8204             {
8205               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8206               aMin=a2; aMax=a1;
8207             }
8208           else
8209             {
8210               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8211               aMin=a1; aMax=a2;
8212             }
8213           if(nbOfCompMin==1)
8214             {
8215               ret=DataArrayInt::New();
8216               ret->alloc(nbOfTuple,nbOfCompMax);
8217               const int *aMinPtr=aMin->getConstPointer();
8218               const int *aMaxPtr=aMax->getConstPointer();
8219               int *res=ret->getPointer();
8220               for(int i=0;i<nbOfTuple;i++)
8221                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8222               ret->copyStringInfoFrom(*aMax);
8223             }
8224           else
8225             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8226         }
8227     }
8228   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8229     {
8230       if(nbOfComp==nbOfComp2)
8231         {
8232           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8233           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8234           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8235           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8236           ret=DataArrayInt::New();
8237           ret->alloc(nbOfTupleMax,nbOfComp);
8238           int *res=ret->getPointer();
8239           for(int i=0;i<nbOfTupleMax;i++)
8240             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8241           ret->copyStringInfoFrom(*aMax);
8242         }
8243       else
8244         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8245     }
8246   else
8247     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8248   return ret.retn();
8249 }
8250
8251 /*!
8252  * Adds values of another DataArrayInt to values of \a this one. There are 3
8253  * valid cases.
8254  * 1.  The arrays have same number of tuples and components. Then each value of
8255  *   \a other array is added to the corresponding value of \a this array, i.e.:
8256  *   _a_ [ i, j ] += _other_ [ i, j ].
8257  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8258  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8259  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8260  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8261  *
8262  *  \param [in] other - an array to add to \a this one.
8263  *  \throw If \a other is NULL.
8264  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8265  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8266  *         \a other has number of both tuples and components not equal to 1.
8267  */
8268 void DataArrayInt::addEqual(const DataArrayInt *other)
8269 {
8270   if(!other)
8271     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8272   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8273   checkAllocated(); other->checkAllocated();
8274   int nbOfTuple=getNumberOfTuples();
8275   int nbOfTuple2=other->getNumberOfTuples();
8276   int nbOfComp=getNumberOfComponents();
8277   int nbOfComp2=other->getNumberOfComponents();
8278   if(nbOfTuple==nbOfTuple2)
8279     {
8280       if(nbOfComp==nbOfComp2)
8281         {
8282           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8283         }
8284       else if(nbOfComp2==1)
8285         {
8286           int *ptr=getPointer();
8287           const int *ptrc=other->getConstPointer();
8288           for(int i=0;i<nbOfTuple;i++)
8289             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8290         }
8291       else
8292         throw INTERP_KERNEL::Exception(msg);
8293     }
8294   else if(nbOfTuple2==1)
8295     {
8296       if(nbOfComp2==nbOfComp)
8297         {
8298           int *ptr=getPointer();
8299           const int *ptrc=other->getConstPointer();
8300           for(int i=0;i<nbOfTuple;i++)
8301             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8302         }
8303       else
8304         throw INTERP_KERNEL::Exception(msg);
8305     }
8306   else
8307     throw INTERP_KERNEL::Exception(msg);
8308   declareAsNew();
8309 }
8310
8311 /*!
8312  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8313  * valid cases.
8314  * 1.  The arrays have same number of tuples and components. Then each value of
8315  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8316  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8317  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8318  *   component. Then
8319  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8320  * 3.  The arrays have same number of components and one array, say _a2_, has one
8321  *   tuple. Then
8322  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8323  *
8324  * Info on components is copied either from the first array (in the first case) or from
8325  * the array with maximal number of elements (getNbOfElems()).
8326  *  \param [in] a1 - an array to subtract from.
8327  *  \param [in] a2 - an array to subtract.
8328  *  \return DataArrayInt * - the new instance of DataArrayInt.
8329  *          The caller is to delete this result array using decrRef() as it is no more
8330  *          needed.
8331  *  \throw If either \a a1 or \a a2 is NULL.
8332  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8333  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8334  *         none of them has number of tuples or components equal to 1.
8335  */
8336 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8337 {
8338   if(!a1 || !a2)
8339     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8340   int nbOfTuple1=a1->getNumberOfTuples();
8341   int nbOfTuple2=a2->getNumberOfTuples();
8342   int nbOfComp1=a1->getNumberOfComponents();
8343   int nbOfComp2=a2->getNumberOfComponents();
8344   if(nbOfTuple2==nbOfTuple1)
8345     {
8346       if(nbOfComp1==nbOfComp2)
8347         {
8348           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8349           ret->alloc(nbOfTuple2,nbOfComp1);
8350           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8351           ret->copyStringInfoFrom(*a1);
8352           return ret.retn();
8353         }
8354       else if(nbOfComp2==1)
8355         {
8356           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8357           ret->alloc(nbOfTuple1,nbOfComp1);
8358           const int *a2Ptr=a2->getConstPointer();
8359           const int *a1Ptr=a1->getConstPointer();
8360           int *res=ret->getPointer();
8361           for(int i=0;i<nbOfTuple1;i++)
8362             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8363           ret->copyStringInfoFrom(*a1);
8364           return ret.retn();
8365         }
8366       else
8367         {
8368           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8369           return 0;
8370         }
8371     }
8372   else if(nbOfTuple2==1)
8373     {
8374       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8375       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8376       ret->alloc(nbOfTuple1,nbOfComp1);
8377       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8378       int *pt=ret->getPointer();
8379       for(int i=0;i<nbOfTuple1;i++)
8380         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8381       ret->copyStringInfoFrom(*a1);
8382       return ret.retn();
8383     }
8384   else
8385     {
8386       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8387       return 0;
8388     }
8389 }
8390
8391 /*!
8392  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8393  * valid cases.
8394  * 1.  The arrays have same number of tuples and components. Then each value of
8395  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8396  *   _a_ [ i, j ] -= _other_ [ i, j ].
8397  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8398  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8399  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8400  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8401  *
8402  *  \param [in] other - an array to subtract from \a this one.
8403  *  \throw If \a other is NULL.
8404  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8405  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8406  *         \a other has number of both tuples and components not equal to 1.
8407  */
8408 void DataArrayInt::substractEqual(const DataArrayInt *other)
8409 {
8410   if(!other)
8411     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8412   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8413   checkAllocated(); other->checkAllocated();
8414   int nbOfTuple=getNumberOfTuples();
8415   int nbOfTuple2=other->getNumberOfTuples();
8416   int nbOfComp=getNumberOfComponents();
8417   int nbOfComp2=other->getNumberOfComponents();
8418   if(nbOfTuple==nbOfTuple2)
8419     {
8420       if(nbOfComp==nbOfComp2)
8421         {
8422           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8423         }
8424       else if(nbOfComp2==1)
8425         {
8426           int *ptr=getPointer();
8427           const int *ptrc=other->getConstPointer();
8428           for(int i=0;i<nbOfTuple;i++)
8429             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8430         }
8431       else
8432         throw INTERP_KERNEL::Exception(msg);
8433     }
8434   else if(nbOfTuple2==1)
8435     {
8436       int *ptr=getPointer();
8437       const int *ptrc=other->getConstPointer();
8438       for(int i=0;i<nbOfTuple;i++)
8439         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8440     }
8441   else
8442     throw INTERP_KERNEL::Exception(msg);
8443   declareAsNew();
8444 }
8445
8446 /*!
8447  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8448  * valid cases.
8449  * 1.  The arrays have same number of tuples and components. Then each value of
8450  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8451  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8452  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8453  *   component. Then
8454  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8455  * 3.  The arrays have same number of components and one array, say _a2_, has one
8456  *   tuple. Then
8457  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8458  *
8459  * Info on components is copied either from the first array (in the first case) or from
8460  * the array with maximal number of elements (getNbOfElems()).
8461  *  \param [in] a1 - a factor array.
8462  *  \param [in] a2 - another factor array.
8463  *  \return DataArrayInt * - the new instance of DataArrayInt.
8464  *          The caller is to delete this result array using decrRef() as it is no more
8465  *          needed.
8466  *  \throw If either \a a1 or \a a2 is NULL.
8467  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8468  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8469  *         none of them has number of tuples or components equal to 1.
8470  */
8471 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8472 {
8473   if(!a1 || !a2)
8474     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8475   int nbOfTuple=a1->getNumberOfTuples();
8476   int nbOfTuple2=a2->getNumberOfTuples();
8477   int nbOfComp=a1->getNumberOfComponents();
8478   int nbOfComp2=a2->getNumberOfComponents();
8479   MCAuto<DataArrayInt> ret=0;
8480   if(nbOfTuple==nbOfTuple2)
8481     {
8482       if(nbOfComp==nbOfComp2)
8483         {
8484           ret=DataArrayInt::New();
8485           ret->alloc(nbOfTuple,nbOfComp);
8486           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8487           ret->copyStringInfoFrom(*a1);
8488         }
8489       else
8490         {
8491           int nbOfCompMin,nbOfCompMax;
8492           const DataArrayInt *aMin, *aMax;
8493           if(nbOfComp>nbOfComp2)
8494             {
8495               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8496               aMin=a2; aMax=a1;
8497             }
8498           else
8499             {
8500               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8501               aMin=a1; aMax=a2;
8502             }
8503           if(nbOfCompMin==1)
8504             {
8505               ret=DataArrayInt::New();
8506               ret->alloc(nbOfTuple,nbOfCompMax);
8507               const int *aMinPtr=aMin->getConstPointer();
8508               const int *aMaxPtr=aMax->getConstPointer();
8509               int *res=ret->getPointer();
8510               for(int i=0;i<nbOfTuple;i++)
8511                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8512               ret->copyStringInfoFrom(*aMax);
8513             }
8514           else
8515             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8516         }
8517     }
8518   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8519     {
8520       if(nbOfComp==nbOfComp2)
8521         {
8522           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8523           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8524           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8525           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8526           ret=DataArrayInt::New();
8527           ret->alloc(nbOfTupleMax,nbOfComp);
8528           int *res=ret->getPointer();
8529           for(int i=0;i<nbOfTupleMax;i++)
8530             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8531           ret->copyStringInfoFrom(*aMax);
8532         }
8533       else
8534         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8535     }
8536   else
8537     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8538   return ret.retn();
8539 }
8540
8541
8542 /*!
8543  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8544  * valid cases.
8545  * 1.  The arrays have same number of tuples and components. Then each value of
8546  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8547  *   _a_ [ i, j ] *= _other_ [ i, j ].
8548  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8549  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8550  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8551  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8552  *
8553  *  \param [in] other - an array to multiply to \a this one.
8554  *  \throw If \a other is NULL.
8555  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8556  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8557  *         \a other has number of both tuples and components not equal to 1.
8558  */
8559 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8560 {
8561   if(!other)
8562     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8563   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8564   checkAllocated(); other->checkAllocated();
8565   int nbOfTuple=getNumberOfTuples();
8566   int nbOfTuple2=other->getNumberOfTuples();
8567   int nbOfComp=getNumberOfComponents();
8568   int nbOfComp2=other->getNumberOfComponents();
8569   if(nbOfTuple==nbOfTuple2)
8570     {
8571       if(nbOfComp==nbOfComp2)
8572         {
8573           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8574         }
8575       else if(nbOfComp2==1)
8576         {
8577           int *ptr=getPointer();
8578           const int *ptrc=other->getConstPointer();
8579           for(int i=0;i<nbOfTuple;i++)
8580             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8581         }
8582       else
8583         throw INTERP_KERNEL::Exception(msg);
8584     }
8585   else if(nbOfTuple2==1)
8586     {
8587       if(nbOfComp2==nbOfComp)
8588         {
8589           int *ptr=getPointer();
8590           const int *ptrc=other->getConstPointer();
8591           for(int i=0;i<nbOfTuple;i++)
8592             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8593         }
8594       else
8595         throw INTERP_KERNEL::Exception(msg);
8596     }
8597   else
8598     throw INTERP_KERNEL::Exception(msg);
8599   declareAsNew();
8600 }
8601
8602
8603 /*!
8604  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8605  * valid cases.
8606  * 1.  The arrays have same number of tuples and components. Then each value of
8607  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8608  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8609  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8610  *   component. Then
8611  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8612  * 3.  The arrays have same number of components and one array, say _a2_, has one
8613  *   tuple. Then
8614  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8615  *
8616  * Info on components is copied either from the first array (in the first case) or from
8617  * the array with maximal number of elements (getNbOfElems()).
8618  *  \warning No check of division by zero is performed!
8619  *  \param [in] a1 - a numerator array.
8620  *  \param [in] a2 - a denominator array.
8621  *  \return DataArrayInt * - the new instance of DataArrayInt.
8622  *          The caller is to delete this result array using decrRef() as it is no more
8623  *          needed.
8624  *  \throw If either \a a1 or \a a2 is NULL.
8625  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8626  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8627  *         none of them has number of tuples or components equal to 1.
8628  */
8629 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8630 {
8631   if(!a1 || !a2)
8632     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8633   int nbOfTuple1=a1->getNumberOfTuples();
8634   int nbOfTuple2=a2->getNumberOfTuples();
8635   int nbOfComp1=a1->getNumberOfComponents();
8636   int nbOfComp2=a2->getNumberOfComponents();
8637   if(nbOfTuple2==nbOfTuple1)
8638     {
8639       if(nbOfComp1==nbOfComp2)
8640         {
8641           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8642           ret->alloc(nbOfTuple2,nbOfComp1);
8643           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8644           ret->copyStringInfoFrom(*a1);
8645           return ret.retn();
8646         }
8647       else if(nbOfComp2==1)
8648         {
8649           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8650           ret->alloc(nbOfTuple1,nbOfComp1);
8651           const int *a2Ptr=a2->getConstPointer();
8652           const int *a1Ptr=a1->getConstPointer();
8653           int *res=ret->getPointer();
8654           for(int i=0;i<nbOfTuple1;i++)
8655             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8656           ret->copyStringInfoFrom(*a1);
8657           return ret.retn();
8658         }
8659       else
8660         {
8661           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8662           return 0;
8663         }
8664     }
8665   else if(nbOfTuple2==1)
8666     {
8667       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8668       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8669       ret->alloc(nbOfTuple1,nbOfComp1);
8670       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8671       int *pt=ret->getPointer();
8672       for(int i=0;i<nbOfTuple1;i++)
8673         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8674       ret->copyStringInfoFrom(*a1);
8675       return ret.retn();
8676     }
8677   else
8678     {
8679       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8680       return 0;
8681     }
8682 }
8683
8684 /*!
8685  * Divide values of \a this array by values of another DataArrayInt. There are 3
8686  * valid cases.
8687  * 1.  The arrays have same number of tuples and components. Then each value of
8688  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8689  *   _a_ [ i, j ] /= _other_ [ i, j ].
8690  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8691  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8692  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8693  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8694  *
8695  *  \warning No check of division by zero is performed!
8696  *  \param [in] other - an array to divide \a this one by.
8697  *  \throw If \a other is NULL.
8698  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8699  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8700  *         \a other has number of both tuples and components not equal to 1.
8701  */
8702 void DataArrayInt::divideEqual(const DataArrayInt *other)
8703 {
8704   if(!other)
8705     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8706   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8707   checkAllocated(); other->checkAllocated();
8708   int nbOfTuple=getNumberOfTuples();
8709   int nbOfTuple2=other->getNumberOfTuples();
8710   int nbOfComp=getNumberOfComponents();
8711   int nbOfComp2=other->getNumberOfComponents();
8712   if(nbOfTuple==nbOfTuple2)
8713     {
8714       if(nbOfComp==nbOfComp2)
8715         {
8716           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8717         }
8718       else if(nbOfComp2==1)
8719         {
8720           int *ptr=getPointer();
8721           const int *ptrc=other->getConstPointer();
8722           for(int i=0;i<nbOfTuple;i++)
8723             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8724         }
8725       else
8726         throw INTERP_KERNEL::Exception(msg);
8727     }
8728   else if(nbOfTuple2==1)
8729     {
8730       if(nbOfComp2==nbOfComp)
8731         {
8732           int *ptr=getPointer();
8733           const int *ptrc=other->getConstPointer();
8734           for(int i=0;i<nbOfTuple;i++)
8735             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8736         }
8737       else
8738         throw INTERP_KERNEL::Exception(msg);
8739     }
8740   else
8741     throw INTERP_KERNEL::Exception(msg);
8742   declareAsNew();
8743 }
8744
8745
8746 /*!
8747  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8748  * valid cases.
8749  * 1.  The arrays have same number of tuples and components. Then each value of
8750  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8751  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8752  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8753  *   component. Then
8754  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8755  * 3.  The arrays have same number of components and one array, say _a2_, has one
8756  *   tuple. Then
8757  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8758  *
8759  * Info on components is copied either from the first array (in the first case) or from
8760  * the array with maximal number of elements (getNbOfElems()).
8761  *  \warning No check of division by zero is performed!
8762  *  \param [in] a1 - a dividend array.
8763  *  \param [in] a2 - a divisor array.
8764  *  \return DataArrayInt * - the new instance of DataArrayInt.
8765  *          The caller is to delete this result array using decrRef() as it is no more
8766  *          needed.
8767  *  \throw If either \a a1 or \a a2 is NULL.
8768  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8769  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8770  *         none of them has number of tuples or components equal to 1.
8771  */
8772 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8773 {
8774   if(!a1 || !a2)
8775     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8776   int nbOfTuple1=a1->getNumberOfTuples();
8777   int nbOfTuple2=a2->getNumberOfTuples();
8778   int nbOfComp1=a1->getNumberOfComponents();
8779   int nbOfComp2=a2->getNumberOfComponents();
8780   if(nbOfTuple2==nbOfTuple1)
8781     {
8782       if(nbOfComp1==nbOfComp2)
8783         {
8784           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8785           ret->alloc(nbOfTuple2,nbOfComp1);
8786           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8787           ret->copyStringInfoFrom(*a1);
8788           return ret.retn();
8789         }
8790       else if(nbOfComp2==1)
8791         {
8792           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8793           ret->alloc(nbOfTuple1,nbOfComp1);
8794           const int *a2Ptr=a2->getConstPointer();
8795           const int *a1Ptr=a1->getConstPointer();
8796           int *res=ret->getPointer();
8797           for(int i=0;i<nbOfTuple1;i++)
8798             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8799           ret->copyStringInfoFrom(*a1);
8800           return ret.retn();
8801         }
8802       else
8803         {
8804           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8805           return 0;
8806         }
8807     }
8808   else if(nbOfTuple2==1)
8809     {
8810       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8811       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8812       ret->alloc(nbOfTuple1,nbOfComp1);
8813       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8814       int *pt=ret->getPointer();
8815       for(int i=0;i<nbOfTuple1;i++)
8816         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8817       ret->copyStringInfoFrom(*a1);
8818       return ret.retn();
8819     }
8820   else
8821     {
8822       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8823       return 0;
8824     }
8825 }
8826
8827 /*!
8828  * Modify \a this array so that each value becomes a modulus of division of this value by
8829  * a value of another DataArrayInt. There are 3 valid cases.
8830  * 1.  The arrays have same number of tuples and components. Then each value of
8831  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8832  *   _a_ [ i, j ] %= _other_ [ i, j ].
8833  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8834  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8835  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8836  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8837  *
8838  *  \warning No check of division by zero is performed!
8839  *  \param [in] other - a divisor array.
8840  *  \throw If \a other is NULL.
8841  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8842  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8843  *         \a other has number of both tuples and components not equal to 1.
8844  */
8845 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8846 {
8847   if(!other)
8848     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8849   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8850   checkAllocated(); other->checkAllocated();
8851   int nbOfTuple=getNumberOfTuples();
8852   int nbOfTuple2=other->getNumberOfTuples();
8853   int nbOfComp=getNumberOfComponents();
8854   int nbOfComp2=other->getNumberOfComponents();
8855   if(nbOfTuple==nbOfTuple2)
8856     {
8857       if(nbOfComp==nbOfComp2)
8858         {
8859           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8860         }
8861       else if(nbOfComp2==1)
8862         {
8863           if(nbOfComp2==nbOfComp)
8864             {
8865               int *ptr=getPointer();
8866               const int *ptrc=other->getConstPointer();
8867               for(int i=0;i<nbOfTuple;i++)
8868                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8869             }
8870           else
8871             throw INTERP_KERNEL::Exception(msg);
8872         }
8873       else
8874         throw INTERP_KERNEL::Exception(msg);
8875     }
8876   else if(nbOfTuple2==1)
8877     {
8878       int *ptr=getPointer();
8879       const int *ptrc=other->getConstPointer();
8880       for(int i=0;i<nbOfTuple;i++)
8881         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8882     }
8883   else
8884     throw INTERP_KERNEL::Exception(msg);
8885   declareAsNew();
8886 }
8887
8888 /*!
8889  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8890  * valid cases.
8891  *
8892  *  \param [in] a1 - an array to pow up.
8893  *  \param [in] a2 - another array to sum up.
8894  *  \return DataArrayInt * - the new instance of DataArrayInt.
8895  *          The caller is to delete this result array using decrRef() as it is no more
8896  *          needed.
8897  *  \throw If either \a a1 or \a a2 is NULL.
8898  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8899  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8900  *  \throw If there is a negative value in \a a2.
8901  */
8902 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8903 {
8904   if(!a1 || !a2)
8905     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8906   int nbOfTuple=a1->getNumberOfTuples();
8907   int nbOfTuple2=a2->getNumberOfTuples();
8908   int nbOfComp=a1->getNumberOfComponents();
8909   int nbOfComp2=a2->getNumberOfComponents();
8910   if(nbOfTuple!=nbOfTuple2)
8911     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8912   if(nbOfComp!=1 || nbOfComp2!=1)
8913     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8914   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8915   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8916   int *ptr=ret->getPointer();
8917   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8918     {
8919       if(*ptr2>=0)
8920         {
8921           int tmp=1;
8922           for(int j=0;j<*ptr2;j++)
8923             tmp*=*ptr1;
8924           *ptr=tmp;
8925         }
8926       else
8927         {
8928           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8929           throw INTERP_KERNEL::Exception(oss.str().c_str());
8930         }
8931     }
8932   return ret.retn();
8933 }
8934
8935 /*!
8936  * Apply pow on values of another DataArrayInt to values of \a this one.
8937  *
8938  *  \param [in] other - an array to pow to \a this one.
8939  *  \throw If \a other is NULL.
8940  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8941  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8942  *  \throw If there is a negative value in \a other.
8943  */
8944 void DataArrayInt::powEqual(const DataArrayInt *other)
8945 {
8946   if(!other)
8947     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8948   int nbOfTuple=getNumberOfTuples();
8949   int nbOfTuple2=other->getNumberOfTuples();
8950   int nbOfComp=getNumberOfComponents();
8951   int nbOfComp2=other->getNumberOfComponents();
8952   if(nbOfTuple!=nbOfTuple2)
8953     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8954   if(nbOfComp!=1 || nbOfComp2!=1)
8955     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8956   int *ptr=getPointer();
8957   const int *ptrc=other->begin();
8958   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8959     {
8960       if(*ptrc>=0)
8961         {
8962           int tmp=1;
8963           for(int j=0;j<*ptrc;j++)
8964             tmp*=*ptr;
8965           *ptr=tmp;
8966         }
8967       else
8968         {
8969           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8970           throw INTERP_KERNEL::Exception(oss.str().c_str());
8971         }
8972     }
8973   declareAsNew();
8974 }
8975
8976 /*!
8977  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8978  * This map, if applied to \a start array, would make it sorted. For example, if
8979  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8980  * [5,6,0,3,2,7,1,4].
8981  *  \param [in] start - pointer to the first element of the array for which the
8982  *         permutation map is computed.
8983  *  \param [in] end - pointer specifying the end of the array \a start, so that
8984  *         the last value of \a start is \a end[ -1 ].
8985  *  \return int * - the result permutation array that the caller is to delete as it is no
8986  *         more needed.
8987  *  \throw If there are equal values in the input array.
8988  */
8989 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
8990 {
8991   std::size_t sz=std::distance(start,end);
8992   int *ret=(int *)malloc(sz*sizeof(int));
8993   int *work=new int[sz];
8994   std::copy(start,end,work);
8995   std::sort(work,work+sz);
8996   if(std::unique(work,work+sz)!=work+sz)
8997     {
8998       delete [] work;
8999       free(ret);
9000       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9001     }
9002   std::map<int,int> m;
9003   for(int *workPt=work;workPt!=work+sz;workPt++)
9004     m[*workPt]=(int)std::distance(work,workPt);
9005   int *iter2=ret;
9006   for(const int *iter=start;iter!=end;iter++,iter2++)
9007     *iter2=m[*iter];
9008   delete [] work;
9009   return ret;
9010 }
9011
9012 /*!
9013  * Returns a new DataArrayInt containing an arithmetic progression
9014  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9015  * function.
9016  *  \param [in] begin - the start value of the result sequence.
9017  *  \param [in] end - limiting value, so that every value of the result array is less than
9018  *              \a end.
9019  *  \param [in] step - specifies the increment or decrement.
9020  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9021  *          array using decrRef() as it is no more needed.
9022  *  \throw If \a step == 0.
9023  *  \throw If \a end < \a begin && \a step > 0.
9024  *  \throw If \a end > \a begin && \a step < 0.
9025  */
9026 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9027 {
9028   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9029   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9030   ret->alloc(nbOfTuples,1);
9031   int *ptr=ret->getPointer();
9032   if(step>0)
9033     {
9034       for(int i=begin;i<end;i+=step,ptr++)
9035         *ptr=i;
9036     }
9037   else
9038     {
9039       for(int i=begin;i>end;i+=step,ptr++)
9040         *ptr=i;
9041     }
9042   return ret.retn();
9043 }
9044
9045 /*!
9046  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9047  * Server side.
9048  */
9049 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9050 {
9051   tinyInfo.resize(2);
9052   if(isAllocated())
9053     {
9054       tinyInfo[0]=getNumberOfTuples();
9055       tinyInfo[1]=getNumberOfComponents();
9056     }
9057   else
9058     {
9059       tinyInfo[0]=-1;
9060       tinyInfo[1]=-1;
9061     }
9062 }
9063
9064 /*!
9065  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9066  * Server side.
9067  */
9068 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9069 {
9070   if(isAllocated())
9071     {
9072       int nbOfCompo=getNumberOfComponents();
9073       tinyInfo.resize(nbOfCompo+1);
9074       tinyInfo[0]=getName();
9075       for(int i=0;i<nbOfCompo;i++)
9076         tinyInfo[i+1]=getInfoOnComponent(i);
9077     }
9078   else
9079     {
9080       tinyInfo.resize(1);
9081       tinyInfo[0]=getName();
9082     }
9083 }
9084
9085 /*!
9086  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9087  * This method returns if a feeding is needed.
9088  */
9089 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9090 {
9091   int nbOfTuple=tinyInfoI[0];
9092   int nbOfComp=tinyInfoI[1];
9093   if(nbOfTuple!=-1 || nbOfComp!=-1)
9094     {
9095       alloc(nbOfTuple,nbOfComp);
9096       return true;
9097     }
9098   return false;
9099 }
9100
9101 /*!
9102  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9103  * This method returns if a feeding is needed.
9104  */
9105 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9106 {
9107   setName(tinyInfoS[0]);
9108   if(isAllocated())
9109     {
9110       int nbOfCompo=tinyInfoI[1];
9111       for(int i=0;i<nbOfCompo;i++)
9112         setInfoOnComponent(i,tinyInfoS[i+1]);
9113     }
9114 }
9115
9116 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9117 {
9118   if(_da)
9119     {
9120       _da->incrRef();
9121       if(_da->isAllocated())
9122         {
9123           _nb_comp=da->getNumberOfComponents();
9124           _nb_tuple=da->getNumberOfTuples();
9125           _pt=da->getPointer();
9126         }
9127     }
9128 }
9129
9130 DataArrayIntIterator::~DataArrayIntIterator()
9131 {
9132   if(_da)
9133     _da->decrRef();
9134 }
9135
9136 DataArrayIntTuple *DataArrayIntIterator::nextt()
9137 {
9138   if(_tuple_id<_nb_tuple)
9139     {
9140       _tuple_id++;
9141       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9142       _pt+=_nb_comp;
9143       return ret;
9144     }
9145   else
9146     return 0;
9147 }
9148
9149 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9150 {
9151 }
9152
9153 std::string DataArrayIntTuple::repr() const
9154 {
9155   std::ostringstream oss; oss << "(";
9156   for(int i=0;i<_nb_of_compo-1;i++)
9157     oss << _pt[i] << ", ";
9158   oss << _pt[_nb_of_compo-1] << ")";
9159   return oss.str();
9160 }
9161
9162 int DataArrayIntTuple::intValue() const
9163 {
9164   if(_nb_of_compo==1)
9165     return *_pt;
9166   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9167 }
9168
9169 /*!
9170  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9171  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9172  * 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
9173  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9174  */
9175 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9176 {
9177   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9178     {
9179       DataArrayInt *ret=DataArrayInt::New();
9180       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9181       return ret;
9182     }
9183   else
9184     {
9185       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9186       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9187       throw INTERP_KERNEL::Exception(oss.str().c_str());
9188     }
9189 }