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